containers = $this->parseContainer($data); // For debugging if (FALSE) $this->debug = hex_dump($data ?: $this->data(min($size,256))); } private function parseContainer(string $bytes=NULL): Collection { $this->be = FALSE; // @todo $rp = 0; if (! $bytes) { $fh = fopen($this->filename,'r'); fseek($fh,$this->offset); } $result = collect(); // Our first container should be hrl $read = $bytes ? substr($bytes,$rp,4) : fread($fh,4); $rp += 4; $header = unpack('a4name',$read); switch ($header['name']) { case 'hdrl': case 'strl': case 'INFO': while ($rp < $this->size) { $read = $bytes ? substr($bytes,$rp,8) : fread($fh,8); $rp += 8; $header = unpack('a4name/Vsize',$read); // We cant have a php function named 'list', so we change it to rlist if ($header['name'] === 'LIST') $header['name'] = 'RLIST'; $class = self::container_classes.$header['name']; $data = $bytes ? substr($bytes,$rp,$header['size']) : ($header['size'] && ($header['size'] <= self::record_size) ? fread($fh,$header['size']) : NULL); if ($header['size']) { $o = class_exists($class) ? new $class($this->offset+$rp,$header['size'],$this->filename,$this->be,$data) : new Unknown($this->offset+$rp,$header['size'],$this->filename,$header['name'],$this->be,$data); $result->push($o); $rp += $header['size']; // Only need to seek if we didnt read all the data if ((! $bytes) && ($header['size'] > self::record_size)) fseek($fh,$this->offset+$rp); } else { dd([get_class($this) => $data,'header'=>$header,'ptr'=>$rp,'size'=>$this->size,'bytes'=>$bytes]); } } break; case 'movi': $result->push(new movi($this->offset,$this->size,$this->filename,$this->be)); break; default: throw new \Exception('Unhandled header type: '.$header['name']); } if (! $bytes) { fclose($fh); unset($fh); } return $result; } }