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

Documentation generated on Tue, 01 Jun 2010 17:05:55 +0200 by phpDocumentor 1.4.3