| <?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;
   
   }
   
}
?>
 |