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

Source for file Root.php

Documentation is available at Root.php

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2002 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.02 of the PHP license,      |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Author: Xavier Noguer <xnoguer@php.net>                              |
  17. // | Based on OLE::Storage_Lite by Kawai, Takanori                        |
  18. // +----------------------------------------------------------------------+
  19. //
  20. // $Id: Root.php 322720 2012-01-25 12:56:57Z clockwerx $
  21.  
  22.  
  23. require_once 'OLE/PPS.php';
  24. require_once 'System.php';
  25.  
  26. /**
  27. * Class for creating Root PPS's for OLE containers
  28. *
  29. @author   Xavier Noguer <xnoguer@php.net>
  30. @category Structures
  31. @package  OLE
  32. */
  33. class OLE_PPS_Root extends OLE_PPS
  34. {
  35.     /**
  36.     * Flag to enable new logic
  37.     * @var bool 
  38.     */
  39.     var $new_func = true;
  40.  
  41.     /**
  42.     * The temporary dir for storing the OLE file
  43.     * @var string 
  44.     */
  45.     var $_tmp_dir;
  46.     
  47.     /**
  48.     * Constructor
  49.     *
  50.     * @access public
  51.     * @param integer $time_1st A timestamp
  52.     * @param integer $time_2nd A timestamp
  53.     */
  54.     function OLE_PPS_Root($time_1st$time_2nd$raChild)
  55.     {
  56.         $this->_tmp_dir = System::tmpdir();
  57.         $this->OLE_PPS(
  58.            null
  59.            OLE::Asc2Ucs('Root Entry'),
  60.            OLE_PPS_TYPE_ROOT,
  61.            null,
  62.            null,
  63.            null,
  64.            $time_1st,
  65.            $time_2nd,
  66.            null,
  67.            $raChild);
  68.     }
  69.  
  70.     /**
  71.     * Sets the temp dir used for storing the OLE file
  72.     *
  73.     * @access public
  74.     * @param string $dir The dir to be used as temp dir
  75.     * @return true if given dir is valid, false otherwise
  76.     */
  77.     function setTempDir($dir)
  78.     {
  79.         if (is_dir($dir)) {
  80.             $this->_tmp_dir $dir;
  81.             return true;
  82.         }
  83.         return false;
  84.     }
  85.  
  86.     /**
  87.     * Method for saving the whole OLE container (including files).
  88.     * In fact, if called with an empty argument (or '-'), it saves to a
  89.     * temporary file and then outputs it's contents to stdout.
  90.     *
  91.     * @param string $filename The name of the file where to save the OLE container
  92.     * @access public
  93.     * @return mixed true on success, PEAR_Error on failure
  94.     */
  95.     function save($filename)
  96.     {
  97.         // Initial Setting for saving
  98.         $this->_BIG_BLOCK_SIZE  pow(2,
  99.                       ((isset($this->_BIG_BLOCK_SIZE))$this->_adjust2($this->_BIG_BLOCK_SIZE)  : 9));
  100.         $this->_SMALL_BLOCK_SIZEpow(2
  101.                       ((isset($this->_SMALL_BLOCK_SIZE))?  $this->_adjust2($this->_SMALL_BLOCK_SIZE): 6));
  102.  
  103.         // Open temp file if we are sending output to stdout
  104.         if (($filename == '-'|| ($filename == '')) {
  105.             $this->_tmp_filename tempnam($this->_tmp_dir"OLE_PPS_Root");
  106.             $this->_FILEH_ @fopen($this->_tmp_filename,"w+b");
  107.             if ($this->_FILEH_ == false{
  108.                 return $this->raiseError("Can't create temporary file.");
  109.             }
  110.         else {
  111.             $this->_FILEH_ @fopen($filename"wb");
  112.             if ($this->_FILEH_ == false{
  113.                 return $this->raiseError("Can't open $filename. It may be in use or protected.");
  114.             }
  115.         }
  116.         // Make an array of PPS's (for Save)
  117.         $aList = array();
  118.         OLE_PPS_Root::_savePpsSetPnt($aListarray($this));
  119.         // calculate values for header
  120.         list($iSBDcnt$iBBcnt$iPPScnt$this->_calcSize($aList)//, $rhInfo);
  121.         // Save Header
  122.         $this->_saveHeader($iSBDcnt$iBBcnt$iPPScnt);
  123.   
  124.         // Make Small Data string (write SBD)
  125.         $this->_data $this->_makeSmallData($aList);
  126.   
  127.         // Write BB
  128.         $this->_saveBigData($iSBDcnt$aList);
  129.         // Write PPS
  130.         $this->_savePps($aList);
  131.         // Write Big Block Depot and BDList and Adding Header informations
  132.         $this->_saveBbd($iSBDcnt$iBBcnt$iPPScnt);
  133.         // Close File, send it to stdout if necessary
  134.         if (($filename == '-'|| ($filename == '')) {
  135.             fseek($this->_FILEH_0);
  136.             fpassthru($this->_FILEH_);
  137.             @fclose($this->_FILEH_);
  138.             // Delete the temporary file.
  139.             @unlink($this->_tmp_filename);
  140.         else {
  141.             @fclose($this->_FILEH_);
  142.         }
  143.  
  144.         return true;
  145.     }
  146.  
  147.     /**
  148.     * Calculate some numbers
  149.     *
  150.     * @access private
  151.     * @param array $raList Reference to an array of PPS's
  152.     * @return array The array of numbers
  153.     */
  154.     function _calcSize(&$raList
  155.     {
  156.         // Calculate Basic Setting
  157.         list($iSBDcnt$iBBcnt$iPPScnt= array(0,0,0);
  158.         $iSmallLen = 0;
  159.         $iSBcnt = 0;
  160.         for ($i = 0; $i count($raList)$i++{
  161.             if ($raList[$i]->Type == OLE_PPS_TYPE_FILE{
  162.                 $raList[$i]->Size = $raList[$i]->_DataLen();
  163.                 if ($raList[$i]->Size < OLE_DATA_SIZE_SMALL{
  164.                     $iSBcnt += floor($raList[$i]->Size / $this->_SMALL_BLOCK_SIZE)
  165.                                   + (($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)? 1: 0);
  166.                 else {
  167.                     $iBBcnt += (floor($raList[$i]->Size / $this->_BIG_BLOCK_SIZE+
  168.                         (($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)? 1: 0));
  169.                 }
  170.             }
  171.         }
  172.         $iSmallLen $iSBcnt $this->_SMALL_BLOCK_SIZE;
  173.         $iSlCnt floor($this->_BIG_BLOCK_SIZE OLE_LONG_INT_SIZE);
  174.         $iSBDcnt floor($iSBcnt $iSlCnt(($iSBcnt $iSlCnt)? 1:0);
  175.         $iBBcnt +=  (floor($iSmallLen $this->_BIG_BLOCK_SIZE+
  176.                       (( $iSmallLen $this->_BIG_BLOCK_SIZE)? 1: 0));
  177.         $iCnt count($raList);
  178.         $iBdCnt $this->_BIG_BLOCK_SIZE OLE_PPS_SIZE;
  179.         $iPPScnt (floor($iCnt/$iBdCnt(($iCnt $iBdCnt)? 1: 0));
  180.    
  181.         return array($iSBDcnt$iBBcnt$iPPScnt);
  182.     }
  183.  
  184.     /**
  185.     * Helper function for caculating a magic value for block sizes
  186.     *
  187.     * @access private
  188.     * @param integer $i2 The argument
  189.     * @see save()
  190.     * @return integer 
  191.     */
  192.     function _adjust2($i2)
  193.     {
  194.         $iWk log($i2)/log(2);
  195.         return ($iWk floor($iWk))floor($iWk)+1:$iWk;
  196.     }
  197.  
  198.     /**
  199.     * Save OLE header
  200.     *
  201.     * @access private
  202.     * @param integer $iSBDcnt 
  203.     * @param integer $iBBcnt 
  204.     * @param integer $iPPScnt 
  205.     */
  206.     function _saveHeader($iSBDcnt$iBBcnt$iPPScnt)
  207.     {
  208.         $FILE $this->_FILEH_;
  209.   
  210.         if($this->new_func)
  211.           return $this->_create_header($iSBDcnt$iBBcnt$iPPScnt);
  212.  
  213.         // Calculate Basic Setting
  214.         $iBlCnt $this->_BIG_BLOCK_SIZE OLE_LONG_INT_SIZE;
  215.         $i1stBdL ($this->_BIG_BLOCK_SIZE - 0x4COLE_LONG_INT_SIZE;
  216.   
  217.         $iBdExL = 0;
  218.         $iAll $iBBcnt $iPPScnt $iSBDcnt;
  219.         $iAllW $iAll;
  220.         $iBdCntW floor($iAllW $iBlCnt(($iAllW $iBlCnt)? 1: 0);
  221.         $iBdCnt floor(($iAll $iBdCntW$iBlCnt((($iAllW+$iBdCntW$iBlCnt)? 1: 0);
  222.   
  223.         // Calculate BD count
  224.         if ($iBdCnt $i1stBdL{
  225.             while (1{
  226.                 $iBdExL++;
  227.                 $iAllW++;
  228.                 $iBdCntW floor($iAllW $iBlCnt(($iAllW $iBlCnt)? 1: 0);
  229.                 $iBdCnt floor(($iAllW $iBdCntW$iBlCnt((($iAllW+$iBdCntW$iBlCnt)? 1: 0);
  230.                 if ($iBdCnt <= ($iBdExL*$iBlCnt$i1stBdL)) {
  231.                     break;
  232.                 }
  233.             }
  234.         }
  235.   
  236.         // Save Header
  237.         fwrite($FILE,
  238.                   "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1"
  239.                   . "\x00\x00\x00\x00"
  240.                   . "\x00\x00\x00\x00"
  241.                   . "\x00\x00\x00\x00"
  242.                   . "\x00\x00\x00\x00"
  243.                   . pack("v"0x3b)
  244.                   . pack("v"0x03)
  245.                   . pack("v"-2)
  246.                   . pack("v"9)
  247.                   . pack("v"6)
  248.                   . pack("v"0)
  249.                   . "\x00\x00\x00\x00"
  250.                   . "\x00\x00\x00\x00"
  251.                   . pack("V"$iBdCnt
  252.                   . pack("V"$iBBcnt+$iSBDcnt//ROOT START
  253.                   . pack("V"0)
  254.                   . pack("V"0x1000)
  255.                   . pack("V"$iSBDcnt ? 0 : -2)                  //Small Block Depot
  256.                   . pack("V"$iSBDcnt)
  257.           );
  258.         // Extra BDList Start, Count
  259.         if ($iBdCnt $i1stBdL{
  260.             fwrite($FILE,
  261.                       pack("V"-2).      // Extra BDList Start
  262.                       pack("V"0)        // Extra BDList Count
  263.                   );
  264.         else {
  265.             fwrite($FILEpack("V"$iAll+$iBdCntpack("V"$iBdExL));
  266.         }
  267.  
  268.         // BDList
  269.         for ($i = 0; $i $i1stBdL && $i $iBdCnt$i++{
  270.             fwrite($FILEpack("V"$iAll+$i));
  271.         }
  272.         if ($i $i1stBdL{
  273.             for ($j = 0; $j ($i1stBdL-$i)$j++{
  274.                 fwrite($FILE(pack("V"-1)));
  275.             }
  276.         }
  277.     }
  278.  
  279.     /**
  280.     * Saving big data (PPS's with data bigger than OLE_DATA_SIZE_SMALL)
  281.     *
  282.     * @access private
  283.     * @param integer $iStBlk 
  284.     * @param array &$raList Reference to array of PPS's
  285.     */
  286.     function _saveBigData($iStBlk&$raList)
  287.     {
  288.         $FILE $this->_FILEH_;
  289.    
  290.         // cycle through PPS's
  291.         for ($i = 0; $i count($raList)$i++{
  292.             if ($raList[$i]->Type != OLE_PPS_TYPE_DIR{
  293.                 $raList[$i]->Size = $raList[$i]->_DataLen();
  294.                 if (($raList[$i]->Size >= OLE_DATA_SIZE_SMALL||
  295.                     (($raList[$i]->Type == OLE_PPS_TYPE_ROOT&& isset($raList[$i]->_data)))
  296.                 {
  297.                     // Write Data
  298.                     if (isset($raList[$i]->_PPS_FILE)) {
  299.                         $iLen = 0;
  300.                         fseek($raList[$i]->_PPS_FILE0)// To The Top
  301.                         while($sBuff fread($raList[$i]->_PPS_FILE4096)) {
  302.                             $iLen += strlen($sBuff);
  303.                             fwrite($FILE$sBuff);
  304.                         }
  305.                     else {
  306.                         fwrite($FILE$raList[$i]->_data);
  307.                     }
  308.            
  309.                     if ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE{
  310.                         for ($j = 0; $j ($this->_BIG_BLOCK_SIZE ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE))$j++{
  311.                             fwrite($FILE"\x00");
  312.                         }
  313.                     }
  314.                     // Set For PPS
  315.                     $raList[$i]->_StartBlock = $iStBlk;
  316.                     $iStBlk += 
  317.                             (floor($raList[$i]->Size / $this->_BIG_BLOCK_SIZE+
  318.                                 (($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)? 1: 0));
  319.                 }
  320.                 // Close file for each PPS, and unlink it
  321.                 if (isset($raList[$i]->_PPS_FILE)) {
  322.                     @fclose($raList[$i]->_PPS_FILE);
  323.                     $raList[$i]->_PPS_FILE = null;
  324.                     @unlink($raList[$i]->_tmp_filename);
  325.                 }
  326.             }
  327.         }
  328.     }
  329.  
  330.     /**
  331.     * get small data (PPS's with data smaller than OLE_DATA_SIZE_SMALL)
  332.     *
  333.     * @access private
  334.     * @param array &$raList Reference to array of PPS's
  335.     */
  336.     function _makeSmallData(&$raList)
  337.     {
  338.         $sRes '';
  339.         $FILE $this->_FILEH_;
  340.         $iSmBlk = 0;
  341.    
  342.         for ($i = 0; $i count($raList)$i++{
  343.             // Make SBD, small data string
  344.             if ($raList[$i]->Type == OLE_PPS_TYPE_FILE{
  345.                 if ($raList[$i]->Size <= 0{
  346.                     continue;
  347.                 }
  348.                 if ($raList[$i]->Size < OLE_DATA_SIZE_SMALL{
  349.                     $iSmbCnt floor($raList[$i]->Size / $this->_SMALL_BLOCK_SIZE)
  350.                                   + (($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)? 1: 0);
  351.                     // Add to SBD
  352.                     for ($j = 0; $j ($iSmbCnt-1)$j++{
  353.                         fwrite($FILEpack("V"$j+$iSmBlk+1));
  354.                     }
  355.                     fwrite($FILEpack("V"-2));
  356.                    
  357.                     // Add to Data String(this will be written for RootEntry)
  358.                     if ($raList[$i]->_PPS_FILE{
  359.                         fseek($raList[$i]->_PPS_FILE0)// To The Top
  360.                         while ($sBuff fread($raList[$i]->_PPS_FILE4096)) {
  361.                             $sRes .= $sBuff;
  362.                         }
  363.                     else {
  364.                         $sRes .= $raList[$i]->_data;
  365.                     }
  366.                     if ($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE{
  367.                         for ($j = 0; $j ($this->_SMALL_BLOCK_SIZE ($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE))$j++{
  368.                             $sRes .= "\x00";
  369.                         }
  370.                     }
  371.                     // Set for PPS
  372.                     $raList[$i]->_StartBlock = $iSmBlk;
  373.                     $iSmBlk += $iSmbCnt;
  374.                 }
  375.             }
  376.         }
  377.         $iSbCnt floor($this->_BIG_BLOCK_SIZE OLE_LONG_INT_SIZE);
  378.         if ($iSmBlk $iSbCnt{
  379.             for ($i = 0; $i ($iSbCnt ($iSmBlk $iSbCnt))$i++{
  380.                 fwrite($FILEpack("V"-1));
  381.             }
  382.         }
  383.         return $sRes;
  384.     }
  385.  
  386.     /**
  387.     * Saves all the PPS's WKs
  388.     *
  389.     * @access private
  390.     * @param array $raList Reference to an array with all PPS's
  391.     */
  392.     function _savePps(&$raList
  393.     {
  394.         // Save each PPS WK
  395.         for ($i = 0; $i count($raList)$i++{
  396.             fwrite($this->_FILEH_$raList[$i]->_getPpsWk());
  397.         }
  398.         // Adjust for Block
  399.         $iCnt count($raList);
  400.         $iBCnt $this->_BIG_BLOCK_SIZE OLE_PPS_SIZE;
  401.         if ($iCnt $iBCnt{
  402.             for ($i = 0; $i (($iBCnt ($iCnt $iBCnt)) OLE_PPS_SIZE)$i++{
  403.                 fwrite($this->_FILEH_"\x00");
  404.             }
  405.         }
  406.     }
  407.  
  408.     /**
  409.     * Saving Big Block Depot
  410.     *
  411.     * @access private
  412.     * @param integer $iSbdSize 
  413.     * @param integer $iBsize 
  414.     * @param integer $iPpsCnt 
  415.     */
  416.     function _saveBbd($iSbdSize$iBsize$iPpsCnt
  417.     {
  418.       if($this->new_func)
  419.         return $this->_create_big_block_chain($iSbdSize$iBsize$iPpsCnt);
  420.  
  421.         $FILE $this->_FILEH_;
  422.         // Calculate Basic Setting
  423.         $iBbCnt $this->_BIG_BLOCK_SIZE OLE_LONG_INT_SIZE;
  424.         $i1stBdL ($this->_BIG_BLOCK_SIZE - 0x4COLE_LONG_INT_SIZE;
  425.       
  426.         $iBdExL = 0;
  427.         $iAll $iBsize $iPpsCnt $iSbdSize;
  428.         $iAllW $iAll;
  429.         $iBdCntW floor($iAllW $iBbCnt(($iAllW $iBbCnt)? 1: 0);
  430.         $iBdCnt floor(($iAll $iBdCntW$iBbCnt((($iAllW+$iBdCntW$iBbCnt)? 1: 0);
  431.         // Calculate BD count
  432.         if ($iBdCnt >$i1stBdL{
  433.             while (1{
  434.                 $iBdExL++;
  435.                 $iAllW++;
  436.                 $iBdCntW floor($iAllW $iBbCnt(($iAllW $iBbCnt)? 1: 0);
  437.                 $iBdCnt floor(($iAllW $iBdCntW$iBbCnt((($iAllW+$iBdCntW$iBbCnt)? 1: 0);
  438.                 if ($iBdCnt <= ($iBdExL*$iBbCnt$i1stBdL)) {
  439.                     break;
  440.                 }
  441.             }
  442.         }
  443.       
  444.         // Making BD
  445.         // Set for SBD
  446.         if ($iSbdSize > 0{
  447.             for ($i = 0; $i ($iSbdSize - 1)$i++{
  448.                 fwrite($FILEpack("V"$i+1));
  449.             }
  450.             fwrite($FILEpack("V"-2));
  451.         }
  452.         // Set for B
  453.         for ($i = 0; $i ($iBsize - 1)$i++{
  454.             fwrite($FILEpack("V"$i+$iSbdSize+1));
  455.         }
  456.         fwrite($FILEpack("V"-2));
  457.       
  458.         // Set for PPS
  459.         for ($i = 0; $i ($iPpsCnt - 1)$i++{
  460.             fwrite($FILEpack("V"$i+$iSbdSize+$iBsize+1));
  461.         }
  462.         fwrite($FILEpack("V"-2));
  463.         // Set for BBD itself ( 0xFFFFFFFD : BBD)
  464.         for ($i = 0; $i $iBdCnt$i++{
  465.             fwrite($FILEpack("V"0xFFFFFFFD));
  466.         }
  467.         // Set for ExtraBDList
  468.         for ($i = 0; $i $iBdExL$i++{
  469.             fwrite($FILEpack("V"0xFFFFFFFC));
  470.         }
  471.         // Adjust for Block
  472.         if (($iAllW $iBdCnt$iBbCnt{
  473.             for ($i = 0; $i ($iBbCnt (($iAllW $iBdCnt$iBbCnt))$i++{
  474.                 fwrite($FILEpack("V"-1));
  475.             }
  476.         }
  477.         // Extra BDList
  478.         if ($iBdCnt $i1stBdL{
  479.             $iN=0;
  480.             $iNb=0;
  481.             for ($i $i1stBdL;$i $iBdCnt$i++$iN++{
  482.                 if ($iN >= ($iBbCnt - 1)) {
  483.                     $iN = 0;
  484.                     $iNb++;
  485.                     fwrite($FILEpack("V"$iAll+$iBdCnt+$iNb));
  486.                 }
  487.                 fwrite($FILEpack("V"$iBsize+$iSbdSize+$iPpsCnt+$i));
  488.             }
  489.             if (($iBdCnt-$i1stBdL($iBbCnt-1)) {
  490.                 for ($i = 0; $i (($iBbCnt - 1(($iBdCnt $i1stBdL($iBbCnt - 1)))$i++{
  491.                     fwrite($FILEpack("V"-1))
  492.                 }
  493.             }
  494.             fwrite($FILEpack("V"-2));
  495.         }
  496.     }
  497.  
  498.  
  499.  
  500.     /**
  501.      * New method to store Bigblock chain
  502.      *
  503.      * @access private
  504.      * @param integer $num_sb_blocks - number of Smallblock depot blocks
  505.      * @param integer $num_bb_blocks - number of Bigblock depot blocks
  506.      * @param integer $num_pps_blocks - number of PropertySetStorage blocks
  507.      */
  508.     function _create_big_block_chain($num_sb_blocks$num_bb_blocks$num_pps_blocks
  509.     {
  510.       $FILE $this->_FILEH_;
  511.  
  512.       $bbd_info $this->_calculate_big_block_chain($num_sb_blocks$num_bb_blocks$num_pps_blocks);
  513.           
  514.       $data "";
  515.  
  516.       if($num_sb_blocks > 0)
  517.         {
  518.           for($i = 0; $i<($num_sb_blocks-1)$i++)
  519.             $data .= pack("V"$i+1);
  520.           $data .= pack("V"-2);
  521.         }
  522.  
  523.       for($i = 0; $i<($num_bb_blocks-1)$i++)
  524.         $data .= pack("V"$i $num_sb_blocks + 1);
  525.       $data .= pack("V"-2);
  526.  
  527.       for($i = 0; $i<($num_pps_blocks-1)$i++)
  528.         $data .= pack("V"$i $num_sb_blocks $num_bb_blocks + 1);
  529.       $data .= pack("V"-2);
  530.  
  531.       for($i = 0; $i $bbd_info["0xFFFFFFFD_blockchain_entries"]$i++)
  532.         $data .= pack("V"0xFFFFFFFD);
  533.  
  534.       for($i = 0; $i $bbd_info["0xFFFFFFFC_blockchain_entries"]$i++)
  535.         $data .= pack("V"0xFFFFFFFC);
  536.  
  537.       // Adjust for Block
  538.       $all_entries $num_sb_blocks $num_bb_blocks $num_pps_blocks $bbd_info["0xFFFFFFFD_blockchain_entries"$bbd_info["0xFFFFFFFC_blockchain_entries"];
  539.       if($all_entries $bbd_info["entries_per_block"])
  540.         {
  541.           $rest $bbd_info["entries_per_block"($all_entries $bbd_info["entries_per_block"]);
  542.           for($i = 0; $i $rest$i++)
  543.             $data .= pack("V"-1);
  544.         }
  545.  
  546.       // Extra BDList
  547.       if($bbd_info["blockchain_list_entries"$bbd_info["header_blockchain_list_entries"])
  548.         {
  549.           $iN=0;
  550.           $iNb=0;
  551.           for($i $bbd_info["header_blockchain_list_entries"]$i $bbd_info["blockchain_list_entries"]$i++$iN++)
  552.             {
  553.               if($iN >= ($bbd_info["entries_per_block"]-1))
  554.                 {
  555.                   $iN = 0;
  556.                   $iNb++;
  557.                   $data .= pack("V"$num_sb_blocks $num_bb_blocks $num_pps_blocks $bbd_info["0xFFFFFFFD_blockchain_entries"$iNb);
  558.                 }
  559.  
  560.               $data .= pack("V"$num_bb_blocks $num_sb_blocks $num_pps_blocks $i);
  561.             }
  562.  
  563.           $all_entries $bbd_info["blockchain_list_entries"$bbd_info["header_blockchain_list_entries"];
  564.           if(($all_entries ($bbd_info["entries_per_block"- 1)))
  565.             {
  566.               $rest ($bbd_info["entries_per_block"- 1($all_entries ($bbd_info["entries_per_block"- 1));
  567.               for($i = 0; $i $rest$i++)
  568.                 $data .= pack("V"-1);
  569.             }
  570.  
  571.           $data .= pack("V"-2);
  572.         }
  573.  
  574.       /*
  575.         $this->dump($data, 0, strlen($data));
  576.         die;
  577.       */
  578.  
  579.       fwrite($FILE$data);
  580.     }
  581.  
  582.     /**
  583.      * New method to store Header
  584.      *
  585.      * @access private
  586.      * @param integer $num_sb_blocks - number of Smallblock depot blocks
  587.      * @param integer $num_bb_blocks - number of Bigblock depot blocks
  588.      * @param integer $num_pps_blocks - number of PropertySetStorage blocks
  589.      */
  590.     function _create_header($num_sb_blocks$num_bb_blocks$num_pps_blocks
  591.     {
  592.       $FILE $this->_FILEH_;
  593.  
  594.       $bbd_info $this->_calculate_big_block_chain($num_sb_blocks$num_bb_blocks$num_pps_blocks);
  595.   
  596.       // Save Header
  597.       fwrite($FILE,
  598.              "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1"
  599.              . "\x00\x00\x00\x00"
  600.              . "\x00\x00\x00\x00"
  601.              . "\x00\x00\x00\x00"
  602.              . "\x00\x00\x00\x00"
  603.              . pack("v"0x3b)
  604.              . pack("v"0x03)
  605.              . pack("v"-2)
  606.              . pack("v"9)
  607.              . pack("v"6)
  608.              . pack("v"0)
  609.              . "\x00\x00\x00\x00"
  610.              . "\x00\x00\x00\x00"
  611.              . pack("V"$bbd_info["blockchain_list_entries"]
  612.              . pack("V"$num_sb_blocks $num_bb_blocks//ROOT START
  613.              . pack("V"0)
  614.              . pack("V"0x1000)
  615.              );
  616.  
  617.       //Small Block Depot
  618.       if($num_sb_blocks > 0)
  619.         fwrite($FILEpack("V"0));
  620.       else
  621.         fwrite($FILEpack("V"-2));
  622.  
  623.       fwrite($FILEpack("V"1));
  624.  
  625.       // Extra BDList Start, Count
  626.       if($bbd_info["blockchain_list_entries"$bbd_info["header_blockchain_list_entries"])
  627.         {
  628.           fwrite($FILE,
  629.                  pack("V"-2).      // Extra BDList Start
  630.                  pack("V"0)        // Extra BDList Count
  631.                  );
  632.         }
  633.       else
  634.         {
  635.           fwrite($FILEpack("V"$num_sb_blocks $num_bb_blocks $num_pps_blocks $bbd_info["0xFFFFFFFD_blockchain_entries"]pack("V"$bbd_info["0xFFFFFFFC_blockchain_entries"]));
  636.         }
  637.  
  638.       // BDList
  639.       for ($i=0; $i $bbd_info["header_blockchain_list_entries"and $i $bbd_info["blockchain_list_entries"]$i++
  640.         {
  641.           fwrite($FILEpack("V"$num_bb_blocks $num_sb_blocks $num_pps_blocks $i));
  642.         }
  643.  
  644.       if($i $bbd_info["header_blockchain_list_entries"])
  645.         {
  646.           for($j = 0; $j ($bbd_info["header_blockchain_list_entries"]-$i)$j++
  647.             {
  648.               fwrite($FILE(pack("V"-1)));
  649.             }
  650.         }
  651.     }
  652.  
  653.     /**
  654.      * New method to calculate Bigblock chain
  655.      *
  656.      * @access private
  657.      * @param integer $num_sb_blocks - number of Smallblock depot blocks
  658.      * @param integer $num_bb_blocks - number of Bigblock depot blocks
  659.      * @param integer $num_pps_blocks - number of PropertySetStorage blocks
  660.      */
  661.     function _calculate_big_block_chain($num_sb_blocks$num_bb_blocks$num_pps_blocks)
  662.     {
  663.       $bbd_info["entries_per_block"$this->_BIG_BLOCK_SIZE OLE_LONG_INT_SIZE;
  664.       $bbd_info["header_blockchain_list_entries"($this->_BIG_BLOCK_SIZE - 0x4COLE_LONG_INT_SIZE;
  665.       $bbd_info["blockchain_entries"$num_sb_blocks $num_bb_blocks $num_pps_blocks;
  666.       $bbd_info["0xFFFFFFFD_blockchain_entries"$this->get_number_of_pointer_blocks($bbd_info["blockchain_entries"]);
  667.       $bbd_info["blockchain_list_entries"$this->get_number_of_pointer_blocks($bbd_info["blockchain_entries"$bbd_info["0xFFFFFFFD_blockchain_entries"]);
  668.  
  669.       // do some magic
  670.       $bbd_info["ext_blockchain_list_entries"= 0;
  671.       $bbd_info["0xFFFFFFFC_blockchain_entries"= 0;
  672.       if($bbd_info["blockchain_list_entries"$bbd_info["header_blockchain_list_entries"])
  673.         {
  674.           do
  675.             {
  676.               $bbd_info["blockchain_list_entries"$this->get_number_of_pointer_blocks($bbd_info["blockchain_entries"$bbd_info["0xFFFFFFFD_blockchain_entries"$bbd_info["0xFFFFFFFC_blockchain_entries"]);
  677.               $bbd_info["ext_blockchain_list_entries"$bbd_info["blockchain_list_entries"$bbd_info["header_blockchain_list_entries"];
  678.               $bbd_info["0xFFFFFFFC_blockchain_entries"$this->get_number_of_pointer_blocks($bbd_info["ext_blockchain_list_entries"]);
  679.               $bbd_info["0xFFFFFFFD_blockchain_entries"$this->get_number_of_pointer_blocks($num_sb_blocks $num_bb_blocks $num_pps_blocks $bbd_info["0xFFFFFFFD_blockchain_entries"$bbd_info["0xFFFFFFFC_blockchain_entries"]);
  680.             }
  681.           while($bbd_info["blockchain_list_entries"$this->get_number_of_pointer_blocks($bbd_info["blockchain_entries"$bbd_info["0xFFFFFFFD_blockchain_entries"$bbd_info["0xFFFFFFFC_blockchain_entries"]));
  682.         }
  683.  
  684.       return $bbd_info;
  685.     }
  686.  
  687.     /**
  688.      * Calculates number of pointer blocks
  689.      *
  690.      * @access public
  691.      * @param integer $num_pointers - number of pointers
  692.      */
  693.     function get_number_of_pointer_blocks($num_pointers)
  694.     {
  695.       $pointers_per_block $this->_BIG_BLOCK_SIZE OLE_LONG_INT_SIZE;
  696.       
  697.       return floor($num_pointers $pointers_per_block(($num_pointers $pointers_per_block)? 1: 0);
  698.     }
  699.  
  700.     /**
  701.      * Support method for some hexdumping
  702.      *
  703.      * @access public
  704.      * @param string $data - Binary data
  705.      * @param integer $from - Start offset of data to dump
  706.      * @param integer $to - Target offset of data to dump
  707.      */
  708.     function dump($data$from$to)
  709.     {
  710.       $chars = array();
  711.       $i = 0;
  712.       for($i $from$i $to$i++)
  713.         {
  714.           if(sizeof($chars== 16)
  715.             {
  716.               printf("%08X (% 12d) |"$i-16$i-16);
  717.               foreach($chars as $char)
  718.                 printf(" %02X"$char);
  719.               print " |\n";
  720.  
  721.               $chars = array();
  722.             }
  723.  
  724.           $chars[ord($data[$i]);
  725.         }
  726.  
  727.       if(sizeof($chars))
  728.         {
  729.           printf("%08X (% 12d) |"$i-sizeof($chars)$i-sizeof($chars));
  730.           foreach($chars as $char)
  731.             printf(" %02X"$char);
  732.           print " |\n";
  733.  
  734.           $chars = array();
  735.         }
  736.     }
  737. }
  738. ?>

Documentation generated on Mon, 11 Mar 2019 15:47:11 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.