[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/phpexcel/PHPExcel/Shared/OLE/PPS/ -> Root.php (source)

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


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1