/** * Parse a binary plist string * @return void * @throws IOException if read error occurs */ public function parseBinaryString() { $this->uniqueTable = array(); $this->countObjects = 0; $this->stringSize = 0; $this->intSize = 0; $this->miscSize = 0; $this->objectRefs = 0; $this->writtenObjectCount = 0; $this->objectTable = array(); $this->objectRefSize = 0; $this->offsets = array(); // first, we read the trailer: 32 byte from the end $buff = substr($this->content, -32); if (strlen($buff) < 32) { throw new PListException('Error in PList format: content is less than at least necessary 32 bytes!'); } $infos = unpack("x6/Coffset_size/Cobject_ref_size/x4/Nnumber_of_objects/x4/Ntop_object/x4/Ntable_offset", $buff); // after that, get the offset table $coded_offset_table = substr($this->content, $infos['table_offset'], $infos['number_of_objects'] * $infos['offset_size']); if (strlen($coded_offset_table) != $infos['number_of_objects'] * $infos['offset_size']) { throw IOException::readError(""); } $this->countObjects = $infos['number_of_objects']; // decode offset table $formats = array("", "C*", "n*", NULL, "N*"); if ($infos['offset_size'] == 3) { # since PHP does not support parenthesis in pack/unpack expressions, # "(H6)*" does not work and we have to work round this by repeating the # expression as often as it fits in the string $this->offsets = array(NULL); while ($coded_offset_table) { $str = unpack("H6", $coded_offset_table); $this->offsets[] = hexdec($str[1]); $coded_offset_table = substr($coded_offset_table, 3); } } else { $this->offsets = unpack($formats[$infos['offset_size']], $coded_offset_table); } $this->uniqueTable = array(); $this->objectRefSize = $infos['object_ref_size']; $top = $this->readBinaryObjectAt($infos['top_object'] + 1); $this->add($top); }
/** * Read a binary plist file * @param string $file The file to read * @return void * @throws IOException if read error occurs */ function readBinary($file) { $this->uniqueTable = array(); $this->countObjects = 0; $this->stringSize = 0; $this->intSize = 0; $this->miscSize = 0; $this->objectRefs = 0; $this->writtenObjectCount = 0; $this->objectTable = array(); $this->objectRefSize = 0; $this->offsets = array(); $fd = fopen($file, "rb"); // first, we read the trailer: 32 byte from the end fseek($fd, -32, SEEK_END); $buff = fread($fd, 32); $infos = unpack("x6/Coffset_size/Cobject_ref_size/x4/Nnumber_of_objects/x4/Ntop_object/x4/Ntable_offset", $buff); // after that, get the offset table fseek($fd, $infos['table_offset'], SEEK_SET); $coded_offset_table = fread($fd, $infos['number_of_objects'] * $infos['offset_size']); if (strlen($coded_offset_table) != $infos['number_of_objects'] * $infos['offset_size']) { throw IOException::readError($file); } $this->countObjects = $infos['number_of_objects']; // decode offset table $formats = array("", "C*", "n*", "(H6)*", "N*"); $this->offsets = unpack($formats[$infos['offset_size']], $coded_offset_table); if ($infos['offset_size'] == 3) { foreach ($this->offsets as $k => $v) { $this->offsets[$k] = hexdec($v); } } $this->uniqueTable = array(); $this->objectRefSize = $infos['object_ref_size']; $top = $this->readBinaryObjectAt($file, $fd, $infos['top_object'] + 1); $this->add($top); fclose($fd); }
public function parseBinaryString() { $this->uniqueTable = array(); $this->countObjects = 0; $this->stringSize = 0; $this->intSize = 0; $this->miscSize = 0; $this->objectRefs = 0; $this->writtenObjectCount = 0; $this->objectTable = array(); $this->objectRefSize = 0; $this->offsets = array(); $buff = substr($this->content, -32); $infos = unpack("x6/Coffset_size/Cobject_ref_size/x4/Nnumber_of_objects/x4/Ntop_object/x4/Ntable_offset", $buff); $coded_offset_table = substr($this->content, $infos['table_offset'], $infos['number_of_objects'] * $infos['offset_size']); if (strlen($coded_offset_table) != $infos['number_of_objects'] * $infos['offset_size']) { throw IOException::readError(""); } $this->countObjects = $infos['number_of_objects']; $formats = array("", "C*", "n*", NULL, "N*"); if ($infos['offset_size'] == 3) { $this->offsets = array(NULL); while ($coded_offset_table) { $str = unpack("H6", $coded_offset_table); $this->offsets[] = hexdec($str[1]); $coded_offset_table = substr($coded_offset_table, 3); } } else { $this->offsets = unpack($formats[$infos['offset_size']], $coded_offset_table); } $this->uniqueTable = array(); $this->objectRefSize = $infos['object_ref_size']; $top = $this->readBinaryObjectAt($infos['top_object'] + 1); $this->add($top); }