Reworked OLE Reader logic to provide a single stream reader for all streams (Workbook, Properties and Document Properties) rather than duplicating code with separate stream readers for each

git-svn-id: https://phpexcel.svn.codeplex.com/svn/trunk@65086 2327b42d-5241-43d6-9e2a-de5ac946f064
This commit is contained in:
Mark Baker 2010-12-10 00:28:18 +00:00
parent 1fad8bd2dd
commit 1def6cae75
2 changed files with 28 additions and 125 deletions

View File

@ -944,15 +944,16 @@ class PHPExcel_Reader_Excel5 implements PHPExcel_Reader_IReader
// OLE reader // OLE reader
$ole = new PHPExcel_Shared_OLERead(); $ole = new PHPExcel_Shared_OLERead();
// get excel data // get excel data,
$res = $ole->read($pFilename); $res = $ole->read($pFilename);
$this->_data = $ole->getWorkBook(); // Get workbook data: workbook stream + sheet streams
$this->_data = $ole->getStream($ole->wrkbook);
// Get summary information data // Get summary information data
$this->_summaryInformation = $ole->getSummaryInformation(); $this->_summaryInformation = $ole->getStream($ole->summaryInformation);
// Get additional document summary information data // Get additional document summary information data
$this->_documentSummaryInformation = $ole->getDocumentSummaryInformation(); $this->_documentSummaryInformation = $ole->getStream($ole->documentSummaryInformation);
// Get user-defined property data // Get user-defined property data
// $this->_userDefinedProperties = $ole->getUserDefinedProperties(); // $this->_userDefinedProperties = $ole->getUserDefinedProperties();

View File

@ -59,6 +59,13 @@ class PHPExcel_Shared_OLERead {
const START_BLOCK_POS = 0x74; const START_BLOCK_POS = 0x74;
const SIZE_POS = 0x78; const SIZE_POS = 0x78;
public $wrkbook = null;
public $summaryInformation = null;
public $documentSummaryInformation = null;
/** /**
* Read the file * Read the file
* *
@ -124,8 +131,7 @@ class PHPExcel_Shared_OLERead {
} }
} }
$pos = 0; $pos = $index = 0;
$index = 0;
$this->bigBlockChain = array(); $this->bigBlockChain = array();
$bbs = self::BIG_BLOCK_SIZE / 4; $bbs = self::BIG_BLOCK_SIZE / 4;
@ -139,8 +145,7 @@ class PHPExcel_Shared_OLERead {
} }
} }
$pos = 0; $pos = $index = 0;
$index = 0;
$sbdBlock = $this->sbdStartBlock; $sbdBlock = $this->sbdStartBlock;
$this->smallBlockChain = array(); $this->smallBlockChain = array();
@ -156,79 +161,31 @@ class PHPExcel_Shared_OLERead {
$sbdBlock = $this->bigBlockChain[$sbdBlock]; $sbdBlock = $this->bigBlockChain[$sbdBlock];
} }
$block = $this->rootStartBlock;
$pos = 0;
// read the directory stream // read the directory stream
$block = $this->rootStartBlock;
$this->entry = $this->_readData($block); $this->entry = $this->_readData($block);
$this->_readPropertySets(); $this->_readPropertySets();
} }
/** /**
* Extract binary stream data, workbook stream + sheet streams * Extract binary stream data
* *
* @return string * @return string
*/ */
public function getWorkBook() public function getStream($stream)
{ {
if ($this->props[$this->wrkbook]['size'] < self::SMALL_BLOCK_THRESHOLD){ if (is_null($stream)) {
$rootdata = $this->_readData($this->props[$this->rootentry]['startBlock']);
$streamData = '';
$block = $this->props[$this->wrkbook]['startBlock'];
$pos = 0;
while ($block != -2) {
$pos = $block * self::SMALL_BLOCK_SIZE;
$streamData .= substr($rootdata, $pos, self::SMALL_BLOCK_SIZE);
$block = $this->smallBlockChain[$block];
}
return $streamData;
} else {
$numBlocks = $this->props[$this->wrkbook]['size'] / self::BIG_BLOCK_SIZE;
if ($this->props[$this->wrkbook]['size'] % self::BIG_BLOCK_SIZE != 0) {
++$numBlocks;
}
if ($numBlocks == 0) return '';
$streamData = '';
$block = $this->props[$this->wrkbook]['startBlock'];
$pos = 0;
while ($block != -2) {
$pos = ($block + 1) * self::BIG_BLOCK_SIZE;
$streamData .= substr($this->data, $pos, self::BIG_BLOCK_SIZE);
$block = $this->bigBlockChain[$block];
}
return $streamData;
}
}
/**
* Extract binary stream data, summary information
*
* @return string|null
*/
public function getSummaryInformation()
{
if (!isset($this->summaryInformation)) {
return null; return null;
} }
if ($this->props[$this->summaryInformation]['size'] < self::SMALL_BLOCK_THRESHOLD){ $streamData = '';
if ($this->props[$stream]['size'] < self::SMALL_BLOCK_THRESHOLD) {
$rootdata = $this->_readData($this->props[$this->rootentry]['startBlock']); $rootdata = $this->_readData($this->props[$this->rootentry]['startBlock']);
$streamData = ''; $block = $this->props[$stream]['startBlock'];
$block = $this->props[$this->summaryInformation]['startBlock'];
$pos = 0;
while ($block != -2) { while ($block != -2) {
$pos = $block * self::SMALL_BLOCK_SIZE; $pos = $block * self::SMALL_BLOCK_SIZE;
$streamData .= substr($rootdata, $pos, self::SMALL_BLOCK_SIZE); $streamData .= substr($rootdata, $pos, self::SMALL_BLOCK_SIZE);
@ -237,69 +194,15 @@ class PHPExcel_Shared_OLERead {
} }
return $streamData; return $streamData;
} else { } else {
$numBlocks = $this->props[$this->summaryInformation]['size'] / self::BIG_BLOCK_SIZE; $numBlocks = $this->props[$stream]['size'] / self::BIG_BLOCK_SIZE;
if ($this->props[$this->summaryInformation]['size'] % self::BIG_BLOCK_SIZE != 0) { if ($this->props[$stream]['size'] % self::BIG_BLOCK_SIZE != 0) {
++$numBlocks; ++$numBlocks;
} }
if ($numBlocks == 0) return ''; if ($numBlocks == 0) return '';
$streamData = ''; $block = $this->props[$stream]['startBlock'];
$block = $this->props[$this->summaryInformation]['startBlock'];
$pos = 0;
while ($block != -2) {
$pos = ($block + 1) * self::BIG_BLOCK_SIZE;
$streamData .= substr($this->data, $pos, self::BIG_BLOCK_SIZE);
$block = $this->bigBlockChain[$block];
}
return $streamData;
}
}
/**
* Extract binary stream data, additional document summary information
*
* @return string|null
*/
public function getDocumentSummaryInformation()
{
if (!isset($this->documentSummaryInformation)) {
return null;
}
if ($this->props[$this->documentSummaryInformation]['size'] < self::SMALL_BLOCK_THRESHOLD){
$rootdata = $this->_readData($this->props[$this->rootentry]['startBlock']);
$streamData = '';
$block = $this->props[$this->documentSummaryInformation]['startBlock'];
$pos = 0;
while ($block != -2) {
$pos = $block * self::SMALL_BLOCK_SIZE;
$streamData .= substr($rootdata, $pos, self::SMALL_BLOCK_SIZE);
$block = $this->smallBlockChain[$block];
}
return $streamData;
} else {
$numBlocks = $this->props[$this->documentSummaryInformation]['size'] / self::BIG_BLOCK_SIZE;
if ($this->props[$this->documentSummaryInformation]['size'] % self::BIG_BLOCK_SIZE != 0) {
++$numBlocks;
}
if ($numBlocks == 0) return '';
$streamData = '';
$block = $this->props[$this->documentSummaryInformation]['startBlock'];
$pos = 0;
while ($block != -2) { while ($block != -2) {
$pos = ($block + 1) * self::BIG_BLOCK_SIZE; $pos = ($block + 1) * self::BIG_BLOCK_SIZE;
@ -320,7 +223,6 @@ class PHPExcel_Shared_OLERead {
private function _readData($bl) private function _readData($bl)
{ {
$block = $bl; $block = $bl;
$pos = 0;
$data = ''; $data = '';
while ($block != -2) { while ($block != -2) {
@ -334,12 +236,12 @@ class PHPExcel_Shared_OLERead {
/** /**
* Read entries in the directory stream. * Read entries in the directory stream.
*/ */
private function _readPropertySets() private function _readPropertySets() {
{
$offset = 0; $offset = 0;
// loop through entires, each entry is 128 bytes // loop through entires, each entry is 128 bytes
while ($offset < strlen($this->entry)) { $entryLen = strlen($this->entry);
while ($offset < $entryLen) {
// entry data (128 bytes) // entry data (128 bytes)
$d = substr($this->entry, $offset, self::PROPERTY_STORAGE_BLOCK_SIZE); $d = substr($this->entry, $offset, self::PROPERTY_STORAGE_BLOCK_SIZE);