<?
/*
this softwary by Musicman 2003
is covered by the GPL
for the exact terms and conditions please see http://www.fsf.org
*/
class amfdata
{ var $fn, $fnseq, $fnargs;
var $hdrs;
var $byteorder;
function nargs()
{ return count($this->fnargs);
}
function getstr($d, &$n)
{ // print "($n) ";
$hi = ord($d[$n++]);
$lo = ord($d[$n++]);
$lo += 256 * $hi;
$val = substr($d, $n, $lo);
$n += $lo;
return $val;
}
function getnumber($d, &$n)
{ $ibf = "";
switch($this->byteorder)
{ case 'x86':
for($nc = 7 ; $nc >= 0 ; $nc--)
$ibf .= $d[$n+$nc];
break;
case 'ppc':
$ibf = substr($d, $n, 8);
break;
}
$n += 8;
$zz = unpack("dflt", $ibf);
return $zz['flt'];
}
function parseitem($ch, $d, &$n)
{ switch($ch)
{ case 1: // boolean
$ch = ord($d[$n++]);
// settype($ch, BOOL);
return $ch;
break;
case 0:
return $this->getnumber($d, $n);
break;
case 3:
return $this->getobj($d, $n);
break;
case 10:
return $this->getarray($d, $n);
break;
case 2:
return $this->getstr($d, $n);
break;
case 5:
return null;
default:
print "xxx $ch ";
}
}
function getobj($d, &$n)
{ $ret = array();
while($key = $this->getstr($d, $n))
{ $ch = ord($d[$n++]);
$val = $this->parseitem($ch, $d, $n);
$ret[$key] = $val;
}
$ch = ord($d[$n++]);
if($ch != 9) print "obj?? $ch ";
return $ret;
}
function getarray($d, &$n)
{ $ret = array();
for($lo = 0, $c = 0 ; $c < 4 ; $c++)
{ $lo *= 256;
$lo += ord($d[$n++]);
}
for($ni = 0 ; $ni < $lo ; $ni++)
{ $ch = ord($d[$n++]);
$ret[] = $this->parseitem($ch, $d, $n);
}
return $ret;
}
function amfdata()
{ $this->hdrs = array();
$this->fnargs = array();
$tmp = pack("d", 1);
if($tmp == "\0\0\0\0\0\0\360\77")
$this->byteorder = 'x86';
else if($tmp == "\77\360\0\0\0\0\0\0")
$this->byteorder = 'ppc';
else
die("unknown byteorder in amfdata\n");
$d = $GLOBALS[HTTP_RAW_POST_DATA];
$l = strlen($d);
$n = 3;
$nv = ord($d[$n++]);
while(--$nv >= 0)
{ $key = $this->getstr($d, $n);
$n++;
for($lo = 0, $c = 0 ; $c < 4 ; $c++)
{ $lo *= 256;
$lo += ord($d[$n++]);
}
$ch = ord($d[$n++]);
$val = $this->parseitem($ch, $d, $n);
$this->$hdrs[$key] = $val;
}
$n++;
if($ch = ord($d[$n++]))
{ $this->fn = $this->getstr($d, $n);
$this->fnseq = $this->getstr($d, $n);
for($lo = 0, $c = 0 ; $c < 4 ; $c++)
{ $lo *= 256;
$lo += ord($d[$n++]);
}
$ch = ord($d[$n++]); if($ch != 10) print " ??";
for($lo = 0, $c = 0 ; $c < 4 ; $c++)
{ $lo *= 256;
$lo += ord($d[$n++]);
}
for($ni = 0 ; $ni < $lo ; $ni++)
{ $ch = ord($d[$n++]);
$this->fnargs[] = $this->parseitem($ch, $d, $n);
}
}
return $this;
}
function sendnum($val)
{ $b = pack("d", $val);
switch($this->byteorder)
{ case 'x86':
$r = "";
for($n = 7 ; $n >= 0 ; $n--)
$r .= $b[$n];
return $r;
case 'ppc':
return $b;
}
}
function sendstr($str)
{ return pack("n", strlen($str)) . $str;
}
function sendobj($val)
{ if(is_array($val) || is_object($val))
{ $first = 1;
$num_array = 1;
foreach($val as $key => $data)
{ if(!is_int($key) || ($key < 0))
{ $num_array = 0;
break;
}
if($first)
{ $lo = $hi = $key;
$first = 0;
}
else if($key < $lo)
$lo = $key;
else if($key > $hi)
$hi = $key;
}
if($num_array)
{ $ret = "\12" . pack("N", $hi+1);
for($n = 0 ; $n <= $hi ; $n++)
$ret .= $this->sendobj($val[$n]);
}
else
{ $ret = "\3";
foreach($val as $key => $data)
{ $ret .= $this->sendstr($key);
$ret .= $this->sendobj($data);
}
$ret .= $this->sendstr('') . "\11";
}
return $ret;
}
else if(is_integer($val) || is_numeric($val))
return "\0" . $this->sendnum($val);
else
return "\2" . $this->sendstr($val);
}
function sendresult($data)
{ header('Content-type: application/x-amf');
print "\0\0\0\0\0\1" . $this->sendstr($this->fnseq . "/onResult") .
$this->sendstr("null") . pack("N", -1) . $this->sendobj($data);
}
}
Back