<?
if (!defined("_PICKLE_INCLUDED_"))
{
define("_PICKLE_INCLUDED_", 1);
}
else
return;
// this is pickle.inc
//
// The pickle function may be passed an associative array or object. It returns a
// string that can be used in python.
//
class pickleClass {
var $STEP = 0;
var $LINE = 0;
var $FLAGS = "";
var $BIN = 0;
var $ESC = 0;
var $KEYFLAG = 0;
// these are the pickling functions
function dumps($obj, $bin = 0, $esc = 0) {
$this->STEP = 0;
$this->FLAGS = "";
$this->BIN = $bin;
$this->ESC = $esc;
$pickled = $this->_process($obj);
$pickled .= $this->FLAGS.".";
return $pickled;
}
function dump($obj, $fp, $bin = 0) {
fwrite($fp, $this->dumps($obj, $bin));
}
function _process($obj) {
$pickleBuf = $this->_signal(0);
reset($obj);
while(list($objKey, $objVal) = each($obj)) {
$pickleBuf .= $this->_signal(1, $objKey);
if (is_array($objVal)) $pickleBuf .= $this->_process($objVal);
else $pickleBuf .= $this->_signal(1, $objVal);
if (!$this->BIN) {
$this->FLAGS .= "s";
}
}
if ($this->BIN) $this->FLAGS .= "u";
return $pickleBuf;
}
function _signal($proc, $str = "") {
switch($proc) {
case 0: // 'BEGIN ARRAY'
if ($this->BIN) {
$sigBuf = "}";
$this->FLAGS .= "(";
} else {
$sigBuf = $this->FLAGS."(d";
$this->FLAGS = "";
}
break;
case 1: // 'STRING'
if ($this->BIN) {
$num = strlen($str);
if ($this->ESC) { $str = ereg_replace('"', '\"', $str); }
if ($num > 255) {
$sigBuf = $this->FLAGS . "T";
for ($i = 0; $i < 4; $i++) {
$sigBuf .= $this->_char($num % 256);
$num /= 256;
}
} else {
$sigBuf = $this->FLAGS . "U" . $this->_char($num);
}
$sigBuf .= $str;
} else {
$sigBuf = $this->FLAGS."S'".$this->_format($str)."'".$this->_char(10);
}
$this->FLAGS = "";
break;
case 2: // 'INTEGER'
if ($this->BIN) {
$k = ord("K");
$num = intval($str);
if ($num > 255) {
$i = 2;
if ($num > 65535) {
$i = 4;
}
$k = "\"".($k + $i)."\"";
while ($i) {
$k .= $this->_char($num % 256);
$k /= 256;
$i--;
}
} else {
$k = "\"".$k."\"".$this->_char($num);
}
$sigBuf = $this->FLAGS . $k;
} else {
$sigBuf = $this->FLAGS."I$str".$this->_char(10);
}
$this->FLAGS = "";
break;
}
if ($this->BIN) {
$sigBuf .= "q" . $this->_char($this->STEP);
} else {
$sigBuf .= "p".$this->STEP.$this->_char(10);
}
$this->STEP++;
return $sigBuf;
}
function _format($str) {
$str = ereg_replace("'", "\\\'", $str);
$str = ereg_replace('"', '\"', $str);
return $str;
}
function _char($ch) {
$ch = intval($ch);
if ($this->ESC) {
return "\\" . sprintf("%03o", $ch);
} else {
return chr($ch);
}
}
function _detect($str) {
// crappy, but very simple detection (returns 0 on ascii; 1 on binary)
return (ereg("^\(?[SIFdlpg]", $str) ? 0 : 1);
}
// these are the unpickling functions
function loads($str) {
$this->STEP = 0;
$this->LINE = 0;
$this->EOF = 0;
$this->KEYFLAG = 0;
$this->DEPTH = array('PARENT');
$this->TYPES = array();
$this->LAST = '\$obj';
$this->INDEX = array();
$this->BIN = $this->_detect($str);
$str = $this->_raw($str);
if ($this->BIN) {
$this->PT = 0;
//print $str."<BR>";
while ($prog = $this->_binary($str)) {
//print $prog."<BR>";
if (substr($prog, 0, 4) == "\$obj") {
eval($prog);
} else if (substr($prog, 0, 4) == "DONE") {
//print $prog."<BR>";
break;
}
}
} else {
$str = split("\n", $str);
while (list(, $line) = each($str)) {
//print $line."<BR>";
$prog = $this->_ascii($line);
//print $prog."<BR>";
if (substr($prog, 0, 4) == "\$obj") {
eval($prog);
}
}
}
return $obj;
}
function load($fp) {
$this->STEP = 0;
$this->LINE = 0;
$this->KEYFLAG = 0;
$this->PT = 0;
$this->EOF = 0;
$this->DEPTH = array('PARENT');
$this->TYPES = array();
$this->LAST = '\$obj';
$this->INDEX = array();
$pt = ftell($fp);
$str = fgets($fp, 40);
$this->BIN = $this->_detect($str);
fseek($fp, $pt);
if ($this->BIN) {
while (!$this->EOF) {
$prog = $this->_binary($fp);
//print $prog."\n";
if (substr($prog, 0, 4) == "\$obj") {
eval($prog);
} else if (substr($prog, 0, 4) == "DONE") {
return $obj;
}
}
} else {
while (!feof($fp)) {
$pt = ftell($fp);
$line = fgets($fp, 4096);
//print $line."<BR>";
$prog = $this->_ascii($line);
//print $prog."<BR>";
if (substr($prog, 0, 4) == "\$obj") {
eval($prog);
} else if (substr($prog, 0, 4) == "DONE") {
$off = intval(substr($prog, 5));
fseek($fp, intval($pt + $off + 1));
return $obj;
}
}
}
return $obj;
}
function _ascii($line) {
$val = "";
$prog = "";
$cl = $op = $r = 0;
while (strlen($val) < 1) {
$ch = substr($line, $r, 1);
if ($ch == "p") {
$this->LINE = intval(substr($line, $r + 1));
return "LINE ".$this->LINE;
} else if ($ch == "a" || $ch == "s") {
$cl++;
} else if ($ch == "(") {
$op++;
if (substr($line, $r + 1, 1) == "l") {
$val = "[]";
} else {
$val = "{}";
}
if (substr($line, $r + 2, 1) == "p") {
$this->LINE = intval(substr($line, $r + 3));
}
} else if ($ch == "S") {
$val = substr($line, $r + 1);
} else if ($ch == "I") {
$val = intval(substr($line, $r + 1));
} else if ($ch == ".") {
return "DONE ".$r;
}
$r++;
}
if ($cl) {
$this->STEP -= $cl - 1;
if (strlen($val) > 0 && !$this->KEYFLAG
&& $this->TYPES[$this->STEP - 1] == "{}") {
$this->KEYFLAG = 1;
} else if ($this->KEYFLAG && $this->TYPES[$this->PKSTEP - 1] == "[]") {
$this->KEYFLAG = 0;
}
if ($this->TYPES[$this->STEP - 1] == "[]") {
$this->DEPTH[$this->STEP]++;
}
}
if (strlen($val) > 0) {
//print "[$cl, $op] $val : $this->STEP<BR>";
if ($this->KEYFLAG) {
$this->DEPTH[$this->STEP] = $val;
$this->KEYFLAG = 0;
} else {
if ($val == "[]") {
$this->TYPES[$this->STEP] = $val;
$this->DEPTH[$this->STEP + 1] = 0;
$val = "array()";
} else if ($val == "{}") {
$this->KEYFLAG = 1;
$this->TYPES[$this->STEP] = $val;
$val = "array()";
} else if ($this->TYPES[$this->STEP - 1] == "{}") {
$this->KEYFLAG = 1;
}
for ($dp = 1; $dp <= $this->STEP; $dp++) {
$prog .= "[".$this->DEPTH[$dp]."]";
if ($this->TYPES[$dp - 1] == "[]" && $dp == $this->STEP
&& !$op) {
$this->DEPTH[$dp]++;
}
}
$prog = "\$obj$prog = $val;";
}
}
$this->STEP += $op;
return $prog;
}
function _binary($str) {
$val = "";
$prog = "";
$cl = $op = 0;
while ($val == "" && !$this->EOF) {
$ch = $this->_read($str, 1);
if ($ch == "a" || $ch == "e" || $ch == "u" || $ch == "s") {
$cl++;
} else if ($ch == "}") {
$op++;
$val = "{}";
} else if ($ch == "]") {
$op++;
$val = "[]";
} else if ($ch == "U") {
$len = ord($this->_read($str, 1));
$val = "'".addslashes($this->_read($str, $len))."'";
} else if ($ch == "T") {
$len = ord($this->_read($str, 1)) + (ord($this->_read($str, 1)) * 256)
+ (ord($this->_read($str,1)) * 256 * 256) + (ord($this->_read($str, 1)) * 256 * 256 * 256);
$val = "'".addslashes($this->_read($str, $len))."'";
} else if ($ch == "K") {
$val = "'".ord($this->_read($str, 1))."'";
} else if ($ch == "M") {
$val = ord($this->_read($str, 1)) + (ord($this->_read($str, 1)) * 256);
} else if ($ch == "J") {
$val = ord($this->_read($str, 1)) + (ord($this->_read($str, 1)) * 256)
+ (ord($this->_read($str,1)) * 256 * 256) + (ord($this->_read($str, 1)) * 256 * 256 * 256);
} else if ($ch == ".") {
return "DONE ".$this->PT;
} else if ($ch == "h") {
$val = ord($this->_read($str, 1));
$val = $this->INDEX[$val];
} else if ($ch == "q") {
$val = ord($this->_read($str, 1));
$this->INDEX[$val] = $this->LAST;
$this->LAST = "";
return "LINE ".$val;
}
}
if ($cl) {
$this->STEP -= $cl;
if (strlen($val) > 0 && !$this->KEYFLAG
&& $this->TYPES[$this->STEP - 1] == "{}") {
$this->KEYFLAG = 1;
} else if ($this->KEYFLAG && $this->TYPES[$this->PKSTEP - 1] == "[]") {
$this->KEYFLAG = 0;
}
if ($this->TYPES[$this->STEP - 1] == "[]") {
$this->DEPTH[$this->STEP]++;
}
}
//print "[$cl, $op] $val : $this->PT\n";
if ($val != "") {
$this->LAST = $val;
if ($this->KEYFLAG) {
$this->DEPTH[$this->STEP] = $val;
$this->KEYFLAG = 0;
} else {
if ($val == "[]") {
$this->TYPES[$this->STEP] = $val;
$this->DEPTH[$this->STEP + 1] = 0;
$val = "array()";
} else if ($val == "{}") {
$this->KEYFLAG = 1;
$this->TYPES[$this->STEP] = $val;
$val = "array()";
} else if ($this->TYPES[$this->STEP - 1] == "{}") {
$this->KEYFLAG = 1;
}
for ($dp = 1; $dp <= $this->STEP; $dp++) {
$prog .= "[".$this->DEPTH[$dp]."]";
if ($this->TYPES[$dp - 1] == "[]" && $dp == $this->STEP
&& !$op) {
$this->DEPTH[$dp]++;
}
}
$this->LAST = "\$obj$prog";
if ($ch == "K") $val = "intval($val)";
$prog = "\$obj$prog = $val;";
}
}
$this->STEP += $op;
if ($this->EOF) $prog = "DONE";
return ($prog ? $prog : "PASS");
}
function _read($in, $len) {
if (is_string($in)) {
$v = substr($in, $this->PT, $len);
} else {
$v = fread($in, $len);
if (feof($in)) $this->EOF = 1;
}
$this->PT += $len;
return $v;
}
function _raw($str) {
$pl = 0;
while ($pl = strpos($str, "\\", $pl)) {
if (strpos($str, "\\", $pl) == $pl + 1) {
$pl += 2; continue;
}
$pre = substr($str, 0, $pl);
$o = substr($str, $pl + 1, 3);
$post = substr($str, $pl + 4);
$str = $pre . chr(octdec($o)) . $post;
}
return $str;
}
}
function pickle_load($ref) {
$pickle = new pickleClass;
return $pickle->load($ref);
}
function pickle_loads($ref) {
$pickle = new pickleClass;
return $pickle->loads($ref);
}
function pickle_dump($obj, $ref, $bin = 0) {
$pickle = new pickleClass;
return $pickle->dump($obj, $ref, $bin);
}
function pickle_dumps($obj, $bin = 0, $esc = 0) {
$pickle = new pickleClass;
return $pickle->dumps($obj, $bin, $esc);
}
?>