PHPExcel_Shared
[ class tree: PHPExcel_Shared ] [ index: PHPExcel_Shared ] [ all elements ]

Source for file OLERead.php

Documentation is available at OLERead.php

  1. <?php
  2. /**
  3.  * PHPExcel
  4.  *
  5.  * Copyright (c) 2006 - 2009 PHPExcel
  6.  *
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  *
  12.  * This library is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with this library; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  20.  *
  21.  * @category   PHPExcel
  22.  * @package    PHPExcel_Shared
  23.  * @copyright  Copyright (c) 2006 - 2009 PHPExcel (http://www.codeplex.com/PHPExcel)
  24.  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  25.  * @version    1.6.5, 2009-01-05
  26.  */
  27.  
  28. define('IDENTIFIER_OLE'pack("CCCCCCCC"0xd0,0xcf,0x11,0xe0,0xa1,0xb1,0x1a,0xe1));
  29. define('IDENTIFIER_BIFF7'pack("CCCCCCCC"0x09,0x08,0x08,0x00,0x00,0x05,0x05,0x00));
  30. define('IDENTIFIER_BIFF8'pack("CCCCCCCC"0x09,0x08,0x10,0x00,0x00,0x06,0x05,0x00));
  31. // OpenOffice and Excel 97-2004 for Mac.
  32. define('IDENTIFIER_OOF'pack("CCCCCCCC"0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xff));
  33. define('IDENTIFIER_MAC04'pack("CCCCCCCC"0xfd,0xff,0xff,0xff,0x23,0x00,0x00,0x00));
  34.  
  35.  
  36.     public $data = '';
  37.  
  38.     const NUM_BIG_BLOCK_DEPOT_BLOCKS_POS 0x2c;
  39.     const SMALL_BLOCK_DEPOT_BLOCK_POS 0x3c;
  40.     const ROOT_START_BLOCK_POS 0x30;
  41.     const BIG_BLOCK_SIZE 0x200;
  42.     const SMALL_BLOCK_SIZE 0x40;
  43.     const EXTENSION_BLOCK_POS 0x44;
  44.     const NUM_EXTENSION_BLOCK_POS 0x48;
  45.     const PROPERTY_STORAGE_BLOCK_SIZE 0x80;
  46.     const BIG_BLOCK_DEPOT_BLOCKS_POS 0x4c;
  47.     const SMALL_BLOCK_THRESHOLD 0x1000;
  48.     // property storage offsets
  49.     const SIZE_OF_NAME_POS 0x40;
  50.     const TYPE_POS 0x42;
  51.     const START_BLOCK_POS 0x74;
  52.     const SIZE_POS 0x78;
  53.     const IDENTIFIER_OLE IDENTIFIER_OLE;
  54.     const IDENTIFIER_BIFF7 IDENTIFIER_BIFF7;
  55.     const IDENTIFIER_BIFF8 IDENTIFIER_BIFF8;
  56.     // OpenOffice and Excel 97-2004 for Mac.
  57.     const IDENTIFIER_OOF IDENTIFIER_OOF;
  58.     const IDENTIFIER_MAC04 IDENTIFIER_MAC04;
  59.  
  60.     public function read($sFileName)
  61.     {
  62.         // check if file exist and is readable (Darko Miljanovic)
  63.         if(!is_readable($sFileName)) {
  64.             $this->error 1;
  65.             return false;
  66.         }
  67.  
  68.         $this->data = file_get_contents($sFileName);
  69.         if (!$this->data{
  70.             $this->error 1;
  71.             return false;
  72.         }
  73.  
  74.         if (substr($this->data08!= self::IDENTIFIER_OLE{
  75.             $this->error 1;
  76.             return false;
  77.         }
  78.  
  79.         // Check the start of the first block for a signature found in valid
  80.         // Excel files
  81.  
  82.         // Incorrectly throws out some valid Excel files. Removing for now.
  83.         /*$identifiers = array(
  84.             IDENTIFIER_BIFF7,
  85.             IDENTIFIER_BIFF8,
  86.             IDENTIFIER_OOF,
  87.             IDENTIFIER_MAC04
  88.         );
  89.  
  90.         if (!in_array(substr($this->data, 512, 8), $identifiers)) {
  91.             $this->error = 2;
  92.             return false;
  93.         }*/
  94.  
  95.         $this->numBigBlockDepotBlocks $this->_GetInt4d($this->dataself::NUM_BIG_BLOCK_DEPOT_BLOCKS_POS);
  96.         $this->sbdStartBlock $this->_GetInt4d($this->dataself::SMALL_BLOCK_DEPOT_BLOCK_POS);
  97.         $this->rootStartBlock $this->_GetInt4d($this->dataself::ROOT_START_BLOCK_POS);
  98.         $this->extensionBlock $this->_GetInt4d($this->dataself::EXTENSION_BLOCK_POS);
  99.         $this->numExtensionBlocks $this->_GetInt4d($this->dataself::NUM_EXTENSION_BLOCK_POS);
  100.  
  101.         $bigBlockDepotBlocks array();
  102.         $pos self::BIG_BLOCK_DEPOT_BLOCKS_POS;
  103.  
  104.         $bbdBlocks $this->numBigBlockDepotBlocks;
  105.  
  106.         if ($this->numExtensionBlocks != 0{
  107.             $bbdBlocks (self::BIG_BLOCK_SIZE self::BIG_BLOCK_DEPOT_BLOCKS_POS)/4;
  108.         }
  109.  
  110.         for ($i 0$i $bbdBlocks++$i{
  111.               $bigBlockDepotBlocks[$i$this->_GetInt4d($this->data$pos);
  112.               $pos += 4;
  113.         }
  114.  
  115.         for ($j 0$j $this->numExtensionBlocks++$j{
  116.             $pos ($this->extensionBlock 1self::BIG_BLOCK_SIZE;
  117.             $blocksToRead min($this->numBigBlockDepotBlocks $bbdBlocksself::BIG_BLOCK_SIZE 1);
  118.  
  119.             for ($i $bbdBlocks$i $bbdBlocks $blocksToRead++$i{
  120.                 $bigBlockDepotBlocks[$i$this->_GetInt4d($this->data$pos);
  121.                 $pos += 4;
  122.             }
  123.  
  124.             $bbdBlocks += $blocksToRead;
  125.             if ($bbdBlocks $this->numBigBlockDepotBlocks{
  126.                 $this->extensionBlock $this->_GetInt4d($this->data$pos);
  127.             }
  128.         }
  129.  
  130.         $pos 0;
  131.         $index 0;
  132.         $this->bigBlockChain array();
  133.  
  134.         for ($i 0$i $this->numBigBlockDepotBlocks++$i{
  135.             $pos ($bigBlockDepotBlocks[$i1self::BIG_BLOCK_SIZE;
  136.  
  137.             for ($j $j self::BIG_BLOCK_SIZE 4++$j{
  138.                 $this->bigBlockChain[$index$this->_GetInt4d($this->data$pos);
  139.                 $pos += ;
  140.                 ++$index;
  141.             }
  142.         }
  143.  
  144.         $pos 0;
  145.         $index 0;
  146.         $sbdBlock $this->sbdStartBlock;
  147.         $this->smallBlockChain array();
  148.  
  149.         while ($sbdBlock != -2{
  150.             $pos ($sbdBlock 1self::BIG_BLOCK_SIZE;
  151.  
  152.             for ($j 0$j self::BIG_BLOCK_SIZE 4++$j{
  153.                 $this->smallBlockChain[$index$this->_GetInt4d($this->data$pos);
  154.                 $pos += 4;
  155.                 ++$index;
  156.             }
  157.  
  158.             $sbdBlock $this->bigBlockChain[$sbdBlock];
  159.         }
  160.  
  161.         $block $this->rootStartBlock;
  162.         $pos 0;
  163.         $this->entry $this->_readData($block);
  164.  
  165.         $this->_readPropertySets();
  166.  
  167.     }
  168.  
  169.     public function getWorkBook()
  170.     {
  171.         if ($this->props[$this->wrkbook]['size'self::SMALL_BLOCK_THRESHOLD){
  172.             $rootdata $this->_readData($this->props[$this->rootentry]['startBlock']);
  173.  
  174.             $streamData '';
  175.             $block $this->props[$this->wrkbook]['startBlock'];
  176.  
  177.             $pos 0;
  178.             while ($block != -2{
  179.                   $pos $block self::SMALL_BLOCK_SIZE;
  180.                 $streamData .= substr($rootdata$posself::SMALL_BLOCK_SIZE);
  181.  
  182.                 $block $this->smallBlockChain[$block];
  183.             }
  184.  
  185.             return $streamData;
  186.  
  187.  
  188.         else {
  189.             $numBlocks $this->props[$this->wrkbook]['size'self::BIG_BLOCK_SIZE;
  190.             if ($this->props[$this->wrkbook]['size'self::BIG_BLOCK_SIZE != 0{
  191.                 ++$numBlocks;
  192.             }
  193.  
  194.             if ($numBlocks == 0return '';
  195.  
  196.  
  197.             $streamData '';
  198.             $block $this->props[$this->wrkbook]['startBlock'];
  199.  
  200.             $pos 0;
  201.  
  202.             while ($block != -2{
  203.                 $pos ($block 1self::BIG_BLOCK_SIZE;
  204.                 $streamData .= substr($this->data$posself::BIG_BLOCK_SIZE);
  205.                 $block $this->bigBlockChain[$block];
  206.             }
  207.  
  208.             return $streamData;
  209.         }
  210.     }
  211.  
  212.     public function _GetInt4d($data$pos)
  213.     {
  214.         // Hacked by Andreas Rehm 2006 to ensure correct result of the <<24 block on 32 and 64bit systems
  215.         $_or_24 ord($data[$pos+3]);
  216.         if ($_or_24>=128$_ord_24 = -abs((256-$_or_24<< 24);
  217.         else $_ord_24 ($_or_24&127<< 24;
  218.  
  219.         return ord($data[$pos](ord($data[$pos+1]<< 8(ord($data[$pos+2]<< 16$_ord_24;
  220.     }
  221.  
  222.      public function _readData($bl)
  223.      {
  224.         $block $bl;
  225.         $pos 0;
  226.         $data '';
  227.  
  228.         while ($block != -2)  {
  229.             $pos ($block 1self::BIG_BLOCK_SIZE;
  230.             $data $data.substr($this->data$posself::BIG_BLOCK_SIZE);
  231.             $block $this->bigBlockChain[$block];
  232.         }
  233.         return $data;
  234.      }
  235.  
  236.     public function _readPropertySets()
  237.     {
  238.         $offset 0;
  239.  
  240.         while ($offset strlen($this->entry)) {
  241.             $d substr($this->entry$offsetself::PROPERTY_STORAGE_BLOCK_SIZE);
  242.  
  243.             $nameSize ord($d[self::SIZE_OF_NAME_POS](ord($d[self::SIZE_OF_NAME_POS+1]<< 8);
  244.  
  245.             $type ord($d[self::TYPE_POS]);
  246.  
  247.             $startBlock $this->_GetInt4d($dself::START_BLOCK_POS);
  248.             $size $this->_GetInt4d($dself::SIZE_POS);
  249.  
  250.             $name '';
  251.             for ($i 0$i $nameSize ++$i{
  252.                 $name .= $d[$i];
  253.             }
  254.  
  255.             $name str_replace("\x00"""$name);
  256.  
  257.             $this->props[array (
  258.                 'name' => $name,
  259.                 'type' => $type,
  260.                 'startBlock' => $startBlock,
  261.                 'size' => $size);
  262.  
  263.             if (($name == "Workbook"|| ($name == "Book"|| ($name == "WORKBOOK")) {
  264.                 $this->wrkbook count($this->props1;
  265.             }
  266.  
  267.             if ($name == "Root Entry" || $name == "ROOT ENTRY"{
  268.                 $this->rootentry count($this->props1;
  269.             }
  270.  
  271.             $offset += self::PROPERTY_STORAGE_BLOCK_SIZE;
  272.         }
  273.  
  274.     }
  275. }

Documentation generated on Mon, 05 Jan 2009 20:38:11 +0100 by phpDocumentor 1.4.1