<?php
// -----------------------------------------------------------------
//
// Autor: Jorge Machin
//
// Header:
//
// 01 - 07 Last element
// 08 - 14 Register Size
// 15 - 21 Max number of register
// 22 - 28 Pointer to next element
//
// -----------------------------------------------------------------
class shmem {
var $register_size = 0; // Register Size
var $header_size = 28; // Header Size
var $maxRegs; // Max number or registers
var $fields; // Array with fields size
// Punteros a la memoria
var $shmid; // Shared memory block identifier
var $key; // Shared memory key
var $semid; // Semaphore identifier
// Debug Flag:
var $debug;
// --------------------------------------------------------------
// Constructor
//
// key : Shared Memory key
// fields : Fields sizes array
// max : Register max number
// Debug : Debug flag
//
// -------------------------------------------------------------
function shmem( $key, $fields, $maxRegs = 0, $debug = false ) {
$this->key = $key;
$this->fields = $fields;
$this->maxRegs = $maxRegs;
$this->debug = $debug;
// get semaphore:
$this->semid = sem_get ( $key, 1, 0666 );
if ( !$this->semid ) {
echo "mem.mem: Can't get semaphore<BR>";
return;
}
if ( !sem_acquire( $this->semid ) ) {
echo "mem.mem: Can't acquire semaphore<BR>";
return;
}
// Check shared memory block.
$this->shmid= @shmop_open( $key, 'c', 0, 0 );
if ( $this->shmid == '' ) {
if ( $this->debug )
echo 'mem.mem: Creating shared memory<BR>';
// Get register size:
while( list( $index, $val ) = each( $fields ) )
$this->register_size += $val;
// Create shared memory block
$this->shmid=shmop_open( $key, 'c', 0666, ( $this->maxRegs*$this->register_size )+$this->header_size );
if ( $this->shmid == '' ) {
echo "mem.mem: Can't create shared memory";
} else {
// Set Header Info:
shmop_write( $this->shmid, $this->formatField( $this->header_size, 7 ),0 );
shmop_write( $this->shmid, $this->formatField( $this->register_size, 7 ),7 );
shmop_write( $this->shmid, $this->formatField( $this->maxRegs, 7 ),14 );
shmop_write( $this->shmid, $this->formatField( '',7 ), 21 );
}
} else {
// Get Header Info
if ( $this->debug )
echo 'mem.mem: Reading Header<BR>';
$this->register_size = (int) shmop_read( $this->shmid, 7, 7 );
$this->Regsmax = (int) shmop_read( $this->shmid, 14, 7 );
if ( $this -> debug ) {
echo "mem.register_size : " . $this->register_size . '<BR>';
echo "mem.maxRegs : " . $this->maxRegs . '<BR>';
}//endif
}//endif
// Release semaphore:
if( !sem_release( $this->semid ) )
echo "mem: Can't release semaphore";
}
// Insert a register
function insert( $register ) {
// Format register
while( list( $index, $val ) = each( $this->fields ) )
$cadena .= $this->formatField( $register[$index], $val );
reset( $this-> fields );
if ( $this->debug )
echo "<PRE>String: *$cadena*</PRE><BR>";
if ( !sem_acquire( $this -> semid ) ) {
echo "mem.insert: Can't semaphore<BR>";
return;
}
// Get Header Info:
$last = (int) shmop_read( $this->shmid, 0, 7 );
if ( $this->debug )
echo "mem.Last: *$last*<BR>";
// Insert register
shmop_write ( $this->shmid, $cadena, $last );
// Update Header:
shmop_write( $this->shmid, $last + $this->register_size , 0 );
if( !sem_release( $this->semid ) ) {
echo "mem.Last: Can't realese semaphore";
exit();
}
}
// Update a register
function update( $id, $value, $register ) {
if ( !sem_acquire( $this->semid ) ) {
echo "mem.find: Can't get semaphore<BR>";
return;
}
// Main loop
$last = (int) shmop_read( $this->shmid, 0, 7 );
for ( $ptr = $this->header_size; $ptr < $last; $ptr+=$this->register_size ) {
if ( trim(shmop_read( $this->shmid, $ptr, $this->fields[$id] )) == $value ) {
while( list( $index, $val ) = each( $this->fields ) )
$cadena .= $this->formatField( $register[$index], $val );
reset( $this-> fields );
shmop_write ( $this->shmid, $cadena, $ptr );
if( !sem_release( $this->semid ) ) {
echo "find: Can't release semaphore";
exit();
}
return true;
}//endif
}//endfor
if( !sem_release( $this->semid ) ) {
echo "find: Can't release semaphore";
exit();
}
return false;
}
// Delete a record
function delete( $id, $value ) {
if ( !sem_acquire( $this->semid ) ) {
echo "mem.find: Can't get semaphore<BR>";
return;
}
// Main loop
$last = (int) shmop_read( $this->shmid, 0, 7 );
for ( $ptr = $this->header_size; $ptr < $last; $ptr+=$this->register_size ) {
if ( trim(shmop_read( $this->shmid, $ptr, $this->fields[$id] )) == $value ) {
if ( $ptr + $this->register_size < $last ) {
$mov = shmop_read( $this->shmid, $ptr+$this->register_size, $last-( $ptr+$this->register_size ) );
shmop_write( $this->shmid, $mov, $ptr );
}
shmop_write( $this->shmid, $this->formatField( $last-$this->register_size, 7 ) , 0 );
if( !sem_release( $this->semid ) ) {
echo "find: Can't release semaphore";
return;
}
return true;
}//endif
}//endfor
if( !sem_release( $this->semid ) ) {
echo "find: Can't release semaphore";
exit();
}
return false;
}
// find a register
function find( $id, $value ) {
if ( !sem_acquire( $this -> semid ) ) {
echo "mem.find: Can't get semaphore<BR>";
return;
}
// Main loop
$last = (int) shmop_read( $this->shmid, 0, 7 );
for ( $ptr = $this->header_size; $ptr < $last; $ptr += $this->register_size ) {
if ( trim(shmop_read( $this->shmid, $ptr, $this->fields[$id] )) == $value ) {
if( !sem_release( $this->semid ) ) {
echo "find: Can't release semaphore";
return;
}
return $this->getArray( $ptr );
}//endif
}//endfor
if( !sem_release( $this->semid ) ) {
echo "find: Can't release semaphore";
exit();
}
return NULL;
}
// List all
function listAll() {
if ( !sem_acquire( $this->semid ) ) {
echo "listAll.find: Can't get semaphore<BR>";
return;
}
// Obten los datos del encabezado:
$last = (int) shmop_read( $this->shmid, 0, 7 );
// Ciclo principal
echo '<PRE>';
for ( $ptr = $this->header_size; $ptr < $last; $ptr += $this->register_size )
echo "loop: " . $ptr . ' -' . shmop_read( $this->shmid, $ptr, $this->register_size ) . '-<BR>';
echo '</PRE>';
if ( !sem_release( $this->semid ) ) {
echo "find: Can't release semaphore";
exit();
}
return;
}
// Convertion functions:
function getArray( $origin ) {
$ptr = $origin;
while( list( $index, $val ) = each( $this->fields ) ) {
$arr[$index] = trim( shmop_read( $this->shmid, $ptr, $val ) );
$ptr += $val;
}
reset( $this-> fields );
return $arr;
}
function formatField( $cadena, $val ) {
$len = strlen( $cadena );
if ( $len > $val )
$cadena = substr( $cadena, 0, $val );
else
$cadena = $cadena . str_repeat( ' ', ($val-$len) );
return $cadena;
}
}
?>
|