PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.9.4
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.9.4
4.0.8 4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 All 149 releases
visualizer / vendor / phpoffice / phpspreadsheet / src / PhpSpreadsheet / Shared / OLE / PPS / Root.php

Root.php in Visualizer – Tables & Charts Manager with Built-in AI Generator 3.9.4, at vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/OLE/PPS/Root.php

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