class MYENC { private $STRESC = [ '"' => """, "'" => "'", '&' => "&", '>' => ">", '<' => "<", ]; function STRENC($s) { if (is_null($s)) return "N"; $opc = 'P'; $rv = []; foreach (str_split($s) as $c) { $n = ord($c); if ($n <= 0x20 || $n > 126 || $n == ord('\\')) array_push($rv, sprintf(strtoupper("&#%x;"), $n)); elseif (array_key_exists($c, $this->STRESC)) array_push($rv, $this->STRESC[$c]); else array_push($rv, $c); } return join('',$rv); } function STRDEC($s) { if (is_null($s)) return $s; preg_match_all("/[&][^;]*;/", $s, $m, PREG_OFFSET_CAPTURE); if (count($m) <= 0) return $s; $p = $m[0]; if (count($p) <= 0) return $s; $ESC = array_flip($this->STRESC); for ($i = count($p)-1; $i >= 0; $i--) { $rep = ''; $x = $p[$i]; if (array_key_exists($x[0], $ESC)) $rep = $ESC[$x[0]]; else if (preg_match("/^[&][#]([0-9A-F]+);/i", $x[0], $h) > 0) $rep = chr(hexdec($h[1])); $s = substr_replace($s, $rep, $x[1], strlen($x[0])); } return $s; } private $CONTROL = [ "N" => [ 'arg' => 0, 'func' => '_N'], "A" => [ 'opc' => 'A', 'arg' => 0, 'func' => '_A'], "C" => [ 'opc' => 'C', 'arg' => 0, 'func' => '_C'], "P" => [ 'opc' => 'P', 'arg' => 1, 'func' => '_P'], "=" => [ 'opc' => '=', 'arg' => 0, 'func' => '_EQ'], "#" => [ 'opc' => '#', 'arg' => 0, 'func' => '_HASH'], "i" => [ 'opc' => 'i', 'arg' => 0, 'func' => '_INT'], "b" => [ 'opc' => 'b', 'arg' => 0, 'func' => '_BOOL'], "f" => [ 'opc' => 'f', 'arg' => 0, 'func' => '_FLOAT'], ]; function __construct() { } private function _N(&$S,$v) { array_push($S, NULL); } private function _A(&$S,$v) { array_push($S, []); } private function _C(&$S,$v) { array_push($S, new stdClass); } private function _P(&$S,$v) { array_push($S, $v); } private function _EQ(&$S,$v) { $v = array_pop($S); $f = array_pop($S); $C = array_pop($S); $C->$f = $v; array_push($S, $C); } private function _HASH(&$S,$v) { $v = array_pop($S); $f = array_pop($S); $A = array_pop($S); $A[$f] = $v; array_push($S, $A); } private function _INT(&$S,$v) { $v = array_pop($S); array_push($S, intVal($v)); } private function _BOOL(&$S,$v) { $v = array_pop($S); array_push($S, !!intVal($v)); } private function _FLOAT(&$S,$v) { $v = array_pop($S); if ($v == 'NAN') $v = NAN; elseif ($v == 'INF') $v = INF; else $v = floatVal($v); array_push($S, $v); } private function NEXTOPC($P, $_off, &$opr, &$v) { $opr = NULL; $v = NULL; $idx = $_off; $CTL = $this->CONTROL; if ($idx < 0 || $idx >= strlen($P)) return 0; $op = $P[$idx]; $idx++; if (!array_key_exists($op, $CTL)) return 0; $opr = $CTL[$op]; if ($opr['arg'] == 0) return $idx - $_off; if (preg_match("/([0-9]+)[.]/", $P, $m, PREG_OFFSET_CAPTURE, $idx) <= 0) return 0; $k = $m[1]; $idx += strlen($k[0]) + 1; $len = intVal($k[0]); if ($idx+$len > strlen($P)) return 0; $v = substr($P, $idx, $len); $idx += $len; return $idx - $_off; } function DECODE($P) { $STACK = []; $off = 0; for (;;) { $i = $this->NEXTOPC($P, $off, $opr, $v); if ($i <= 0) break; $off += $i; $func = $opr['func']; $this->$func($STACK, $v); #print "OPC " . $opr['opc'] . "\$i=${i} \$off=${off}\n"; } return array_pop($STACK); } private function EMIT(&$K, ... $s) { $K .= join('', $s); } private function EMITS(&$K, ... $params) { foreach ($params as $s) { if (is_null($s)) { $this->EMIT($K, "N"); return; } $post = ''; if (is_float($s)) { $post = 'f'; if (is_nan($s)) $s = 'NAN'; elseif (is_infinite($s)) $s = 'INF'; else $s = sprintf("%.17e", $s); } elseif (is_int($s)) $post = 'i'; elseif (is_bool($s)) $post = 'b'; $this->EMIT($K, "P", strlen($s), ".", $s, $post); } } private function ENC(&$K, $X) { if (is_array($X)) { $this->EMIT($K, "A"); foreach ($X as $k => $v) { if (is_array($v)) { $this->EMITS($K, $k); $this->ENC($K, $v); continue; } if (is_object($v)) { $this->EMITS($K, $k); $this->ENC($K, $v); continue; } $this->EMITS($K, $k, $v); $this->EMIT($K, "#"); } return; } if (is_object($X)) { $this->EMIT($K, "C"); foreach (get_object_vars ($X) as $k => $v) { if (is_array($v)) { $this->EMITS($K, $k); $this->ENC($K, $v); continue; } if (is_object($v)) { $this->EMITS($K, $k); $this->ENC($K, $v); continue; } $this->EMITS($K, $k, $v); $this->EMIT($K, "="); } return; } $this->EMITS($K,$X); } function ENCODE($X) { $K = ''; $this->ENC($K, $X); return $K; } }
Sunday, 7 April 2019
Quick & dirty php serilaization
Subscribe to:
Posts (Atom)