Performance improvements for the Excel5 Reader and Writer

git-svn-id: https://phpexcel.svn.codeplex.com/svn/trunk@64968 2327b42d-5241-43d6-9e2a-de5ac946f064
This commit is contained in:
Mark Baker 2010-12-07 17:34:47 +00:00
parent 1238c6086d
commit c5ea92442d
7 changed files with 99 additions and 104 deletions

View File

@ -2630,10 +2630,10 @@ class PHPExcel_Calculation {
// echo 'Element is a Percentage operator<br />';
$stack->push('Unary Operator','%'); // Put a percentage on the stack
++$index;
} elseif ($opCharacter == '+' && !$expectingOperator) { // Positive (rather than plus) can be discarded?
} elseif ($opCharacter == '+' && !$expectingOperator) { // Positive (unary plus rather than binary operator plus) can be discarded?
// echo 'Element is a Positive number, not Plus operator<br />';
++$index; // Drop the redundant plus symbol
} elseif (($opCharacter == '~') && (!$isOperandOrFunction)) { // We have to explicitly deny a tilde, because it's legal
} elseif ((($opCharacter == '~') || ($opCharacter == '|')) && (!$isOperandOrFunction)) { // We have to explicitly deny a tilde or pipe, because they are legal
return $this->_raiseFormulaError("Formula Error: Illegal character '~'"); // on the stack but not in the input expression
} elseif ((isset(self::$_operators[$opCharacter]) or $isOperandOrFunction) && $expectingOperator) { // Are we putting an operator on the stack?
@ -3278,7 +3278,7 @@ class PHPExcel_Calculation {
// echo 'Token is a PHPExcel constant: '.$excelConstant.'<br />';
$stack->push('Constant Value',self::$_ExcelConstants[$excelConstant]);
$this->_writeDebug('Evaluating Constant '.$excelConstant.' as '.$this->_showTypeDetails(self::$_ExcelConstants[$excelConstant]));
} elseif ((is_numeric($token)) || (is_bool($token)) || (is_null($token)) || ($token == '') || ($token{0} == '"') || ($token{0} == '#')) {
} elseif ((is_numeric($token)) || (is_null($token)) || (is_bool($token)) || ($token == '') || ($token{0} == '"') || ($token{0} == '#')) {
// echo 'Token is a number, boolean, string, null or an Excel error<br />';
$stack->push('Value',$token);
// if the token is a named range, push the named range name onto the stack

View File

@ -570,7 +570,7 @@ class PHPExcel_Reader_Excel5 implements PHPExcel_Reader_IReader
if (!$this->_readDataOnly) {
foreach ($this->_objFonts as $objFont) {
if (isset($objFont->colorIndex)) {
$color = self::_readColor($objFont->colorIndex,$this->_palette);
$color = self::_readColor($objFont->colorIndex,$this->_palette,$this->_version);
$objFont->getColor()->setRGB($color['rgb']);
}
}
@ -580,12 +580,12 @@ class PHPExcel_Reader_Excel5 implements PHPExcel_Reader_IReader
$fill = $objStyle->getFill();
if (isset($fill->startcolorIndex)) {
$startColor = self::_readColor($fill->startcolorIndex,$this->_palette);
$startColor = self::_readColor($fill->startcolorIndex,$this->_palette,$this->_version);
$fill->getStartColor()->setRGB($startColor['rgb']);
}
if (isset($fill->endcolorIndex)) {
$endColor = self::_readColor($fill->endcolorIndex,$this->_palette);
$endColor = self::_readColor($fill->endcolorIndex,$this->_palette,$this->_version);
$fill->getEndColor()->setRGB($endColor['rgb']);
}
@ -597,27 +597,27 @@ class PHPExcel_Reader_Excel5 implements PHPExcel_Reader_IReader
$diagonal = $objStyle->getBorders()->getDiagonal();
if (isset($top->colorIndex)) {
$borderTopColor = self::_readColor($top->colorIndex,$this->_palette);
$borderTopColor = self::_readColor($top->colorIndex,$this->_palette,$this->_version);
$top->getColor()->setRGB($borderTopColor['rgb']);
}
if (isset($right->colorIndex)) {
$borderRightColor = self::_readColor($right->colorIndex,$this->_palette);
$borderRightColor = self::_readColor($right->colorIndex,$this->_palette,$this->_version);
$right->getColor()->setRGB($borderRightColor['rgb']);
}
if (isset($bottom->colorIndex)) {
$borderBottomColor = self::_readColor($bottom->colorIndex,$this->_palette);
$borderBottomColor = self::_readColor($bottom->colorIndex,$this->_palette,$this->_version);
$bottom->getColor()->setRGB($borderBottomColor['rgb']);
}
if (isset($left->colorIndex)) {
$borderLeftColor = self::_readColor($left->colorIndex,$this->_palette);
$borderLeftColor = self::_readColor($left->colorIndex,$this->_palette,$this->_version);
$left->getColor()->setRGB($borderLeftColor['rgb']);
}
if (isset($diagonal->colorIndex)) {
$borderDiagonalColor = self::_readColor($diagonal->colorIndex,$this->_palette);
$borderDiagonalColor = self::_readColor($diagonal->colorIndex,$this->_palette,$this->_version);
$diagonal->getColor()->setRGB($borderDiagonalColor['rgb']);
}
}
@ -4229,7 +4229,7 @@ class PHPExcel_Reader_Excel5 implements PHPExcel_Reader_IReader
case 0x14:
// offset: 16; size: 2; color index for sheet tab
$colorIndex = self::_GetInt2d($recordData, 16);
$color = self::_readColor($colorIndex,$this->_palette);
$color = self::_readColor($colorIndex,$this->_palette,$this->_version);
$this->_phpSheet->getTabColor()->setRGB($color['rgb']);
break;
@ -4665,7 +4665,7 @@ class PHPExcel_Reader_Excel5 implements PHPExcel_Reader_IReader
case 'tAdd': // addition
case 'tConcat': // addition
case 'tDiv': // division
case 'tEQ': // equaltiy
case 'tEQ': // equality
case 'tGE': // greater than or equal
case 'tGT': // greater than
case 'tIsect': // intersection
@ -6124,11 +6124,9 @@ class PHPExcel_Reader_Excel5 implements PHPExcel_Reader_IReader
*/
private static function _GetInt4d($data, $pos)
{
//return ord($data[$pos]) | (ord($data[$pos + 1]) << 8) |
// (ord($data[$pos + 2]) << 16) | (ord($data[$pos + 3]) << 24);
// FIX: represent numbers correctly on 64-bit system
// http://sourceforge.net/tracker/index.php?func=detail&aid=1487372&group_id=99160&atid=623334
// Hacked by Andreas Rehm 2006 to ensure correct result of the <<24 block on 32 and 64bit systems
$_or_24 = ord($data[$pos + 3]);
if ($_or_24 >= 128) {
// negative number
@ -6146,7 +6144,7 @@ class PHPExcel_Reader_Excel5 implements PHPExcel_Reader_IReader
* @param array $palette Color palette
* @return array RGB color value, example: array('rgb' => 'FF0000')
*/
private static function _readColor($color,$palette)
private static function _readColor($color,$palette,$version)
{
if ($color <= 0x07 || $color >= 0x40) {
// special built-in color
@ -6156,7 +6154,7 @@ class PHPExcel_Reader_Excel5 implements PHPExcel_Reader_IReader
return $palette[$color - 8];
} else {
// default color table
if ($this->_version == self::XLS_BIFF8) {
if ($version == self::XLS_BIFF8) {
return self::_mapColor($color);
} else {
// BIFF5

View File

@ -111,36 +111,36 @@ class PHPExcel_Shared_OLE
throw new Exception("Only Little-Endian encoding is supported.");
}
// Size of blocks and short blocks in bytes
$this->bigBlockSize = pow(2, $this->_readInt2($fh));
$this->smallBlockSize = pow(2, $this->_readInt2($fh));
$this->bigBlockSize = pow(2, self::_readInt2($fh));
$this->smallBlockSize = pow(2, self::_readInt2($fh));
// Skip UID, revision number and version number
fseek($fh, 44);
// Number of blocks in Big Block Allocation Table
$bbatBlockCount = $this->_readInt4($fh);
$bbatBlockCount = self::_readInt4($fh);
// Root chain 1st block
$directoryFirstBlockId = $this->_readInt4($fh);
$directoryFirstBlockId = self::_readInt4($fh);
// Skip unused bytes
fseek($fh, 56);
// Streams shorter than this are stored using small blocks
$this->bigBlockThreshold = $this->_readInt4($fh);
$this->bigBlockThreshold = self::_readInt4($fh);
// Block id of first sector in Short Block Allocation Table
$sbatFirstBlockId = $this->_readInt4($fh);
$sbatFirstBlockId = self::_readInt4($fh);
// Number of blocks in Short Block Allocation Table
$sbbatBlockCount = $this->_readInt4($fh);
$sbbatBlockCount = self::_readInt4($fh);
// Block id of first sector in Master Block Allocation Table
$mbatFirstBlockId = $this->_readInt4($fh);
$mbatFirstBlockId = self::_readInt4($fh);
// Number of blocks in Master Block Allocation Table
$mbbatBlockCount = $this->_readInt4($fh);
$mbbatBlockCount = self::_readInt4($fh);
$this->bbat = array();
// Remaining 4 * 109 bytes of current block is beginning of Master
// Block Allocation Table
$mbatBlocks = array();
for ($i = 0; $i < 109; ++$i) {
$mbatBlocks[] = $this->_readInt4($fh);
$mbatBlocks[] = self::_readInt4($fh);
}
// Read rest of Master Block Allocation Table (if any is left)
@ -148,10 +148,10 @@ class PHPExcel_Shared_OLE
for ($i = 0; $i < $mbbatBlockCount; ++$i) {
fseek($fh, $pos);
for ($j = 0; $j < $this->bigBlockSize / 4 - 1; ++$j) {
$mbatBlocks[] = $this->_readInt4($fh);
$mbatBlocks[] = self::_readInt4($fh);
}
// Last block id in each block points to next block
$pos = $this->_getBlockOffset($this->_readInt4($fh));
$pos = $this->_getBlockOffset(self::_readInt4($fh));
}
// Read Big Block Allocation Table according to chain specified by
@ -160,7 +160,7 @@ class PHPExcel_Shared_OLE
$pos = $this->_getBlockOffset($mbatBlocks[$i]);
fseek($fh, $pos);
for ($j = 0 ; $j < $this->bigBlockSize / 4; ++$j) {
$this->bbat[] = $this->_readInt4($fh);
$this->bbat[] = self::_readInt4($fh);
}
}
@ -169,7 +169,7 @@ class PHPExcel_Shared_OLE
$shortBlockCount = $sbbatBlockCount * $this->bigBlockSize / 4;
$sbatFh = $this->getStream($sbatFirstBlockId);
for ($blockId = 0; $blockId < $shortBlockCount; ++$blockId) {
$this->sbat[$blockId] = $this->_readInt4($sbatFh);
$this->sbat[$blockId] = self::_readInt4($sbatFh);
}
fclose($sbatFh);
@ -225,7 +225,7 @@ class PHPExcel_Shared_OLE
* @return int
* @access public
*/
public function _readInt1($fh)
private static function _readInt1($fh)
{
list(, $tmp) = unpack("c", fread($fh, 1));
return $tmp;
@ -237,7 +237,7 @@ class PHPExcel_Shared_OLE
* @return int
* @access public
*/
public function _readInt2($fh)
private static function _readInt2($fh)
{
list(, $tmp) = unpack("v", fread($fh, 2));
return $tmp;
@ -249,7 +249,7 @@ class PHPExcel_Shared_OLE
* @return int
* @access public
*/
public function _readInt4($fh)
private static function _readInt4($fh)
{
list(, $tmp) = unpack("V", fread($fh, 4));
return $tmp;
@ -269,11 +269,11 @@ class PHPExcel_Shared_OLE
for ($pos = 0; ; $pos += 128) {
fseek($fh, $pos, SEEK_SET);
$nameUtf16 = fread($fh, 64);
$nameLength = $this->_readInt2($fh);
$nameLength = self::_readInt2($fh);
$nameUtf16 = substr($nameUtf16, 0, $nameLength - 2);
// Simple conversion from UTF-16LE to ISO-8859-1
$name = str_replace("\x00", "", $nameUtf16);
$type = $this->_readInt1($fh);
$type = self::_readInt1($fh);
switch ($type) {
case self::OLE_PPS_TYPE_ROOT:
$pps = new PHPExcel_Shared_OLE_PPS_Root(null, null, array());
@ -292,14 +292,14 @@ class PHPExcel_Shared_OLE
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);
$pps->PrevPps = self::_readInt4($fh);
$pps->NextPps = self::_readInt4($fh);
$pps->DirPps = self::_readInt4($fh);
fseek($fh, 20, SEEK_CUR);
$pps->Time1st = self::OLE2LocalDate(fread($fh, 8));
$pps->Time2nd = self::OLE2LocalDate(fread($fh, 8));
$pps->_StartBlock = $this->_readInt4($fh);
$pps->Size = $this->_readInt4($fh);
$pps->_StartBlock = self::_readInt4($fh);
$pps->Size = self::_readInt4($fh);
$pps->No = count($this->_list);
$this->_list[] = $pps;

View File

@ -169,10 +169,8 @@ class PHPExcel_Shared_OLE_PPS
*/
public function _getPpsWk()
{
$ret = $this->Name;
for ($i = 0; $i < (64 - strlen($this->Name)); ++$i) {
$ret .= "\x00";
}
$ret = str_pad($this->Name,64,"\x00");
$ret .= pack("v", strlen($this->Name) + 2) // 66
. pack("c", $this->Type) // 67
. pack("c", 0x00) //UK // 68
@ -215,4 +213,4 @@ class PHPExcel_Shared_OLE_PPS
}
return $this->No;
}
}
}

View File

@ -63,9 +63,9 @@ class PHPExcel_Shared_OLE_PPS_Root extends PHPExcel_Shared_OLE_PPS
{
// Initial Setting for saving
$this->_BIG_BLOCK_SIZE = pow(2,
((isset($this->_BIG_BLOCK_SIZE))? $this->_adjust2($this->_BIG_BLOCK_SIZE) : 9));
((isset($this->_BIG_BLOCK_SIZE))? self::_adjust2($this->_BIG_BLOCK_SIZE) : 9));
$this->_SMALL_BLOCK_SIZE= pow(2,
((isset($this->_SMALL_BLOCK_SIZE))? $this->_adjust2($this->_SMALL_BLOCK_SIZE): 6));
((isset($this->_SMALL_BLOCK_SIZE))? self::_adjust2($this->_SMALL_BLOCK_SIZE): 6));
if (is_resource($filename)) {
$this->_FILEH_ = $filename;
@ -119,7 +119,8 @@ class PHPExcel_Shared_OLE_PPS_Root extends PHPExcel_Shared_OLE_PPS
list($iSBDcnt, $iBBcnt, $iPPScnt) = array(0,0,0);
$iSmallLen = 0;
$iSBcnt = 0;
for ($i = 0; $i < count($raList); ++$i) {
$iCount = count($raList);
for ($i = 0; $i < $iCount; ++$i) {
if ($raList[$i]->Type == PHPExcel_Shared_OLE::OLE_PPS_TYPE_FILE) {
$raList[$i]->Size = $raList[$i]->_DataLen();
if ($raList[$i]->Size < PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL) {
@ -151,7 +152,7 @@ class PHPExcel_Shared_OLE_PPS_Root extends PHPExcel_Shared_OLE_PPS
* @see save()
* @return integer
*/
public function _adjust2($i2)
private static function _adjust2($i2)
{
$iWk = log($i2)/log(2);
return ($iWk > floor($iWk))? floor($iWk)+1:$iWk;
@ -229,7 +230,8 @@ class PHPExcel_Shared_OLE_PPS_Root extends PHPExcel_Shared_OLE_PPS
fwrite($FILE, pack("V", $iAll+$i));
}
if ($i < $i1stBdL) {
for ($j = 0; $j < ($i1stBdL-$i); ++$j) {
$jB = $i1stBdL - $i;
for ($j = 0; $j < $jB; ++$j) {
fwrite($FILE, (pack("V", -1)));
}
}
@ -247,7 +249,8 @@ class PHPExcel_Shared_OLE_PPS_Root extends PHPExcel_Shared_OLE_PPS
$FILE = $this->_FILEH_;
// cycle through PPS's
for ($i = 0; $i < count($raList); ++$i) {
$iCount = count($raList);
for ($i = 0; $i < $iCount; ++$i) {
if ($raList[$i]->Type != PHPExcel_Shared_OLE::OLE_PPS_TYPE_DIR) {
$raList[$i]->Size = $raList[$i]->_DataLen();
if (($raList[$i]->Size >= PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL) ||
@ -266,9 +269,7 @@ class PHPExcel_Shared_OLE_PPS_Root extends PHPExcel_Shared_OLE_PPS
//}
if ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE) {
for ($j = 0; $j < ($this->_BIG_BLOCK_SIZE - ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)); ++$j) {
fwrite($FILE, "\x00");
}
fwrite($FILE, str_repeat("\x00", $this->_BIG_BLOCK_SIZE - ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)));
}
// Set For PPS
$raList[$i]->_StartBlock = $iStBlk;
@ -298,7 +299,8 @@ class PHPExcel_Shared_OLE_PPS_Root extends PHPExcel_Shared_OLE_PPS
$FILE = $this->_FILEH_;
$iSmBlk = 0;
for ($i = 0; $i < count($raList); ++$i) {
$iCount = count($raList);
for ($i = 0; $i < $iCount; ++$i) {
// Make SBD, small data string
if ($raList[$i]->Type == PHPExcel_Shared_OLE::OLE_PPS_TYPE_FILE) {
if ($raList[$i]->Size <= 0) {
@ -308,7 +310,8 @@ class PHPExcel_Shared_OLE_PPS_Root extends PHPExcel_Shared_OLE_PPS
$iSmbCnt = floor($raList[$i]->Size / $this->_SMALL_BLOCK_SIZE)
+ (($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)? 1: 0);
// Add to SBD
for ($j = 0; $j < ($iSmbCnt-1); ++$j) {
$jB = $iSmbCnt - 1;
for ($j = 0; $j < $jB; ++$j) {
fwrite($FILE, pack("V", $j+$iSmBlk+1));
}
fwrite($FILE, pack("V", -2));
@ -323,9 +326,7 @@ class PHPExcel_Shared_OLE_PPS_Root extends PHPExcel_Shared_OLE_PPS
$sRes .= $raList[$i]->_data;
//}
if ($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE) {
for ($j = 0; $j < ($this->_SMALL_BLOCK_SIZE - ($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)); ++$j) {
$sRes .= "\x00";
}
$sRes .= str_repeat("\x00",$this->_SMALL_BLOCK_SIZE - ($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE));
}
// Set for PPS
$raList[$i]->_StartBlock = $iSmBlk;
@ -335,7 +336,8 @@ class PHPExcel_Shared_OLE_PPS_Root extends PHPExcel_Shared_OLE_PPS
}
$iSbCnt = floor($this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE);
if ($iSmBlk % $iSbCnt) {
for ($i = 0; $i < ($iSbCnt - ($iSmBlk % $iSbCnt)); ++$i) {
$iB = $iSbCnt - ($iSmBlk % $iSbCnt);
for ($i = 0; $i < $iB; ++$i) {
fwrite($FILE, pack("V", -1));
}
}
@ -351,16 +353,15 @@ class PHPExcel_Shared_OLE_PPS_Root extends PHPExcel_Shared_OLE_PPS
public function _savePps(&$raList)
{
// Save each PPS WK
for ($i = 0; $i < count($raList); ++$i) {
$iC = count($raList);
for ($i = 0; $i < $iC; ++$i) {
fwrite($this->_FILEH_, $raList[$i]->_getPpsWk());
}
// Adjust for Block
$iCnt = count($raList);
$iBCnt = $this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_PPS_SIZE;
if ($iCnt % $iBCnt) {
for ($i = 0; $i < (($iBCnt - ($iCnt % $iBCnt)) * PHPExcel_Shared_OLE::OLE_PPS_SIZE); ++$i) {
fwrite($this->_FILEH_, "\x00");
}
fwrite($this->_FILEH_, str_repeat("\x00",($iBCnt - ($iCnt % $iBCnt)) * PHPExcel_Shared_OLE::OLE_PPS_SIZE));
}
}
@ -426,7 +427,8 @@ class PHPExcel_Shared_OLE_PPS_Root extends PHPExcel_Shared_OLE_PPS
}
// Adjust for Block
if (($iAllW + $iBdCnt) % $iBbCnt) {
for ($i = 0; $i < ($iBbCnt - (($iAllW + $iBdCnt) % $iBbCnt)); ++$i) {
$iBlock = ($iBbCnt - (($iAllW + $iBdCnt) % $iBbCnt));
for ($i = 0; $i < $iBlock; ++$i) {
fwrite($FILE, pack("V", -1));
}
}
@ -443,11 +445,12 @@ class PHPExcel_Shared_OLE_PPS_Root extends PHPExcel_Shared_OLE_PPS
fwrite($FILE, pack("V", $iBsize+$iSbdSize+$iPpsCnt+$i));
}
if (($iBdCnt-$i1stBdL) % ($iBbCnt-1)) {
for ($i = 0; $i < (($iBbCnt - 1) - (($iBdCnt - $i1stBdL) % ($iBbCnt - 1))); ++$i) {
$iB = ($iBbCnt - 1) - (($iBdCnt - $i1stBdL) % ($iBbCnt - 1));
for ($i = 0; $i < $iB; ++$i) {
fwrite($FILE, pack("V", -1));
}
}
fwrite($FILE, pack("V", -2));
}
}
}
}

View File

@ -81,19 +81,19 @@ class PHPExcel_Shared_OLERead {
}
// Total number of sectors used for the SAT
$this->numBigBlockDepotBlocks = $this->_GetInt4d($this->data, self::NUM_BIG_BLOCK_DEPOT_BLOCKS_POS);
$this->numBigBlockDepotBlocks = self::_GetInt4d($this->data, self::NUM_BIG_BLOCK_DEPOT_BLOCKS_POS);
// SecID of the first sector of the directory stream
$this->rootStartBlock = $this->_GetInt4d($this->data, self::ROOT_START_BLOCK_POS);
$this->rootStartBlock = self::_GetInt4d($this->data, self::ROOT_START_BLOCK_POS);
// SecID of the first sector of the SSAT (or -2 if not extant)
$this->sbdStartBlock = $this->_GetInt4d($this->data, self::SMALL_BLOCK_DEPOT_BLOCK_POS);
$this->sbdStartBlock = self::_GetInt4d($this->data, self::SMALL_BLOCK_DEPOT_BLOCK_POS);
// SecID of the first sector of the MSAT (or -2 if no additional sectors are used)
$this->extensionBlock = $this->_GetInt4d($this->data, self::EXTENSION_BLOCK_POS);
$this->extensionBlock = self::_GetInt4d($this->data, self::EXTENSION_BLOCK_POS);
// Total number of sectors used by MSAT
$this->numExtensionBlocks = $this->_GetInt4d($this->data, self::NUM_EXTENSION_BLOCK_POS);
$this->numExtensionBlocks = self::_GetInt4d($this->data, self::NUM_EXTENSION_BLOCK_POS);
$bigBlockDepotBlocks = array();
$pos = self::BIG_BLOCK_DEPOT_BLOCKS_POS;
@ -105,7 +105,7 @@ class PHPExcel_Shared_OLERead {
}
for ($i = 0; $i < $bbdBlocks; ++$i) {
$bigBlockDepotBlocks[$i] = $this->_GetInt4d($this->data, $pos);
$bigBlockDepotBlocks[$i] = self::_GetInt4d($this->data, $pos);
$pos += 4;
}
@ -114,13 +114,13 @@ class PHPExcel_Shared_OLERead {
$blocksToRead = min($this->numBigBlockDepotBlocks - $bbdBlocks, self::BIG_BLOCK_SIZE / 4 - 1);
for ($i = $bbdBlocks; $i < $bbdBlocks + $blocksToRead; ++$i) {
$bigBlockDepotBlocks[$i] = $this->_GetInt4d($this->data, $pos);
$bigBlockDepotBlocks[$i] = self::_GetInt4d($this->data, $pos);
$pos += 4;
}
$bbdBlocks += $blocksToRead;
if ($bbdBlocks < $this->numBigBlockDepotBlocks) {
$this->extensionBlock = $this->_GetInt4d($this->data, $pos);
$this->extensionBlock = self::_GetInt4d($this->data, $pos);
}
}
@ -128,11 +128,12 @@ class PHPExcel_Shared_OLERead {
$index = 0;
$this->bigBlockChain = array();
$bbs = self::BIG_BLOCK_SIZE / 4;
for ($i = 0; $i < $this->numBigBlockDepotBlocks; ++$i) {
$pos = ($bigBlockDepotBlocks[$i] + 1) * self::BIG_BLOCK_SIZE;
for ($j = 0 ; $j < self::BIG_BLOCK_SIZE / 4; ++$j) {
$this->bigBlockChain[$index] = $this->_GetInt4d($this->data, $pos);
for ($j = 0 ; $j < $bbs; ++$j) {
$this->bigBlockChain[$index] = self::_GetInt4d($this->data, $pos);
$pos += 4 ;
++$index;
}
@ -146,8 +147,8 @@ class PHPExcel_Shared_OLERead {
while ($sbdBlock != -2) {
$pos = ($sbdBlock + 1) * self::BIG_BLOCK_SIZE;
for ($j = 0; $j < self::BIG_BLOCK_SIZE / 4; ++$j) {
$this->smallBlockChain[$index] = $this->_GetInt4d($this->data, $pos);
for ($j = 0; $j < $bbs; ++$j) {
$this->smallBlockChain[$index] = self::_GetInt4d($this->data, $pos);
$pos += 4;
++$index;
}
@ -187,7 +188,6 @@ class PHPExcel_Shared_OLERead {
return $streamData;
} else {
$numBlocks = $this->props[$this->wrkbook]['size'] / self::BIG_BLOCK_SIZE;
if ($this->props[$this->wrkbook]['size'] % self::BIG_BLOCK_SIZE != 0) {
@ -196,7 +196,6 @@ class PHPExcel_Shared_OLERead {
if ($numBlocks == 0) return '';
$streamData = '';
$block = $this->props[$this->wrkbook]['startBlock'];
@ -239,7 +238,6 @@ class PHPExcel_Shared_OLERead {
return $streamData;
} else {
$numBlocks = $this->props[$this->summaryInformation]['size'] / self::BIG_BLOCK_SIZE;
if ($this->props[$this->summaryInformation]['size'] % self::BIG_BLOCK_SIZE != 0) {
@ -248,7 +246,6 @@ class PHPExcel_Shared_OLERead {
if ($numBlocks == 0) return '';
$streamData = '';
$block = $this->props[$this->summaryInformation]['startBlock'];
@ -291,7 +288,6 @@ class PHPExcel_Shared_OLERead {
return $streamData;
} else {
$numBlocks = $this->props[$this->documentSummaryInformation]['size'] / self::BIG_BLOCK_SIZE;
if ($this->props[$this->documentSummaryInformation]['size'] % self::BIG_BLOCK_SIZE != 0) {
@ -300,7 +296,6 @@ class PHPExcel_Shared_OLERead {
if ($numBlocks == 0) return '';
$streamData = '';
$block = $this->props[$this->documentSummaryInformation]['startBlock'];
@ -330,7 +325,7 @@ class PHPExcel_Shared_OLERead {
while ($block != -2) {
$pos = ($block + 1) * self::BIG_BLOCK_SIZE;
$data = $data . substr($this->data, $pos, self::BIG_BLOCK_SIZE);
$data .= substr($this->data, $pos, self::BIG_BLOCK_SIZE);
$block = $this->bigBlockChain[$block];
}
return $data;
@ -356,16 +351,11 @@ class PHPExcel_Shared_OLERead {
// sectorID of first sector or short sector, if this entry refers to a stream (the case with workbook)
// sectorID of first sector of the short-stream container stream, if this entry is root entry
$startBlock = $this->_GetInt4d($d, self::START_BLOCK_POS);
$startBlock = self::_GetInt4d($d, self::START_BLOCK_POS);
$size = $this->_GetInt4d($d, self::SIZE_POS);
$size = self::_GetInt4d($d, self::SIZE_POS);
$name = '';
for ($i = 0; $i < $nameSize ; ++$i) {
$name .= $d[$i];
}
$name = str_replace("\x00", "", $name);
$name = str_replace("\x00", "", substr($d,0,$nameSize));
$this->props[] = array (
'name' => $name,
@ -407,14 +397,19 @@ class PHPExcel_Shared_OLERead {
* @param int $pos
* @return int
*/
private function _GetInt4d($data, $pos)
private static function _GetInt4d($data, $pos)
{
// FIX: represent numbers correctly on 64-bit system
// http://sourceforge.net/tracker/index.php?func=detail&aid=1487372&group_id=99160&atid=623334
// Hacked by Andreas Rehm 2006 to ensure correct result of the <<24 block on 32 and 64bit systems
$_or_24 = ord($data[$pos+3]);
if ($_or_24>=128) $_ord_24 = -abs((256-$_or_24) << 24);
else $_ord_24 = ($_or_24&127) << 24;
return ord($data[$pos]) | (ord($data[$pos+1]) << 8) | (ord($data[$pos+2]) << 16) | $_ord_24;
$_or_24 = ord($data[$pos + 3]);
if ($_or_24 >= 128) {
// negative number
$_ord_24 = -abs((256 - $_or_24) << 24);
} else {
$_ord_24 = ($_or_24 & 127) << 24;
}
return ord($data[$pos]) | (ord($data[$pos + 1]) << 8) | (ord($data[$pos + 2]) << 16) | $_ord_24;
}
}

View File

@ -58,6 +58,7 @@ Fixed in SVN:
- Bugfix: (MBaker) Work item 14679 - Formula evaluation fails with Japanese sheet refs
- Bugfix: (MBaker) Work item 13559 - PHPExcel_Writer_PDF does not handle cell borders correctly
- Bugfix: (MBaker) Work item 14831 - Style : applyFromArray() for 'allborders' not working
- Bugfix: (MBaker) Work item 14837 - Using $this when not in object context in Excel5 Reader
- General: (MBaker) Applied patch 6609 - Removes a unnecessary loop through each cell when applying conditional formatting to a range.
- General: (MBaker) Applied patch 7169 - Removed spurious PHP end tags (?>)
- General: (MBaker) Improved performance (speed) and reduced memory overheads, particularly for the Writers, but across the whole library.