File Source for Root.php

PHPExcel_Shared_OLE

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

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