PHPExcel_Shared_OLE
[ class tree: PHPExcel_Shared_OLE ] [ index: PHPExcel_Shared_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,v 1.9 2005/04/23 21:53:49 dufuz Exp $
  21.  
  22.  
  23. /**
  24. * Class for creating Root PPS's for OLE containers
  25. *
  26. @author   Xavier Noguer <xnoguer@php.net>
  27. @category PHPExcel
  28. @package  PHPExcel_Shared_OLE
  29. */
  30.     {
  31.  
  32.     /**
  33.      *    Directory for temporary files
  34.      *    @var string 
  35.      */
  36.     protected $_tmp_dir        = '';
  37.  
  38.     /**
  39.      * @param integer $time_1st A timestamp
  40.      * @param integer $time_2nd A timestamp
  41.      */
  42.     public function __construct($time_1st$time_2nd$raChild)
  43.     {
  44.         $this->_tempDir PHPExcel_Shared_File::sys_get_temp_dir();
  45.  
  46.         parent::__construct(
  47.            null,
  48.            PHPExcel_Shared_OLE::Asc2Ucs('Root Entry'),
  49.            PHPExcel_Shared_OLE::OLE_PPS_TYPE_ROOT,
  50.            null,
  51.            null,
  52.            null,
  53.            $time_1st,
  54.            $time_2nd,
  55.            null,
  56.            $raChild);
  57.     }
  58.  
  59.     /**
  60.     * Method for saving the whole OLE container (including files).
  61.     * In fact, if called with an empty argument (or '-'), it saves to a
  62.     * temporary file and then outputs it's contents to stdout.
  63.     * If a resource pointer to a stream created by fopen() is passed
  64.     * it will be used, but you have to close such stream by yourself.
  65.     *
  66.     * @param string|resource$filename The name of the file or stream where to save the OLE container.
  67.     * @access public
  68.     * @return mixed true on success
  69.     */
  70.     public function save($filename)
  71.     {
  72.         // Initial Setting for saving
  73.         $this->_BIG_BLOCK_SIZE  pow(2,
  74.                       ((isset($this->_BIG_BLOCK_SIZE))self::_adjust2($this->_BIG_BLOCK_SIZE)  9));
  75.         $this->_SMALL_BLOCK_SIZEpow(2,
  76.                       ((isset($this->_SMALL_BLOCK_SIZE))?  self::_adjust2($this->_SMALL_BLOCK_SIZE)6));
  77.  
  78.         if (is_resource($filename)) {
  79.             $this->_FILEH_ $filename;
  80.         else if ($filename == '-' || $filename == ''{
  81.             $this->_tmp_filename tempnam($this->_tmp_dir"OLE_PPS_Root");
  82.             $this->_FILEH_ fopen($this->_tmp_filename,"w+b");
  83.             if ($this->_FILEH_ == false{
  84.                 throw new Exception("Can't create temporary file.");
  85.             }
  86.         else {
  87.             $this->_FILEH_ fopen($filename"wb");
  88.         }
  89.         if ($this->_FILEH_ == false{
  90.             throw new Exception("Can't open $filename. It may be in use or protected.");
  91.         }
  92.         // Make an array of PPS's (for Save)
  93.         $aList array();
  94.         $this->_savePpsSetPnt($aList);
  95.         // calculate values for header
  96.         list($iSBDcnt$iBBcnt$iPPScnt$this->_calcSize($aList)//, $rhInfo);
  97.         // Save Header
  98.         $this->_saveHeader($iSBDcnt$iBBcnt$iPPScnt);
  99.  
  100.         // Make Small Data string (write SBD)
  101.         $this->_data = $this->_makeSmallData($aList);
  102.  
  103.         // Write BB
  104.         $this->_saveBigData($iSBDcnt$aList);
  105.         // Write PPS
  106.         $this->_savePps($aList);
  107.         // Write Big Block Depot and BDList and Adding Header informations
  108.         $this->_saveBbd($iSBDcnt$iBBcnt$iPPScnt);
  109.  
  110.         if (!is_resource($filename)) {
  111.              fclose($this->_FILEH_);
  112.          }
  113.  
  114.         return true;
  115.     }
  116.  
  117.     /**
  118.     * Calculate some numbers
  119.     *
  120.     * @access public
  121.     * @param array $raList Reference to an array of PPS's
  122.     * @return array The array of numbers
  123.     */
  124.     public function _calcSize(&$raList)
  125.     {
  126.         // Calculate Basic Setting
  127.         list($iSBDcnt$iBBcnt$iPPScntarray(0,0,0);
  128.         $iSmallLen 0;
  129.         $iSBcnt 0;
  130.         $iCount count($raList);
  131.         for ($i 0$i $iCount++$i{
  132.             if ($raList[$i]->Type == PHPExcel_Shared_OLE::OLE_PPS_TYPE_FILE{
  133.                 $raList[$i]->Size $raList[$i]->_DataLen();
  134.                 if ($raList[$i]->Size PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL{
  135.                     $iSBcnt += floor($raList[$i]->Size $this->_SMALL_BLOCK_SIZE)
  136.                                   + (($raList[$i]->Size $this->_SMALL_BLOCK_SIZE)10);
  137.                 else {
  138.                     $iBBcnt += (floor($raList[$i]->Size $this->_BIG_BLOCK_SIZE+
  139.                         (($raList[$i]->Size $this->_BIG_BLOCK_SIZE)10));
  140.                 }
  141.             }
  142.         }
  143.         $iSmallLen $iSBcnt $this->_SMALL_BLOCK_SIZE;
  144.         $iSlCnt floor($this->_BIG_BLOCK_SIZE PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE);
  145.         $iSBDcnt floor($iSBcnt $iSlCnt(($iSBcnt $iSlCnt)1:0);
  146.         $iBBcnt +=  (floor($iSmallLen $this->_BIG_BLOCK_SIZE+
  147.                       (( $iSmallLen $this->_BIG_BLOCK_SIZE)10));
  148.         $iCnt count($raList);
  149.         $iBdCnt $this->_BIG_BLOCK_SIZE PHPExcel_Shared_OLE::OLE_PPS_SIZE;
  150.         $iPPScnt (floor($iCnt/$iBdCnt(($iCnt $iBdCnt)10));
  151.  
  152.         return array($iSBDcnt$iBBcnt$iPPScnt);
  153.     }
  154.  
  155.     /**
  156.     * Helper function for caculating a magic value for block sizes
  157.     *
  158.     * @access public
  159.     * @param integer $i2 The argument
  160.     * @see save()
  161.     * @return integer 
  162.     */
  163.     private static function _adjust2($i2)
  164.     {
  165.         $iWk log($i2)/log(2);
  166.         return ($iWk floor($iWk))floor($iWk)+1:$iWk;
  167.     }
  168.  
  169.     /**
  170.     * Save OLE header
  171.     *
  172.     * @access public
  173.     * @param integer $iSBDcnt 
  174.     * @param integer $iBBcnt 
  175.     * @param integer $iPPScnt 
  176.     */
  177.     public function _saveHeader($iSBDcnt$iBBcnt$iPPScnt)
  178.     {
  179.         $FILE $this->_FILEH_;
  180.  
  181.         // Calculate Basic Setting
  182.         $iBlCnt $this->_BIG_BLOCK_SIZE PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE;
  183.         $i1stBdL ($this->_BIG_BLOCK_SIZE 0x4CPHPExcel_Shared_OLE::OLE_LONG_INT_SIZE;
  184.  
  185.         $iBdExL 0;
  186.         $iAll $iBBcnt $iPPScnt $iSBDcnt;
  187.         $iAllW $iAll;
  188.         $iBdCntW floor($iAllW $iBlCnt(($iAllW $iBlCnt)10);
  189.         $iBdCnt floor(($iAll $iBdCntW$iBlCnt((($iAllW+$iBdCntW$iBlCnt)10);
  190.  
  191.         // Calculate BD count
  192.         if ($iBdCnt $i1stBdL{
  193.             while (1{
  194.                 ++$iBdExL;
  195.                 ++$iAllW;
  196.                 $iBdCntW floor($iAllW $iBlCnt(($iAllW $iBlCnt)10);
  197.                 $iBdCnt floor(($iAllW $iBdCntW$iBlCnt((($iAllW+$iBdCntW$iBlCnt)10);
  198.                 if ($iBdCnt <= ($iBdExL*$iBlCnt$i1stBdL)) {
  199.                     break;
  200.                 }
  201.             }
  202.         }
  203.  
  204.         // Save Header
  205.         fwrite($FILE,
  206.                   "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1"
  207.                   . "\x00\x00\x00\x00"
  208.                   . "\x00\x00\x00\x00"
  209.                   . "\x00\x00\x00\x00"
  210.                   . "\x00\x00\x00\x00"
  211.                   . pack("v"0x3b)
  212.                   . pack("v"0x03)
  213.                   . pack("v"-2)
  214.                   . pack("v"9)
  215.                   . pack("v"6)
  216.                   . pack("v"0)
  217.                   . "\x00\x00\x00\x00"
  218.                   . "\x00\x00\x00\x00"
  219.                   . pack("V"$iBdCnt)
  220.                   . pack("V"$iBBcnt+$iSBDcnt//ROOT START
  221.                   . pack("V"0)
  222.                   . pack("V"0x1000)
  223.                   . pack("V"$iSBDcnt : -2)                  //Small Block Depot
  224.                   . pack("V"$iSBDcnt)
  225.           );
  226.         // Extra BDList Start, Count
  227.         if ($iBdCnt $i1stBdL{
  228.             fwrite($FILE,
  229.                       pack("V"-2).      // Extra BDList Start
  230.                       pack("V"0)        // Extra BDList Count
  231.                   );
  232.         else {
  233.             fwrite($FILEpack("V"$iAll+$iBdCntpack("V"$iBdExL));
  234.         }
  235.  
  236.         // BDList
  237.         for ($i 0$i $i1stBdL && $i $iBdCnt++$i{
  238.             fwrite($FILEpack("V"$iAll+$i));
  239.         }
  240.         if ($i $i1stBdL{
  241.             $jB $i1stBdL $i;
  242.             for ($j 0$j $jB++$j{
  243.                 fwrite($FILE(pack("V"-1)));
  244.             }
  245.         }
  246.     }
  247.  
  248.     /**
  249.     * Saving big data (PPS's with data bigger than PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL)
  250.     *
  251.     * @access public
  252.     * @param integer $iStBlk 
  253.     * @param array &$raList Reference to array of PPS's
  254.     */
  255.     public function _saveBigData($iStBlk&$raList)
  256.     {
  257.         $FILE $this->_FILEH_;
  258.  
  259.         // cycle through PPS's
  260.         $iCount count($raList);
  261.         for ($i 0$i $iCount++$i{
  262.             if ($raList[$i]->Type != PHPExcel_Shared_OLE::OLE_PPS_TYPE_DIR{
  263.                 $raList[$i]->Size $raList[$i]->_DataLen();
  264.                 if (($raList[$i]->Size >= PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL||
  265.                     (($raList[$i]->Type == PHPExcel_Shared_OLE::OLE_PPS_TYPE_ROOT&& isset($raList[$i]->_data)))
  266.                 {
  267.                     // Write Data
  268.                     //if (isset($raList[$i]->_PPS_FILE)) {
  269.                     //    $iLen = 0;
  270.                     //    fseek($raList[$i]->_PPS_FILE, 0); // To The Top
  271.                     //    while($sBuff = fread($raList[$i]->_PPS_FILE, 4096)) {
  272.                     //        $iLen += strlen($sBuff);
  273.                     //        fwrite($FILE, $sBuff);
  274.                     //    }
  275.                     //} else {
  276.                         fwrite($FILE$raList[$i]->_data);
  277.                     //}
  278.  
  279.                     if ($raList[$i]->Size $this->_BIG_BLOCK_SIZE{
  280.                         fwrite($FILEstr_repeat("\x00"$this->_BIG_BLOCK_SIZE ($raList[$i]->Size $this->_BIG_BLOCK_SIZE)));
  281.                     }
  282.                     // Set For PPS
  283.                     $raList[$i]->_StartBlock $iStBlk;
  284.                     $iStBlk +=
  285.                             (floor($raList[$i]->Size $this->_BIG_BLOCK_SIZE+
  286.                                 (($raList[$i]->Size $this->_BIG_BLOCK_SIZE)10));
  287.                 }
  288.                 // Close file for each PPS, and unlink it
  289.                 //if (isset($raList[$i]->_PPS_FILE)) {
  290.                 //    fclose($raList[$i]->_PPS_FILE);
  291.                 //    $raList[$i]->_PPS_FILE = null;
  292.                 //    unlink($raList[$i]->_tmp_filename);
  293.                 //}
  294.             }
  295.         }
  296.     }
  297.  
  298.     /**
  299.     * get small data (PPS's with data smaller than PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL)
  300.     *
  301.     * @access public
  302.     * @param array &$raList Reference to array of PPS's
  303.     */
  304.     public function _makeSmallData(&$raList)
  305.     {
  306.         $sRes '';
  307.         $FILE $this->_FILEH_;
  308.         $iSmBlk 0;
  309.  
  310.         $iCount count($raList);
  311.         for ($i 0$i $iCount++$i{
  312.             // Make SBD, small data string
  313.             if ($raList[$i]->Type == PHPExcel_Shared_OLE::OLE_PPS_TYPE_FILE{
  314.                 if ($raList[$i]->Size <= 0{
  315.                     continue;
  316.                 }
  317.                 if ($raList[$i]->Size PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL{
  318.                     $iSmbCnt floor($raList[$i]->Size $this->_SMALL_BLOCK_SIZE)
  319.                                   + (($raList[$i]->Size $this->_SMALL_BLOCK_SIZE)10);
  320.                     // Add to SBD
  321.                     $jB $iSmbCnt 1;
  322.                     for ($j 0$j $jB++$j{
  323.                         fwrite($FILEpack("V"$j+$iSmBlk+1));
  324.                     }
  325.                     fwrite($FILEpack("V"-2));
  326.  
  327.                     //// Add to Data String(this will be written for RootEntry)
  328.                     //if ($raList[$i]->_PPS_FILE) {
  329.                     //    fseek($raList[$i]->_PPS_FILE, 0); // To The Top
  330.                     //    while ($sBuff = fread($raList[$i]->_PPS_FILE, 4096)) {
  331.                     //        $sRes .= $sBuff;
  332.                     //    }
  333.                     //} else {
  334.                         $sRes .= $raList[$i]->_data;
  335.                     //}
  336.                     if ($raList[$i]->Size $this->_SMALL_BLOCK_SIZE{
  337.                         $sRes .= str_repeat("\x00",$this->_SMALL_BLOCK_SIZE ($raList[$i]->Size $this->_SMALL_BLOCK_SIZE));
  338.                     }
  339.                     // Set for PPS
  340.                     $raList[$i]->_StartBlock $iSmBlk;
  341.                     $iSmBlk += $iSmbCnt;
  342.                 }
  343.             }
  344.         }
  345.         $iSbCnt floor($this->_BIG_BLOCK_SIZE PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE);
  346.         if ($iSmBlk $iSbCnt{
  347.             $iB $iSbCnt ($iSmBlk $iSbCnt);
  348.             for ($i 0$i $iB++$i{
  349.                 fwrite($FILEpack("V"-1));
  350.             }
  351.         }
  352.         return $sRes;
  353.     }
  354.  
  355.     /**
  356.     * Saves all the PPS's WKs
  357.     *
  358.     * @access public
  359.     * @param array $raList Reference to an array with all PPS's
  360.     */
  361.     public function _savePps(&$raList)
  362.     {
  363.         // Save each PPS WK
  364.         $iC count($raList);
  365.         for ($i 0$i $iC++$i{
  366.             fwrite($this->_FILEH_$raList[$i]->_getPpsWk());
  367.         }
  368.         // Adjust for Block
  369.         $iCnt count($raList);
  370.         $iBCnt $this->_BIG_BLOCK_SIZE PHPExcel_Shared_OLE::OLE_PPS_SIZE;
  371.         if ($iCnt $iBCnt{
  372.             fwrite($this->_FILEH_str_repeat("\x00",($iBCnt ($iCnt $iBCnt)) PHPExcel_Shared_OLE::OLE_PPS_SIZE));
  373.         }
  374.     }
  375.  
  376.     /**
  377.     * Saving Big Block Depot
  378.     *
  379.     * @access public
  380.     * @param integer $iSbdSize 
  381.     * @param integer $iBsize 
  382.     * @param integer $iPpsCnt 
  383.     */
  384.     public function _saveBbd($iSbdSize$iBsize$iPpsCnt)
  385.     {
  386.         $FILE $this->_FILEH_;
  387.         // Calculate Basic Setting
  388.         $iBbCnt $this->_BIG_BLOCK_SIZE PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE;
  389.         $i1stBdL ($this->_BIG_BLOCK_SIZE 0x4CPHPExcel_Shared_OLE::OLE_LONG_INT_SIZE;
  390.  
  391.         $iBdExL 0;
  392.         $iAll $iBsize $iPpsCnt $iSbdSize;
  393.         $iAllW $iAll;
  394.         $iBdCntW floor($iAllW $iBbCnt(($iAllW $iBbCnt)10);
  395.         $iBdCnt floor(($iAll $iBdCntW$iBbCnt((($iAllW+$iBdCntW$iBbCnt)10);
  396.         // Calculate BD count
  397.         if ($iBdCnt >$i1stBdL{
  398.             while (1{
  399.                 ++$iBdExL;
  400.                 ++$iAllW;
  401.                 $iBdCntW floor($iAllW $iBbCnt(($iAllW $iBbCnt)10);
  402.                 $iBdCnt floor(($iAllW $iBdCntW$iBbCnt((($iAllW+$iBdCntW$iBbCnt)10);
  403.                 if ($iBdCnt <= ($iBdExL*$iBbCnt$i1stBdL)) {
  404.                     break;
  405.                 }
  406.             }
  407.         }
  408.  
  409.         // Making BD
  410.         // Set for SBD
  411.         if ($iSbdSize 0{
  412.             for ($i 0$i ($iSbdSize 1)++$i{
  413.                 fwrite($FILEpack("V"$i+1));
  414.             }
  415.             fwrite($FILEpack("V"-2));
  416.         }
  417.         // Set for B
  418.         for ($i 0$i ($iBsize 1)++$i{
  419.             fwrite($FILEpack("V"$i+$iSbdSize+1));
  420.         }
  421.         fwrite($FILEpack("V"-2));
  422.  
  423.         // Set for PPS
  424.         for ($i 0$i ($iPpsCnt 1)++$i{
  425.             fwrite($FILEpack("V"$i+$iSbdSize+$iBsize+1));
  426.         }
  427.         fwrite($FILEpack("V"-2));
  428.         // Set for BBD itself ( 0xFFFFFFFD : BBD)
  429.         for ($i 0$i $iBdCnt++$i{
  430.             fwrite($FILEpack("V"0xFFFFFFFD));
  431.         }
  432.         // Set for ExtraBDList
  433.         for ($i 0$i $iBdExL++$i{
  434.             fwrite($FILEpack("V"0xFFFFFFFC));
  435.         }
  436.         // Adjust for Block
  437.         if (($iAllW $iBdCnt$iBbCnt{
  438.             $iBlock ($iBbCnt (($iAllW $iBdCnt$iBbCnt));
  439.             for ($i 0$i $iBlock++$i{
  440.                 fwrite($FILEpack("V"-1));
  441.             }
  442.         }
  443.         // Extra BDList
  444.         if ($iBdCnt $i1stBdL{
  445.             $iN=0;
  446.             $iNb=0;
  447.             for ($i $i1stBdL;$i $iBdCnt$i++++$iN{
  448.                 if ($iN >= ($iBbCnt 1)) {
  449.                     $iN 0;
  450.                     ++$iNb;
  451.                     fwrite($FILEpack("V"$iAll+$iBdCnt+$iNb));
  452.                 }
  453.                 fwrite($FILEpack("V"$iBsize+$iSbdSize+$iPpsCnt+$i));
  454.             }
  455.             if (($iBdCnt-$i1stBdL($iBbCnt-1)) {
  456.                 $iB ($iBbCnt 1(($iBdCnt $i1stBdL($iBbCnt 1));
  457.                 for ($i 0$i $iB++$i{
  458.                     fwrite($FILEpack("V"-1));
  459.                 }
  460.             }
  461.             fwrite($FILEpack("V"-2));
  462.         }
  463.     }
  464. }

Documentation generated on Sun, 27 Feb 2011 16:33:47 -0800 by phpDocumentor 1.4.3