[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |