/** * Gets information about all PPS's on the OLE container from the PPS WK's * creates an OLE_PPS object for each one. * * @access private * @param integer $pps_wk_start Position inside the OLE file where PPS WK's start * @param integer $big_block_size Size of big blobks in the OLE file * @return mixed true on success, PEAR_Error on failure */ function _readPpsWks($pps_wk_start, $big_block_size) { $pointer = ($pps_wk_start + 1) * $big_block_size; while (1) { fseek($this->_file_handle, $pointer); $pps_wk = fread($this->_file_handle, OLE_PPS_SIZE); if (strlen($pps_wk) != OLE_PPS_SIZE) { break; // Excel likes to add a trailing byte sometimes //return $this->raiseError("PPS at $pointer seems too short: ".strlen($pps_wk)); } $name_length = unpack("c", substr($pps_wk, 64, 2)); // FIXME (2 bytes??) $name_length = $name_length[''] - 2; $name = substr($pps_wk, 0, $name_length); $type = unpack("c", substr($pps_wk, 66, 1)); if (($type[''] != OLE_PPS_TYPE_ROOT) and ($type[''] != OLE_PPS_TYPE_DIR) and ($type[''] != OLE_PPS_TYPE_FILE)) { return $this->raiseError("PPS at $pointer has unknown type: {$type['']}"); } $prev = unpack("V", substr($pps_wk, 68, 4)); $next = unpack("V", substr($pps_wk, 72, 4)); $dir = unpack("V", substr($pps_wk, 76, 4)); // there is no magic number, it can take different values. //$magic = unpack("V", strrev(substr($pps_wk, 92, 4))); $time_1st = substr($pps_wk, 100, 8); $time_2nd = substr($pps_wk, 108, 8); $start_block = unpack("V", substr($pps_wk, 116, 4)); $size = unpack("V", substr($pps_wk, 120, 4)); // _data member will point to position in file!! // OLE_PPS object is created with an empty children array!! $this->_list[] = new OLE_PPS(null, '', $type[''], $prev[''], $next[''], $dir[''], OLE::OLE2LocalDate($time_1st), OLE::OLE2LocalDate($time_2nd), ($start_block[''] + 1) * $big_block_size, array()); // give it a size $this->_list[count($this->_list) - 1]->Size = $size['']; // check if the PPS tree (starting from root) is complete if ($this->_ppsTreeComplete(0)) { break; } $pointer += OLE_PPS_SIZE; } }
/** * Gets information about all PPS's on the OLE container from the PPS WK's * creates an OLE_PPS object for each one. * * @access private * @param integer $blockId the block id of the first block * @return mixed true on success, PEAR_Error on failure */ function _readPpsWks($blockId) { global $FANNIE_ROOT; $fh = $this->getStream($blockId); for ($pos = 0;; $pos += 128) { fseek($fh, $pos, SEEK_SET); $nameUtf16 = fread($fh, 64); $nameLength = $this->_readInt2($fh); $nameUtf16 = substr($nameUtf16, 0, $nameLength - 2); // Simple conversion from UTF-16LE to ISO-8859-1 $name = str_replace("", "", $nameUtf16); $type = $this->_readInt1($fh); switch ($type) { case OLE_PPS_TYPE_ROOT: require_once dirname(__FILE__) . '/PPS/Root.php'; $pps = new OLE_PPS_Root(null, null, array()); $this->root = $pps; break; case OLE_PPS_TYPE_DIR: $pps = new OLE_PPS(null, null, null, null, null, null, null, null, null, array()); break; case OLE_PPS_TYPE_FILE: require_once dirname(__FILE__) . '/PPS/File.php'; $pps = new OLE_PPS_File($name); break; default: continue; } fseek($fh, 1, SEEK_CUR); $pps->Type = $type; $pps->Name = $name; $pps->PrevPps = $this->_readInt4($fh); $pps->NextPps = $this->_readInt4($fh); $pps->DirPps = $this->_readInt4($fh); fseek($fh, 20, SEEK_CUR); $pps->Time1st = OLE::OLE2LocalDate(fread($fh, 8)); $pps->Time2nd = OLE::OLE2LocalDate(fread($fh, 8)); $pps->_StartBlock = $this->_readInt4($fh); $pps->Size = $this->_readInt4($fh); $pps->No = count($this->_list); $this->_list[] = $pps; // check if the PPS tree (starting from root) is complete if (isset($this->root) && $this->_ppsTreeComplete($this->root->No)) { break; } } fclose($fh); // Initialize $pps->children on directories foreach ($this->_list as $pps) { if ($pps->Type == OLE_PPS_TYPE_DIR || $pps->Type == OLE_PPS_TYPE_ROOT) { $nos = array($pps->DirPps); $pps->children = array(); while ($nos) { $no = array_pop($nos); if ($no != -1) { $childPps = $this->_list[$no]; $nos[] = $childPps->PrevPps; $nos[] = $childPps->NextPps; $pps->children[] = $childPps; } } } } return true; }