Source for file oleread.inc

Documentation is available at oleread.inc

  1. <?php
  2. define('NUM_BIG_BLOCK_DEPOT_BLOCKS_POS', 0x2c);
  3. define('SMALL_BLOCK_DEPOT_BLOCK_POS', 0x3c);
  4. define('ROOT_START_BLOCK_POS', 0x30);
  5. define('BIG_BLOCK_SIZE', 0x200);
  6. define('SMALL_BLOCK_SIZE', 0x40);
  7. define('EXTENSION_BLOCK_POS', 0x44);
  8. define('NUM_EXTENSION_BLOCK_POS', 0x48);
  9. define('PROPERTY_STORAGE_BLOCK_SIZE', 0x80);
  10. define('BIG_BLOCK_DEPOT_BLOCKS_POS', 0x4c);
  11. define('SMALL_BLOCK_THRESHOLD', 0x1000);
  12. // property storage offsets
  13. define('SIZE_OF_NAME_POS', 0x40);
  14. define('TYPE_POS', 0x42);
  15. define('START_BLOCK_POS', 0x74);
  16. define('SIZE_POS', 0x78);
  17.  
  18.  
  19.  
  20. //echo 'ROOT_START_BLOCK_POS = '.ROOT_START_BLOCK_POS."\n";
  21.  
  22. //echo bin2hex($data[ROOT_START_BLOCK_POS])."\n";
  23. //echo "a=";
  24. //echo $data[ROOT_START_BLOCK_POS];
  25. //function log
  26.  
  27. function GetInt4d($data, $pos) {
  28.         return ord($data[$pos]) | (ord($data[$pos+1]) << 8) | (ord($data[$pos+2]) << 16) | (ord($data[$pos+3]) << 24); 
  29. }
  30.  
  31.  
  32. class OLERead {
  33.     var $data = '';
  34.     
  35.     
  36.     function OLERead(){
  37.         
  38.         
  39.     }
  40.     
  41.     function read($sFileName){
  42.         
  43.         // check if file exist and is readable (Darko Miljanovic)
  44.         if(!is_readable($sFileName)) {
  45.             $this->error = 1;
  46.             return false;
  47.         }
  48.         
  49.         $this->data = @file_get_contents($sFileName);
  50.         if (!$this->data) { 
  51.             $this->error = 1; 
  52.             return false; 
  53.            }
  54.            
  55.         $this->numBigBlockDepotBlocks = GetInt4d($this->data, NUM_BIG_BLOCK_DEPOT_BLOCKS_POS);
  56.         $this->sbdStartBlock = GetInt4d($this->data, SMALL_BLOCK_DEPOT_BLOCK_POS);
  57.         $this->rootStartBlock = GetInt4d($this->data, ROOT_START_BLOCK_POS);
  58.         $this->extensionBlock = GetInt4d($this->data, EXTENSION_BLOCK_POS);
  59.         $this->numExtensionBlocks = GetInt4d($this->data, NUM_EXTENSION_BLOCK_POS);
  60.         
  61.     /*
  62.         echo $this->numBigBlockDepotBlocks." ";
  63.         echo $this->sbdStartBlock." ";
  64.         echo $this->rootStartBlock." ";
  65.         echo $this->extensionBlock." ";
  66.         echo $this->numExtensionBlocks." ";
  67.         */
  68.         //echo "sbdStartBlock = $this->sbdStartBlock\n";
  69.         $bigBlockDepotBlocks = array();
  70.         $pos = BIG_BLOCK_DEPOT_BLOCKS_POS;
  71.         //echo "pos = $pos";
  72.     $bbdBlocks = $this->numBigBlockDepotBlocks;
  73.         
  74.             if ($this->numExtensionBlocks != 0) {
  75.                 $bbdBlocks = (BIG_BLOCK_SIZE - BIG_BLOCK_DEPOT_BLOCKS_POS)/4; 
  76.             }
  77.         
  78.         for ($i = 0; $i < $bbdBlocks; $i++) {
  79.               $bigBlockDepotBlocks[$i] = GetInt4d($this->data, $pos);
  80.               $pos += 4;
  81.         }
  82.         
  83.         
  84.         for ($j = 0; $j < $this->numExtensionBlocks; $j++) {
  85.             $pos = ($this->extensionBlock + 1) * BIG_BLOCK_SIZE;
  86.             $blocksToRead = min($this->numBigBlockDepotBlocks - $bbdBlocks, BIG_BLOCK_SIZE / 4 - 1);
  87.  
  88.             for ($i = $bbdBlocks; $i < $bbdBlocks + $blocksToRead; $i++) {
  89.                 $bigBlockDepotBlocks[$i] = GetInt4d($this->data, $pos);
  90.                 $pos += 4;
  91.             }   
  92.  
  93.             $bbdBlocks += $blocksToRead;
  94.             if ($bbdBlocks < $this->numBigBlockDepotBlocks) {
  95.                 $this->extensionBlock = GetInt4d($this->data, $pos);
  96.             }
  97.         }
  98.  
  99.        // var_dump($bigBlockDepotBlocks);
  100.         
  101.         // readBigBlockDepot
  102.         $pos = 0;
  103.         $index = 0;
  104.         $this->bigBlockChain = array();
  105.         
  106.         for ($i = 0; $i < $this->numBigBlockDepotBlocks; $i++) {
  107.             $pos = ($bigBlockDepotBlocks[$i] + 1) * BIG_BLOCK_SIZE;
  108.             //echo "pos = $pos";    
  109.             for ($j = 0 ; $j < BIG_BLOCK_SIZE / 4; $j++) {
  110.                 $this->bigBlockChain[$index] = GetInt4d($this->data, $pos);
  111.                 $pos += 4 ;
  112.                 $index++;
  113.             }
  114.         }
  115.  
  116.     //var_dump($this->bigBlockChain);
  117.         //echo '=====2';
  118.         // readSmallBlockDepot();
  119.         $pos = 0;
  120.         $index = 0;
  121.         $sbdBlock = $this->sbdStartBlock;
  122.         $this->smallBlockChain = array();
  123.     
  124.         while ($sbdBlock != -2) {
  125.     
  126.           $pos = ($sbdBlock + 1) * BIG_BLOCK_SIZE;
  127.     
  128.           for ($j = 0; $j < BIG_BLOCK_SIZE / 4; $j++) {
  129.             $this->smallBlockChain[$index] = GetInt4d($this->data, $pos);
  130.             $pos += 4;
  131.             $index++;
  132.           }
  133.     
  134.           $sbdBlock = $this->bigBlockChain[$sbdBlock];
  135.         }
  136.  
  137.         
  138.         // readData(rootStartBlock)
  139.         $block = $this->rootStartBlock;
  140.         $pos = 0;
  141.         $this->entry = $this->__readData($block);
  142.         
  143.         /*
  144.         while ($block != -2)  {
  145.             $pos = ($block + 1) * BIG_BLOCK_SIZE;
  146.             $this->entry = $this->entry.substr($this->data, $pos, BIG_BLOCK_SIZE);
  147.             $block = $this->bigBlockChain[$block];
  148.         }
  149.         */
  150.         //echo '==='.$this->entry."===";
  151.         $this->__readPropertySets();
  152.  
  153.     }
  154.     
  155.      function __readData($bl) {
  156.         $block = $bl;
  157.         $pos = 0;
  158.         $data = '';
  159.         
  160.         while ($block != -2)  {
  161.             $pos = ($block + 1) * BIG_BLOCK_SIZE;
  162.             $data = $data.substr($this->data, $pos, BIG_BLOCK_SIZE);
  163.             //echo "pos = $pos data=$data\n";    
  164.         $block = $this->bigBlockChain[$block];
  165.         }
  166.         return $data;
  167.      }
  168.         
  169.     function __readPropertySets(){
  170.         $offset = 0;
  171.         //var_dump($this->entry);
  172.         while ($offset < strlen($this->entry)) {
  173.               $d = substr($this->entry, $offset, PROPERTY_STORAGE_BLOCK_SIZE);
  174.             
  175.               $nameSize = ord($d[SIZE_OF_NAME_POS]) | (ord($d[SIZE_OF_NAME_POS+1]) << 8);
  176.               
  177.               $type = ord($d[TYPE_POS]);
  178.               //$maxBlock = strlen($d) / BIG_BLOCK_SIZE - 1;
  179.         
  180.               $startBlock = GetInt4d($d, START_BLOCK_POS);
  181.               $size = GetInt4d($d, SIZE_POS);
  182.         
  183.             $name = '';
  184.             for ($i = 0; $i < $nameSize ; $i++) {
  185.               $name .= $d[$i];
  186.             }
  187.             
  188.             $name = str_replace("\x00", "", $name);
  189.             
  190.             $this->props[] = array (
  191.                 'name' => $name, 
  192.                 'type' => $type,
  193.                 'startBlock' => $startBlock,
  194.                 'size' => $size);
  195.  
  196.             if (($name == "Workbook") || ($name == "Book")) {
  197.                 $this->wrkbook = count($this->props) - 1;
  198.             }
  199.  
  200.             if ($name == "Root Entry") {
  201.                 $this->rootentry = count($this->props) - 1;
  202.             }
  203.             
  204.             //echo "name ==$name=\n";
  205.  
  206.             
  207.             $offset += PROPERTY_STORAGE_BLOCK_SIZE;
  208.         }   
  209.         
  210.     }
  211.     
  212.     
  213.     function getWorkBook(){
  214.         if ($this->props[$this->wrkbook]['size'] < SMALL_BLOCK_THRESHOLD){
  215. //          getSmallBlockStream(PropertyStorage ps)
  216.  
  217.             $rootdata = $this->__readData($this->props[$this->rootentry]['startBlock']);
  218.             
  219.             $streamData = '';
  220.             $block = $this->props[$this->wrkbook]['startBlock'];
  221.             //$count = 0;
  222.             $pos = 0;
  223.             while ($block != -2) {
  224.                     $pos = $block * SMALL_BLOCK_SIZE;
  225.                   $streamData .= substr($rootdata, $pos, SMALL_BLOCK_SIZE);
  226.  
  227.                   $block = $this->smallBlockChain[$block];
  228.             }
  229.             
  230.             return $streamData;
  231.             
  232.  
  233.         }else{
  234.         
  235.             $numBlocks = $this->props[$this->wrkbook]['size'] / BIG_BLOCK_SIZE;
  236.             if ($this->props[$this->wrkbook]['size'] % BIG_BLOCK_SIZE != 0) {
  237.                 $numBlocks++;
  238.             }
  239.             
  240.             if ($numBlocks == 0) return '';
  241.             
  242.             //echo "numBlocks = $numBlocks\n";
  243.         //byte[] streamData = new byte[numBlocks * BIG_BLOCK_SIZE];
  244.             //print_r($this->wrkbook);
  245.             $streamData = '';
  246.             $block = $this->props[$this->wrkbook]['startBlock'];
  247.             //$count = 0;
  248.             $pos = 0;
  249.             //echo "block = $block";
  250.             while ($block != -2) {
  251.               $pos = ($block + 1) * BIG_BLOCK_SIZE;
  252.               $streamData .= substr($this->data, $pos, BIG_BLOCK_SIZE);
  253.               $block = $this->bigBlockChain[$block];
  254.             }   
  255.             //echo 'stream'.$streamData;
  256.             return $streamData;
  257.         }
  258.     }
  259.     
  260. }
  261. ?>

Documentation generated on Thu, 08 Jan 2009 17:47:35 +0100 by phpDocumentor 1.4.0a2