Chce napisać skrypt który na podstawie "pewnego łańcucha" przekazywanego z zewnętrzenego programu stworzy struktury drzewa opartą na tablicach.
"Pewien łańcuch" ma następującą składnie "i" - oznacza że następne 4 bajty to liczba integer, "s" - następne 4 bajty to liczba integer(Big Endian), i łańcuch znaków którego długość ona określa. nawiasy "(" i ")" oznaczają odpowiednio początek i koniec wewnętrznej tablicy.
Przykłądowe dane wejściowe:

((s\x01\x00\x00\x00ai\x01\x00\x00\x00
(s\x01\x00\x00\x00bi\x02\x00\x00\x00s\x0b\x00\x00\x00longer line)
s\x03\x00\x00\x00end))

odpowiadają strukturze
["a",1,["b",2,3,"longer line",],"end",]

\x01\x00\x00\x00 to przedstawienie liczby 01000000h która w odwrotenej kolejnośći(BIG ENDIAN) oznacza po prostu 1.

Samo przetwarzanie w funkcji loads działa prawidłowo - wyłapuje w odpowiednim miejscu odpowiedni typ danych ale ni działa budowanie drzewa zwraca:
Array
(
[0] => b
[1] => 2
[2] => 3
[3] => longer line
[4] => end
)

Czyli dane do pierwszego otwierającego nawiasu są prawidłowe po pierwszym są wszystkie ale tablica sie "spłaszcza" bo "end" jest na tym samym poziomie co reszta.

Błąd jest prawdopodobnie gdzieś przy referenacach do tablic current_node i parents ale próbowałem już chyba wszystkie możliwości ze znakiem & i bez niego, nie działa..

CODE
$f=fopen("php://input",'r+');
$data=stream_get_contents($f);
$ArrayStartMarker = "(";
$ArrayEndMarker = ")";
$IntegerMarker = "i";
$StringMarker = "s";
$strn="";

//mb_strlen($utf8_string, '8bit'); - returns byte length


function pack_integer($i) {
return pack("I",$i);
}
function unpack_integer($s,$pos) {
return array_pop(unpack("I",substr($s,$pos,4)));
}

function dump_string($val) {
global $strn, $ArrayStartMarker, $ArrayEndMarker, $IntegerMarker, $StringMarker;
if(is_array($val)) {
$strn.=$ArrayStartMarker;
for($i=0;$i<=count($val);$i++) {
dump_string($val[$i]);
}
$strn.=$ArrayEndMarker;
}
elseif(is_string($val)) {
$strn.=$StringMarker;
$strn.=(pack_integer(strlen_utf8($val)));
$strn.=$val;
}
elseif(is_int($val)) {
$strn.=$IntegerMarker;
$strn.=$val;

}
else {
trigger_error("Unknown char specified", E_USER_ERROR);
break;
}
}

function dumps($value) {
global $strn;
dump_string($value);
return $strn;
}


function loads($val) {
global $ArrayStartMarker, $ArrayEndMarker, $IntegerMarker, $StringMarker;
$parents=array();
$pointer=0;
$cur_node = array();
$retval = &$cur_node;
#$retval = array();
#$cur_node = &$retval;
while ($pointer
#print_r($cur_node);
$char=$val[$pointer];
$pointer++;
if($char==$ArrayStartMarker) {
$new_array=array();
array_push($parents,&$cur_node);
#$parents[]=&$cur_node;
array_push($cur_node,$new_array);
$cur_node=$new_array;
}
elseif($char==$ArrayEndMarker) {
$cur_node=array_pop(&$parents);
}
elseif($char==$StringMarker) {
$length=unpack_integer(&$val, $pointer);
$pointer+=4;
array_push($cur_node,substr($val,$pointer,$length));
#$cur_node[]=substr($val,$pointer,$length);
$pointer+=$length;
}
elseif($char==$IntegerMarker) {
$cur_node[]=unpack_integer(&$val,$pointer);
$pointer+=4;
}
else {
trigger_error("Undefined content char: ".$char." at pos:".$pointer, E_USER_ERROR);
}
#print_r($cur_node);
}
#print "STOP\n";
print_r($cur_node);

}
loads($data);
?>