Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- /* Values for TYPE field */
- define( 'ARRAY_T', "A\036" );
- define( 'FILE_T', "F\036" );
- define( 'SCALAR_T', "S\036" );
- define( 'TUPLE_T', "T\036" );
- // Class enforces type uniformity for array elements.
- // This is a design decision that I made to make the
- // serialization process easier. If you want to store
- // multiple objects of different types, use a tuple.
- class array_t implements Countable {
- private $type;
- private $types = array(); // Only used if elements are arrays
- private $members = array();
- public function __construct(){
- if( !($argc = func_num_args()) ) return;
- $argv = func_get_args();
- if( is_array( $argv[0] ) ){
- if( $argc == 1 ){
- $argv = $argv[0];
- $argc = sizeof( $argv );
- }
- if( is_array( $argv[0] ) ){
- $this->type = "array";
- $this->map( $argv[0], $this->types );
- $size = sizeof( $argv );
- for( $i = 0; $i < $size; $i++ ){
- if( $this->isomorphism( $argv[$i], $this->types ) == -1 ){
- echo "Error: Structured array_t elements must be isomorphic.";
- exit;
- }
- $this->members[$i] = $argv[$i];
- }
- }
- }
- else{
- $this->type = gettype( $argv[0] );
- for( $i = 0; $i < $argc; $i++ ){
- if( gettype( $argv[$i] ) != $this->type ){
- echo "Error: Elements of array_t object must all be the same type.";
- exit;
- }
- $this->members[$i] = $argv[$i];
- }
- }
- }
- public function set_element( $index, $value ){
- if( is_array( $this->members[$index] ) ){
- if( !is_array( $value ) ){
- echo "Error: Tried to set array field to non-array";
- return -1;
- }
- if( $this->isomorphism( $value, $this->types ) == -1 ){
- echo "Error: Structured array_t elements must be isomorphic.";
- return -1;
- }
- }
- else if( gettype( $value != $this->type ) ){
- echo "Error: Tried to set array_t element to an incompatible type";
- return -1;
- }
- $this->members[$index] = $value;
- }
- public function get_element( $index ){
- return $this->members[$index];
- }
- public function get_type(){
- return $this->type;
- }
- public function get_types(){
- return $this->types;
- }
- public function count(){
- return count( $this->members );
- }
- /* Function builds a tree of all types in a structure */
- private function map( $arg, &$types ){
- $size = sizeof( $arg );
- for( $i = 0; $i < $size; $i++ ){
- if( is_array( $arg[$i] ) ){
- $types[$i] = array();
- $this->map( $arg[$i], $types[$i] );
- }
- else{
- $types[$i] = gettype( $arg[$i] );
- }
- }
- }
- /* Function compares two trees for isomorphism and type uniformity */
- private function isomorphism( $arg, $types ){
- $size = sizeof( $types );
- if( sizeof( $arg ) != $size ) return -1;
- for( $i = 0; $i < $size; $i++ ){
- if( is_array( $arg[$i] ) && is_array( $types[$i] ) ){
- if( $this->isomorphism( $arg[$i], $types[$i] ) == -1 )
- return -1;
- }
- else if( gettype( $arg[$i] ) != $types[$i] )
- return -1;
- }
- }
- }
- // tuple_t is basically just an alias for PHP hash tables.
- // Tuples are more flexible than arrays but much slower.
- // Serialization of tuples is done using var_dump().
- // Key/value pairs are passed as alternating arguments: key, value, key, value...
- class tuple_t {
- private $members = array();
- private $keys = array();
- public function __construct(){
- if( !($argc = func_num_args()) ) return;
- $argv = func_get_args();
- if( $argc % 2 == 1 ){
- echo "Error: Mismatched key/value pairs in tuple_t initialization";
- exit;
- }
- $argc /= 2;
- for( $i = 0; $i < $argc; $i++ ){
- $i2 = $i * 2;
- if( !is_string( $argv[$i2] ) ){
- echo "Error: Non-string object used for key in tuple_t object";
- exit;
- }
- $this->keys[$i] = $argv[$i2];
- $this->members[$argv[$i2]] = $argv[$i2+1];
- }
- }
- public function set_element( $key, $value ){
- $this->members[$key] = $value;
- }
- public function get_element( $key ){
- return $this->members[$key];
- }
- public function getkeys(){
- return $this->keys;
- }
- }
- function cabs( $exec, $msg ){
- $descriptorspec = array(
- 0 => array( "pipe", "r" ),
- 1 => array( "pipe", "w" ),
- 2 => array( "file", "error_log.txt", "a" ) /* No error log */
- );
- $cwd = sys_get_temp_dir();
- $env = array( 'blank' => 'blank' ); /* TODO: Add OS-specific environment */
- $process = proc_open( $exec, $descriptorspec, $pipes, $cwd, $env );
- if( is_resource( $process ) ){
- fwrite( $pipes[0], $msg );
- fclose( $pipes[0] );
- $result = stream_get_contents( $pipes[1] );
- fclose( $pipes[1] );
- if( proc_close( $process ) ){ /* Nonzero exit status indicates error */
- echo $result; /* Result will be an error message */
- return -1;
- }
- else return $result;
- }
- }
- function array_to_msg( $arg ){
- if( !is_a( $arg, "array_t" ) ){
- echo "Error: Type checking error for function array_to_msg()";
- exit;
- }
- $msg = ARRAY_T;
- $size = sizeof( $arg )-1;
- /*
- * I used two separate loops to avoid having to check
- * the value of $arg->type every iteration.
- */
- if( $arg->get_type() == "array" ){
- $msg .= serialize_tree( $arg->get_types() ) . "\035"; /* Group separator */
- for( $i = 0; $i < $size; $i++ ){
- $msg .= serialize_tree( $arg->get_element( $i ) ) . "\036"; /* Record separator */
- }
- $msg .= serialize_tree( $arg->get_element( $size ) ) . "\004"; /* End of Transmission */
- }
- else{
- $msg .= $arg->get_type() . "\035";
- for( $i = 0; $i < $size; $i++ ){
- $msg .= $arg->get_element( $i ) . "\036";
- }
- $msg .= $arg->get_element( $size ) . "\004";
- }
- return $msg;
- }
- function msg_to_array( $msg ){
- if( $msg[0] != 'A' ){
- echo "Error: Type checking error for function msg_to_array()";
- exit;
- }
- $len = strlen( $msg );
- $i = 0;
- while( $msg[++$i] != "\035" ); /* Move to end of heading */
- $cmdstr1 = "";
- while( ++$i < $len ){
- switch( $msg[$i] ){
- case "\002" : $cmdstr1[$i] = '['; break; /* STX */
- case "\003" : $cmdstr1[$i] = ']'; break; /* ETX */
- case "\036" : $cmdstr1[$i] = ','; break; /* RS */
- case "\037" : $cmdstr1[$i] = ','; break; /* US */
- case "\004" : break 2; /* EOT */
- default : $cmdstr1[$i] = $msg[$i];
- }
- }
- $cmdstr2 = "\$a = array(" . $cmdstr1 . ");";
- eval( $cmdstr2 );
- return $a;
- }
- function serialize_tree( $tree ){
- $size = sizeof( $tree )-1;
- $str = "\002"; /* STX character used to denote start of array */
- for( $i = 0; $i < $size; $i++ ){
- if( gettype( $tree[$i] ) == "array" )
- $str .= serialize_tree( $tree[$i] );
- else
- $str .= $tree[$i];
- $str .= "\037"; /* Unit Separator character separates */
- /* array elements within a record. */
- }
- /*
- * Last element is processed separately to avoid having to use
- * a decision statemnt every iteration to add the comma on only
- * the last one
- */
- if( gettype( $tree[$size] ) == "array" )
- $str .= serialize_tree( $tree[$size] );
- else
- $str .= $tree[$size];
- $str .= "\003"; /* ETX character used to denote end of array */
- return $str;
- }
- ?>
Add Comment
Please, Sign In to add comment