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:
Comments (Atom)