ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
Root.php
Go to the documentation of this file.
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.10 2008/02/02 21:00:37 schmidt Exp $
21
22
23require_once 'OLE/PPS.php';
24require_once 'System.php';
25
33class OLE_PPS_Root extends OLE_PPS
34{
40
48 function OLE_PPS_Root($time_1st, $time_2nd, $raChild)
49 {
50 $this->_tmp_dir = System::tmpdir();
51 $this->OLE_PPS(
52 null,
53 OLE::Asc2Ucs('Root Entry'),
55 null,
56 null,
57 null,
58 $time_1st,
59 $time_2nd,
60 null,
61 $raChild);
62 }
63
71 function setTempDir($dir)
72 {
73 if (is_dir($dir)) {
74 $this->_tmp_dir = $dir;
75 return true;
76 }
77 return false;
78 }
79
89 function save($filename)
90 {
91 // Initial Setting for saving
92 $this->_BIG_BLOCK_SIZE = pow(2,
93 ((isset($this->_BIG_BLOCK_SIZE))? $this->_adjust2($this->_BIG_BLOCK_SIZE) : 9));
94 $this->_SMALL_BLOCK_SIZE= pow(2,
95 ((isset($this->_SMALL_BLOCK_SIZE))? $this->_adjust2($this->_SMALL_BLOCK_SIZE): 6));
96
97 // Open temp file if we are sending output to stdout
98 if (($filename == '-') || ($filename == '')) {
99 $this->_tmp_filename = tempnam($this->_tmp_dir, "OLE_PPS_Root");
100 $this->_FILEH_ = @fopen($this->_tmp_filename,"w+b");
101 if ($this->_FILEH_ == false) {
102 return $this->raiseError("Can't create temporary file.");
103 }
104 } else {
105 $this->_FILEH_ = @fopen($filename, "wb");
106 if ($this->_FILEH_ == false) {
107 return $this->raiseError("Can't open $filename. It may be in use or protected.");
108 }
109 }
110 // Make an array of PPS's (for Save)
111 $aList = array();
112 $this->_savePpsSetPnt($aList);
113 // calculate values for header
114 list($iSBDcnt, $iBBcnt, $iPPScnt) = $this->_calcSize($aList); //, $rhInfo);
115 // Save Header
116 $this->_saveHeader($iSBDcnt, $iBBcnt, $iPPScnt);
117
118 // Make Small Data string (write SBD)
119 $this->_data = $this->_makeSmallData($aList);
120
121 // Write BB
122 $this->_saveBigData($iSBDcnt, $aList);
123 // Write PPS
124 $this->_savePps($aList);
125 // Write Big Block Depot and BDList and Adding Header informations
126 $this->_saveBbd($iSBDcnt, $iBBcnt, $iPPScnt);
127 // Close File, send it to stdout if necessary
128 if (($filename == '-') || ($filename == '')) {
129 fseek($this->_FILEH_, 0);
130 fpassthru($this->_FILEH_);
131 @fclose($this->_FILEH_);
132 // Delete the temporary file.
133 @unlink($this->_tmp_filename);
134 } else {
135 @fclose($this->_FILEH_);
136 }
137
138 return true;
139 }
140
148 function _calcSize(&$raList)
149 {
150 // Calculate Basic Setting
151 list($iSBDcnt, $iBBcnt, $iPPScnt) = array(0,0,0);
152 $iSmallLen = 0;
153 $iSBcnt = 0;
154 for ($i = 0; $i < count($raList); $i++) {
155 if ($raList[$i]->Type == OLE_PPS_TYPE_FILE) {
156 $raList[$i]->Size = $raList[$i]->_DataLen();
157 if ($raList[$i]->Size < OLE_DATA_SIZE_SMALL) {
158 $iSBcnt += floor($raList[$i]->Size / $this->_SMALL_BLOCK_SIZE)
159 + (($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)? 1: 0);
160 } else {
161 $iBBcnt += (floor($raList[$i]->Size / $this->_BIG_BLOCK_SIZE) +
162 (($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)? 1: 0));
163 }
164 }
165 }
166 $iSmallLen = $iSBcnt * $this->_SMALL_BLOCK_SIZE;
167 $iSlCnt = floor($this->_BIG_BLOCK_SIZE / OLE_LONG_INT_SIZE);
168 $iSBDcnt = floor($iSBcnt / $iSlCnt) + (($iSBcnt % $iSlCnt)? 1:0);
169 $iBBcnt += (floor($iSmallLen / $this->_BIG_BLOCK_SIZE) +
170 (( $iSmallLen % $this->_BIG_BLOCK_SIZE)? 1: 0));
171 $iCnt = count($raList);
172 $iBdCnt = $this->_BIG_BLOCK_SIZE / OLE_PPS_SIZE;
173 $iPPScnt = (floor($iCnt/$iBdCnt) + (($iCnt % $iBdCnt)? 1: 0));
174
175 return array($iSBDcnt, $iBBcnt, $iPPScnt);
176 }
177
186 function _adjust2($i2)
187 {
188 $iWk = log($i2)/log(2);
189 return ($iWk > floor($iWk))? floor($iWk)+1:$iWk;
190 }
191
200 function _saveHeader($iSBDcnt, $iBBcnt, $iPPScnt)
201 {
202 $FILE = $this->_FILEH_;
203
204 // Calculate Basic Setting
205 $iBlCnt = $this->_BIG_BLOCK_SIZE / OLE_LONG_INT_SIZE;
206 $i1stBdL = ($this->_BIG_BLOCK_SIZE - 0x4C) / OLE_LONG_INT_SIZE;
207
208 $iBdExL = 0;
209 $iAll = $iBBcnt + $iPPScnt + $iSBDcnt;
210 $iAllW = $iAll;
211 $iBdCntW = floor($iAllW / $iBlCnt) + (($iAllW % $iBlCnt)? 1: 0);
212 $iBdCnt = floor(($iAll + $iBdCntW) / $iBlCnt) + ((($iAllW+$iBdCntW) % $iBlCnt)? 1: 0);
213
214 // Calculate BD count
215 if ($iBdCnt > $i1stBdL) {
216 while (1) {
217 $iBdExL++;
218 $iAllW++;
219 $iBdCntW = floor($iAllW / $iBlCnt) + (($iAllW % $iBlCnt)? 1: 0);
220 $iBdCnt = floor(($iAllW + $iBdCntW) / $iBlCnt) + ((($iAllW+$iBdCntW) % $iBlCnt)? 1: 0);
221 if ($iBdCnt <= ($iBdExL*$iBlCnt+ $i1stBdL)) {
222 break;
223 }
224 }
225 }
226
227 // Save Header
228 fwrite($FILE,
229 "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1"
230 . "\x00\x00\x00\x00"
231 . "\x00\x00\x00\x00"
232 . "\x00\x00\x00\x00"
233 . "\x00\x00\x00\x00"
234 . pack("v", 0x3b)
235 . pack("v", 0x03)
236 . pack("v", -2)
237 . pack("v", 9)
238 . pack("v", 6)
239 . pack("v", 0)
240 . "\x00\x00\x00\x00"
241 . "\x00\x00\x00\x00"
242 . pack("V", $iBdCnt)
243 . pack("V", $iBBcnt+$iSBDcnt) //ROOT START
244 . pack("V", 0)
245 . pack("V", 0x1000)
246 . pack("V", 0) //Small Block Depot
247 . pack("V", 1)
248 );
249 // Extra BDList Start, Count
250 if ($iBdCnt < $i1stBdL) {
251 fwrite($FILE,
252 pack("V", -2). // Extra BDList Start
253 pack("V", 0) // Extra BDList Count
254 );
255 } else {
256 fwrite($FILE, pack("V", $iAll+$iBdCnt) . pack("V", $iBdExL));
257 }
258
259 // BDList
260 for ($i = 0; $i < $i1stBdL && $i < $iBdCnt; $i++) {
261 fwrite($FILE, pack("V", $iAll+$i));
262 }
263 if ($i < $i1stBdL) {
264 for ($j = 0; $j < ($i1stBdL-$i); $j++) {
265 fwrite($FILE, (pack("V", -1)));
266 }
267 }
268 }
269
277 function _saveBigData($iStBlk, &$raList)
278 {
279 $FILE = $this->_FILEH_;
280
281 // cycle through PPS's
282 for ($i = 0; $i < count($raList); $i++) {
283 if ($raList[$i]->Type != OLE_PPS_TYPE_DIR) {
284 $raList[$i]->Size = $raList[$i]->_DataLen();
285 if (($raList[$i]->Size >= OLE_DATA_SIZE_SMALL) ||
286 (($raList[$i]->Type == OLE_PPS_TYPE_ROOT) && isset($raList[$i]->_data)))
287 {
288 // Write Data
289 if (isset($raList[$i]->_PPS_FILE)) {
290 $iLen = 0;
291 fseek($raList[$i]->_PPS_FILE, 0); // To The Top
292 while($sBuff = fread($raList[$i]->_PPS_FILE, 4096)) {
293 $iLen += strlen($sBuff);
294 fwrite($FILE, $sBuff);
295 }
296 } else {
297 fwrite($FILE, $raList[$i]->_data);
298 }
299
300 if ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE) {
301 for ($j = 0; $j < ($this->_BIG_BLOCK_SIZE - ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)); $j++) {
302 fwrite($FILE, "\x00");
303 }
304 }
305 // Set For PPS
306 $raList[$i]->_StartBlock = $iStBlk;
307 $iStBlk +=
308 (floor($raList[$i]->Size / $this->_BIG_BLOCK_SIZE) +
309 (($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)? 1: 0));
310 }
311 // Close file for each PPS, and unlink it
312 if (isset($raList[$i]->_PPS_FILE)) {
313 @fclose($raList[$i]->_PPS_FILE);
314 $raList[$i]->_PPS_FILE = null;
315 @unlink($raList[$i]->_tmp_filename);
316 }
317 }
318 }
319 }
320
327 function _makeSmallData(&$raList)
328 {
329 $sRes = '';
330 $FILE = $this->_FILEH_;
331 $iSmBlk = 0;
332
333 for ($i = 0; $i < count($raList); $i++) {
334 // Make SBD, small data string
335 if ($raList[$i]->Type == OLE_PPS_TYPE_FILE) {
336 if ($raList[$i]->Size <= 0) {
337 continue;
338 }
339 if ($raList[$i]->Size < OLE_DATA_SIZE_SMALL) {
340 $iSmbCnt = floor($raList[$i]->Size / $this->_SMALL_BLOCK_SIZE)
341 + (($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)? 1: 0);
342 // Add to SBD
343 for ($j = 0; $j < ($iSmbCnt-1); $j++) {
344 fwrite($FILE, pack("V", $j+$iSmBlk+1));
345 }
346 fwrite($FILE, pack("V", -2));
347
348 // Add to Data String(this will be written for RootEntry)
349 if ($raList[$i]->_PPS_FILE) {
350 fseek($raList[$i]->_PPS_FILE, 0); // To The Top
351 while ($sBuff = fread($raList[$i]->_PPS_FILE, 4096)) {
352 $sRes .= $sBuff;
353 }
354 } else {
355 $sRes .= $raList[$i]->_data;
356 }
357 if ($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE) {
358 for ($j = 0; $j < ($this->_SMALL_BLOCK_SIZE - ($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)); $j++) {
359 $sRes .= "\x00";
360 }
361 }
362 // Set for PPS
363 $raList[$i]->_StartBlock = $iSmBlk;
364 $iSmBlk += $iSmbCnt;
365 }
366 }
367 }
368 $iSbCnt = floor($this->_BIG_BLOCK_SIZE / OLE_LONG_INT_SIZE);
369 if ($iSmBlk % $iSbCnt) {
370 for ($i = 0; $i < ($iSbCnt - ($iSmBlk % $iSbCnt)); $i++) {
371 fwrite($FILE, pack("V", -1));
372 }
373 }
374 return $sRes;
375 }
376
383 function _savePps(&$raList)
384 {
385 // Save each PPS WK
386 for ($i = 0; $i < count($raList); $i++) {
387 fwrite($this->_FILEH_, $raList[$i]->_getPpsWk());
388 }
389 // Adjust for Block
390 $iCnt = count($raList);
391 $iBCnt = $this->_BIG_BLOCK_SIZE / OLE_PPS_SIZE;
392 if ($iCnt % $iBCnt) {
393 for ($i = 0; $i < (($iBCnt - ($iCnt % $iBCnt)) * OLE_PPS_SIZE); $i++) {
394 fwrite($this->_FILEH_, "\x00");
395 }
396 }
397 }
398
407 function _saveBbd($iSbdSize, $iBsize, $iPpsCnt)
408 {
409 $FILE = $this->_FILEH_;
410 // Calculate Basic Setting
411 $iBbCnt = $this->_BIG_BLOCK_SIZE / OLE_LONG_INT_SIZE;
412 $i1stBdL = ($this->_BIG_BLOCK_SIZE - 0x4C) / OLE_LONG_INT_SIZE;
413
414 $iBdExL = 0;
415 $iAll = $iBsize + $iPpsCnt + $iSbdSize;
416 $iAllW = $iAll;
417 $iBdCntW = floor($iAllW / $iBbCnt) + (($iAllW % $iBbCnt)? 1: 0);
418 $iBdCnt = floor(($iAll + $iBdCntW) / $iBbCnt) + ((($iAllW+$iBdCntW) % $iBbCnt)? 1: 0);
419 // Calculate BD count
420 if ($iBdCnt >$i1stBdL) {
421 while (1) {
422 $iBdExL++;
423 $iAllW++;
424 $iBdCntW = floor($iAllW / $iBbCnt) + (($iAllW % $iBbCnt)? 1: 0);
425 $iBdCnt = floor(($iAllW + $iBdCntW) / $iBbCnt) + ((($iAllW+$iBdCntW) % $iBbCnt)? 1: 0);
426 if ($iBdCnt <= ($iBdExL*$iBbCnt+ $i1stBdL)) {
427 break;
428 }
429 }
430 }
431
432 // Making BD
433 // Set for SBD
434 if ($iSbdSize > 0) {
435 for ($i = 0; $i < ($iSbdSize - 1); $i++) {
436 fwrite($FILE, pack("V", $i+1));
437 }
438 fwrite($FILE, pack("V", -2));
439 }
440 // Set for B
441 for ($i = 0; $i < ($iBsize - 1); $i++) {
442 fwrite($FILE, pack("V", $i+$iSbdSize+1));
443 }
444 fwrite($FILE, pack("V", -2));
445
446 // Set for PPS
447 for ($i = 0; $i < ($iPpsCnt - 1); $i++) {
448 fwrite($FILE, pack("V", $i+$iSbdSize+$iBsize+1));
449 }
450 fwrite($FILE, pack("V", -2));
451 // Set for BBD itself ( 0xFFFFFFFD : BBD)
452 for ($i = 0; $i < $iBdCnt; $i++) {
453 fwrite($FILE, pack("V", 0xFFFFFFFD));
454 }
455 // Set for ExtraBDList
456 for ($i = 0; $i < $iBdExL; $i++) {
457 fwrite($FILE, pack("V", 0xFFFFFFFC));
458 }
459 // Adjust for Block
460 if (($iAllW + $iBdCnt) % $iBbCnt) {
461 for ($i = 0; $i < ($iBbCnt - (($iAllW + $iBdCnt) % $iBbCnt)); $i++) {
462 fwrite($FILE, pack("V", -1));
463 }
464 }
465 // Extra BDList
466 if ($iBdCnt > $i1stBdL) {
467 $iN=0;
468 $iNb=0;
469 for ($i = $i1stBdL;$i < $iBdCnt; $i++, $iN++) {
470 if ($iN >= ($iBbCnt - 1)) {
471 $iN = 0;
472 $iNb++;
473 fwrite($FILE, pack("V", $iAll+$iBdCnt+$iNb));
474 }
475 fwrite($FILE, pack("V", $iBsize+$iSbdSize+$iPpsCnt+$i));
476 }
477 if (($iBdCnt-$i1stBdL) % ($iBbCnt-1)) {
478 for ($i = 0; $i < (($iBbCnt - 1) - (($iBdCnt - $i1stBdL) % ($iBbCnt - 1))); $i++) {
479 fwrite($FILE, pack("V", -1));
480 }
481 }
482 fwrite($FILE, pack("V", -2));
483 }
484 }
485}
486?>
const OLE_PPS_TYPE_DIR
Definition: OLE.php:27
const OLE_PPS_SIZE
Definition: OLE.php:31
const OLE_PPS_TYPE_FILE
Definition: OLE.php:28
const OLE_LONG_INT_SIZE
Definition: OLE.php:30
const OLE_PPS_TYPE_ROOT
Constants for OLE package.
Definition: OLE.php:26
const OLE_DATA_SIZE_SMALL
Definition: OLE.php:29
$filename
Definition: buildRTE.php:89
_calcSize(&$raList)
Calculate some numbers.
Definition: Root.php:148
setTempDir($dir)
Sets the temp dir used for storing the OLE file.
Definition: Root.php:71
_savePps(&$raList)
Saves all the PPS's WKs.
Definition: Root.php:383
_saveHeader($iSBDcnt, $iBBcnt, $iPPScnt)
Save OLE header.
Definition: Root.php:200
_saveBbd($iSbdSize, $iBsize, $iPpsCnt)
Saving Big Block Depot.
Definition: Root.php:407
_adjust2($i2)
Helper function for caculating a magic value for block sizes.
Definition: Root.php:186
save($filename)
Method for saving the whole OLE container (including files).
Definition: Root.php:89
_makeSmallData(&$raList)
get small data (PPS's with data smaller than OLE_DATA_SIZE_SMALL)
Definition: Root.php:327
_saveBigData($iStBlk, &$raList)
Saving big data (PPS's with data bigger than OLE_DATA_SIZE_SMALL)
Definition: Root.php:277
OLE_PPS_Root($time_1st, $time_2nd, $raChild)
Constructor.
Definition: Root.php:48
Definition: PPS.php:34
_savePpsSetPnt(&$pps_array)
Updates index and pointers to previous, next and children PPS's for this PPS.
Definition: PPS.php:208
OLE_PPS($No, $name, $type, $prev, $next, $dir, $time_1st, $time_2nd, $data, $children)
The constructor.
Definition: PPS.php:128
_getPpsWk()
Returns a string with the PPS's WK (What is a WK?)
Definition: PPS.php:173
Asc2Ucs($ascii)
Utility function to transform ASCII text to Unicode.
Definition: OLE.php:473
& raiseError($message=null, $code=null, $mode=null, $options=null, $userinfo=null, $error_class=null, $skipmsg=false)
This method is a wrapper that returns an instance of the configured error class with this object's de...
Definition: PEAR.php:524
tmpdir()
Get the path of the temporal directory set in the system by looking in its environments variables.
Definition: System.php:454