~adamzammit/quexs/quexscativm

« back to all changes in this revision

Viewing changes to include/limesurvey/admin/classes/pear/OLE/PPS/Root.php

  • Committer: azammitdcarf
  • Date: 2008-10-15 04:55:53 UTC
  • Revision ID: svn-v4:fd4a0071-7450-0410-a91b-842f6942ebe7:trunk:6
Import from DCARF SVN

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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.7 2003/12/12 21:10:10 xnoguer Exp $
 
21
 
 
22
if (isset($_REQUEST['homedir'])) {die('You cannot start this script directly');}
 
23
require_once ($homedir.'/classes/pear/OLE/PPS.php');
 
24
 
 
25
/**
 
26
* Class for creating Root PPS's for OLE containers
 
27
*
 
28
* @author   Xavier Noguer <xnoguer@php.net>
 
29
* @category Structures
 
30
* @package  OLE
 
31
*/
 
32
class OLE_PPS_Root extends OLE_PPS
 
33
{
 
34
    /**
 
35
    * The temporary dir for storing the OLE file
 
36
    * @var string
 
37
    */
 
38
    var $_tmp_dir;
 
39
    
 
40
    /**
 
41
    * Constructor
 
42
    *
 
43
    * @access public
 
44
    * @param integer $time_1st A timestamp
 
45
    * @param integer $time_2nd A timestamp
 
46
    */
 
47
    function OLE_PPS_Root($time_1st, $time_2nd, $raChild)
 
48
    {
 
49
        $this->_tmp_dir = '';
 
50
        $this->OLE_PPS(
 
51
           null, 
 
52
           OLE::Asc2Ucs('Root Entry'),
 
53
           OLE_PPS_TYPE_ROOT,
 
54
           null,
 
55
           null,
 
56
           null,
 
57
           $time_1st,
 
58
           $time_2nd,
 
59
           null,
 
60
           $raChild);
 
61
    }
 
62
 
 
63
    /**
 
64
    * Sets the temp dir used for storing the OLE file
 
65
    *
 
66
    * @access public
 
67
    * @param string $dir The dir to be used as temp dir
 
68
    * @return true if given dir is valid, false otherwise
 
69
    */
 
70
    function setTempDir($dir)
 
71
    {
 
72
        if (is_dir($dir)) {
 
73
            $this->_tmp_dir = $dir;
 
74
            return true;
 
75
        }
 
76
        return false;
 
77
    }
 
78
 
 
79
    /**
 
80
    * Method for saving the whole OLE container (including files).
 
81
    * In fact, if called with an empty argument (or '-'), it saves to a
 
82
    * temporary file and then outputs it's contents to stdout.
 
83
    *
 
84
    * @param string $filename The name of the file where to save the OLE container
 
85
    * @access public
 
86
    * @return mixed true on success, PEAR_Error on failure
 
87
    */
 
88
    function save($filename)
 
89
    {
 
90
        // Initial Setting for saving
 
91
        $this->_BIG_BLOCK_SIZE  = pow(2,
 
92
                      ((isset($this->_BIG_BLOCK_SIZE))? $this->_adjust2($this->_BIG_BLOCK_SIZE)  : 9));
 
93
        $this->_SMALL_BLOCK_SIZE= pow(2, 
 
94
                      ((isset($this->_SMALL_BLOCK_SIZE))?  $this->_adjust2($this->_SMALL_BLOCK_SIZE): 6));
 
95
 
 
96
        // Open temp file if we are sending output to stdout
 
97
        if (($filename == '-') or ($filename == ''))
 
98
        {
 
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
        }
 
105
        else
 
106
        {
 
107
            $this->_FILEH_ = @fopen($filename, "wb");
 
108
            if ($this->_FILEH_ == false) {
 
109
                return $this->raiseError("Can't open $filename. It may be in use or protected.");
 
110
            }
 
111
        }
 
112
        // Make an array of PPS's (for Save)
 
113
        $aList = array();
 
114
        $this->_savePpsSetPnt($aList);
 
115
        // calculate values for header
 
116
        list($iSBDcnt, $iBBcnt, $iPPScnt) = $this->_calcSize($aList); //, $rhInfo);
 
117
        // Save Header
 
118
        $this->_saveHeader($iSBDcnt, $iBBcnt, $iPPScnt);
 
119
  
 
120
        // Make Small Data string (write SBD)
 
121
        $this->_data = $this->_makeSmallData($aList);
 
122
  
 
123
        // Write BB
 
124
        $this->_saveBigData($iSBDcnt, $aList);
 
125
        // Write PPS
 
126
        $this->_savePps($aList);
 
127
        // Write Big Block Depot and BDList and Adding Header informations
 
128
        $this->_saveBbd($iSBDcnt, $iBBcnt, $iPPScnt);
 
129
        // Close File, send it to stdout if necessary
 
130
        if(($filename == '-') or ($filename == ''))
 
131
        {
 
132
            fseek($this->_FILEH_, 0);
 
133
            fpassthru($this->_FILEH_);
 
134
            @fclose($this->_FILEH_);
 
135
            // Delete the temporary file.
 
136
            @unlink($this->_tmp_filename);
 
137
        }
 
138
        else {
 
139
            @fclose($this->_FILEH_);
 
140
        }
 
141
        return true;
 
142
    }
 
143
 
 
144
    /**
 
145
    * Calculate some numbers
 
146
    *
 
147
    * @access private
 
148
    * @param array $raList Reference to an array of PPS's
 
149
    * @return array The array of numbers
 
150
    */
 
151
    function _calcSize(&$raList) 
 
152
    {
 
153
        // Calculate Basic Setting
 
154
        list($iSBDcnt, $iBBcnt, $iPPScnt) = array(0,0,0);
 
155
        $iSmallLen = 0;
 
156
        $iSBcnt = 0;
 
157
        for ($i = 0; $i < count($raList); $i++) {
 
158
            if($raList[$i]->Type == OLE_PPS_TYPE_FILE) {
 
159
                $raList[$i]->Size = $raList[$i]->_DataLen();
 
160
                if($raList[$i]->Size < OLE_DATA_SIZE_SMALL) {
 
161
                    $iSBcnt += floor($raList[$i]->Size / $this->_SMALL_BLOCK_SIZE)
 
162
                                  + (($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)? 1: 0);
 
163
                }
 
164
                else {
 
165
                    $iBBcnt += (floor($raList[$i]->Size / $this->_BIG_BLOCK_SIZE) +
 
166
                        (($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)? 1: 0));
 
167
                }
 
168
            }
 
169
        }
 
170
        $iSmallLen = $iSBcnt * $this->_SMALL_BLOCK_SIZE;
 
171
        $iSlCnt = floor($this->_BIG_BLOCK_SIZE / OLE_LONG_INT_SIZE);
 
172
        $iSBDcnt = floor($iSBcnt / $iSlCnt) + (($iSBcnt % $iSlCnt)? 1:0);
 
173
        $iBBcnt +=  (floor($iSmallLen / $this->_BIG_BLOCK_SIZE) +
 
174
                      (( $iSmallLen % $this->_BIG_BLOCK_SIZE)? 1: 0));
 
175
        $iCnt = count($raList);
 
176
        $iBdCnt = $this->_BIG_BLOCK_SIZE / OLE_PPS_SIZE;
 
177
        $iPPScnt = (floor($iCnt/$iBdCnt) + (($iCnt % $iBdCnt)? 1: 0));
 
178
   
 
179
        return array($iSBDcnt, $iBBcnt, $iPPScnt);
 
180
    }
 
181
 
 
182
    /**
 
183
    * Helper function for caculating a magic value for block sizes
 
184
    *
 
185
    * @access private
 
186
    * @param integer $i2 The argument
 
187
    * @see save()
 
188
    * @return integer
 
189
    */
 
190
    function _adjust2($i2)
 
191
    {
 
192
        $iWk = log($i2)/log(2);
 
193
        return ($iWk > floor($iWk))? floor($iWk)+1:$iWk;
 
194
    }
 
195
 
 
196
    /**
 
197
    * Save OLE header
 
198
    *
 
199
    * @access private
 
200
    * @param integer $iSBDcnt
 
201
    * @param integer $iBBcnt
 
202
    * @param integer $iPPScnt
 
203
    */
 
204
    function _saveHeader($iSBDcnt, $iBBcnt, $iPPScnt)
 
205
    {
 
206
        $FILE = $this->_FILEH_;
 
207
  
 
208
        // Calculate Basic Setting
 
209
        $iBlCnt = $this->_BIG_BLOCK_SIZE / OLE_LONG_INT_SIZE;
 
210
        $i1stBdL = ($this->_BIG_BLOCK_SIZE - 0x4C) / OLE_LONG_INT_SIZE;
 
211
  
 
212
        $iBdExL = 0;
 
213
        $iAll = $iBBcnt + $iPPScnt + $iSBDcnt;
 
214
        $iAllW = $iAll;
 
215
        $iBdCntW = floor($iAllW / $iBlCnt) + (($iAllW % $iBlCnt)? 1: 0);
 
216
        $iBdCnt = floor(($iAll + $iBdCntW) / $iBlCnt) + ((($iAllW+$iBdCntW) % $iBlCnt)? 1: 0);
 
217
  
 
218
        // Calculate BD count
 
219
        if ($iBdCnt >$i1stBdL)
 
220
        {
 
221
            while (1)
 
222
            {
 
223
                $iBdExL++;
 
224
                $iAllW++;
 
225
                $iBdCntW = floor($iAllW / $iBlCnt) + (($iAllW % $iBlCnt)? 1: 0);
 
226
                $iBdCnt = floor(($iAllW + $iBdCntW) / $iBlCnt) + ((($iAllW+$iBdCntW) % $iBlCnt)? 1: 0);
 
227
                if ($iBdCnt <= ($iBdExL*$iBlCnt+ $i1stBdL)) {
 
228
                    break;
 
229
                }
 
230
            }
 
231
        }
 
232
  
 
233
        // Save Header
 
234
        fwrite($FILE,
 
235
                  "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1"
 
236
                  . "\x00\x00\x00\x00"
 
237
                  . "\x00\x00\x00\x00"
 
238
                  . "\x00\x00\x00\x00"
 
239
                  . "\x00\x00\x00\x00"
 
240
                  . pack("v", 0x3b)
 
241
                  . pack("v", 0x03)
 
242
                  . pack("v", -2)
 
243
                  . pack("v", 9)
 
244
                  . pack("v", 6)
 
245
                  . pack("v", 0)
 
246
                  . "\x00\x00\x00\x00"
 
247
                  . "\x00\x00\x00\x00"
 
248
                  . pack("V", $iBdCnt) 
 
249
                  . pack("V", $iBBcnt+$iSBDcnt) //ROOT START
 
250
                  . pack("V", 0)
 
251
                  . pack("V", 0x1000)
 
252
                  . pack("V", 0)                  //Small Block Depot
 
253
                  . pack("V", 1)
 
254
          );
 
255
        // Extra BDList Start, Count
 
256
        if ($iBdCnt < $i1stBdL)
 
257
        {
 
258
            fwrite($FILE,
 
259
                      pack("V", -2).      // Extra BDList Start
 
260
                      pack("V", 0)        // Extra BDList Count
 
261
                  );
 
262
        }
 
263
        else
 
264
        {
 
265
            fwrite($FILE, pack("V", $iAll+$iBdCnt) . pack("V", $iBdExL));
 
266
        }
 
267
 
 
268
        // BDList
 
269
        for ($i=0; $i<$i1stBdL and $i < $iBdCnt; $i++) {
 
270
            fwrite($FILE, pack("V", $iAll+$i));
 
271
        }
 
272
        if ($i < $i1stBdL)
 
273
        {
 
274
            for ($j = 0; $j < ($i1stBdL-$i); $j++) {
 
275
                fwrite($FILE, (pack("V", -1)));
 
276
            }
 
277
        }
 
278
    }
 
279
 
 
280
    /**
 
281
    * Saving big data (PPS's with data bigger than OLE_DATA_SIZE_SMALL)
 
282
    *
 
283
    * @access private
 
284
    * @param integer $iStBlk
 
285
    * @param array &$raList Reference to array of PPS's
 
286
    */
 
287
    function _saveBigData($iStBlk, &$raList)
 
288
    {
 
289
        $FILE = $this->_FILEH_;
 
290
   
 
291
        // cycle through PPS's
 
292
        for ($i = 0; $i < count($raList); $i++)
 
293
        {
 
294
            if($raList[$i]->Type != OLE_PPS_TYPE_DIR)
 
295
            {
 
296
                $raList[$i]->Size = $raList[$i]->_DataLen();
 
297
                if(($raList[$i]->Size >= OLE_DATA_SIZE_SMALL) or
 
298
                    (($raList[$i]->Type == OLE_PPS_TYPE_ROOT) and isset($raList[$i]->_data)))
 
299
                {
 
300
                    // Write Data
 
301
                    if(isset($raList[$i]->_PPS_FILE))
 
302
                    {
 
303
                        $iLen = 0;
 
304
                        fseek($raList[$i]->_PPS_FILE, 0); // To The Top
 
305
                        while($sBuff = fread($raList[$i]->_PPS_FILE, 4096))
 
306
                        {
 
307
                            $iLen += strlen($sBuff);
 
308
                            fwrite($FILE, $sBuff);
 
309
                        }
 
310
                    }
 
311
                    else {
 
312
                        fwrite($FILE, $raList[$i]->_data);
 
313
                    }
 
314
           
 
315
                    if ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)
 
316
                    {
 
317
                        for ($j = 0; $j < ($this->_BIG_BLOCK_SIZE - ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)); $j++) {
 
318
                            fwrite($FILE, "\x00");
 
319
                        }
 
320
                    }
 
321
                    // Set For PPS
 
322
                    $raList[$i]->_StartBlock = $iStBlk;
 
323
                    $iStBlk += 
 
324
                            (floor($raList[$i]->Size / $this->_BIG_BLOCK_SIZE) +
 
325
                                (($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)? 1: 0));
 
326
                }
 
327
                // Close file for each PPS, and unlink it
 
328
                if (isset($raList[$i]->_PPS_FILE))
 
329
                {
 
330
                    @fclose($raList[$i]->_PPS_FILE);
 
331
                    $raList[$i]->_PPS_FILE = null;
 
332
                    @unlink($raList[$i]->_tmp_filename);
 
333
                }
 
334
            }
 
335
        }
 
336
    }
 
337
 
 
338
    /**
 
339
    * get small data (PPS's with data smaller than OLE_DATA_SIZE_SMALL)
 
340
    *
 
341
    * @access private
 
342
    * @param array &$raList Reference to array of PPS's
 
343
    */
 
344
    function _makeSmallData(&$raList)
 
345
    {
 
346
        $sRes = '';
 
347
        $FILE = $this->_FILEH_;
 
348
        $iSmBlk = 0;
 
349
   
 
350
        for ($i = 0; $i < count($raList); $i++)
 
351
        {
 
352
            // Make SBD, small data string
 
353
            if ($raList[$i]->Type == OLE_PPS_TYPE_FILE)
 
354
            {
 
355
                if ($raList[$i]->Size <= 0) {
 
356
                    continue;
 
357
                }
 
358
                if ($raList[$i]->Size < OLE_DATA_SIZE_SMALL)
 
359
                {
 
360
                    $iSmbCnt = floor($raList[$i]->Size / $this->_SMALL_BLOCK_SIZE)
 
361
                                  + (($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)? 1: 0);
 
362
                    // Add to SBD
 
363
                    for ($j = 0; $j < ($iSmbCnt-1); $j++) {
 
364
                        fwrite($FILE, pack("V", $j+$iSmBlk+1));
 
365
                    }
 
366
                    fwrite($FILE, pack("V", -2));
 
367
                   
 
368
                    // Add to Data String(this will be written for RootEntry)
 
369
                    if ($raList[$i]->_PPS_FILE)
 
370
                    {
 
371
                        fseek($raList[$i]->_PPS_FILE, 0); // To The Top
 
372
                        while ($sBuff = fread($raList[$i]->_PPS_FILE, 4096)) {
 
373
                            $sRes .= $sBuff;
 
374
                        }
 
375
                    }
 
376
                    else {
 
377
                        $sRes .= $raList[$i]->_data;
 
378
                    }
 
379
                    if($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)
 
380
                    {
 
381
                        for ($j = 0; $j < ($this->_SMALL_BLOCK_SIZE - ($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)); $j++) {
 
382
                            $sRes .= "\x00";
 
383
                        }
 
384
                    }
 
385
                    // Set for PPS
 
386
                    $raList[$i]->_StartBlock = $iSmBlk;
 
387
                    $iSmBlk += $iSmbCnt;
 
388
                }
 
389
            }
 
390
        }
 
391
        $iSbCnt = floor($this->_BIG_BLOCK_SIZE / OLE_LONG_INT_SIZE);
 
392
        if($iSmBlk % $iSbCnt)
 
393
        {
 
394
            for ($i = 0; $i < ($iSbCnt - ($iSmBlk % $iSbCnt)); $i++) {
 
395
                fwrite($FILE, pack("V", -1));
 
396
            }
 
397
        }
 
398
        return $sRes;
 
399
    }
 
400
 
 
401
    /**
 
402
    * Saves all the PPS's WKs
 
403
    *
 
404
    * @access private
 
405
    * @param array $raList Reference to an array with all PPS's
 
406
    */
 
407
    function _savePps(&$raList) 
 
408
    {
 
409
        // Save each PPS WK
 
410
        for ($i = 0; $i < count($raList); $i++) {
 
411
            fwrite($this->_FILEH_, $raList[$i]->_getPpsWk());
 
412
        }
 
413
        // Adjust for Block
 
414
        $iCnt = count($raList);
 
415
        $iBCnt = $this->_BIG_BLOCK_SIZE / OLE_PPS_SIZE;
 
416
        if ($iCnt % $iBCnt)
 
417
        {
 
418
            for ($i = 0; $i < (($iBCnt - ($iCnt % $iBCnt)) * OLE_PPS_SIZE); $i++) {
 
419
                fwrite($this->_FILEH_, "\x00");
 
420
            }
 
421
        }
 
422
    }
 
423
 
 
424
    /**
 
425
    * Saving Big Block Depot
 
426
    *
 
427
    * @access private
 
428
    * @param integer $iSbdSize
 
429
    * @param integer $iBsize
 
430
    * @param integer $iPpsCnt
 
431
    */
 
432
    function _saveBbd($iSbdSize, $iBsize, $iPpsCnt) 
 
433
    {
 
434
        $FILE = $this->_FILEH_;
 
435
        // Calculate Basic Setting
 
436
        $iBbCnt = $this->_BIG_BLOCK_SIZE / OLE_LONG_INT_SIZE;
 
437
        $i1stBdL = ($this->_BIG_BLOCK_SIZE - 0x4C) / OLE_LONG_INT_SIZE;
 
438
      
 
439
        $iBdExL = 0;
 
440
        $iAll = $iBsize + $iPpsCnt + $iSbdSize;
 
441
        $iAllW = $iAll;
 
442
        $iBdCntW = floor($iAllW / $iBbCnt) + (($iAllW % $iBbCnt)? 1: 0);
 
443
        $iBdCnt = floor(($iAll + $iBdCntW) / $iBbCnt) + ((($iAllW+$iBdCntW) % $iBbCnt)? 1: 0);
 
444
        // Calculate BD count
 
445
        if ($iBdCnt >$i1stBdL)
 
446
        {
 
447
            while (1)
 
448
            {
 
449
                $iBdExL++;
 
450
                $iAllW++;
 
451
                $iBdCntW = floor($iAllW / $iBbCnt) + (($iAllW % $iBbCnt)? 1: 0);
 
452
                $iBdCnt = floor(($iAllW + $iBdCntW) / $iBbCnt) + ((($iAllW+$iBdCntW) % $iBbCnt)? 1: 0);
 
453
                if ($iBdCnt <= ($iBdExL*$iBbCnt+ $i1stBdL)) {
 
454
                    break;
 
455
                }
 
456
            }
 
457
        }
 
458
      
 
459
        // Making BD
 
460
        // Set for SBD
 
461
        if ($iSbdSize > 0)
 
462
        {
 
463
            for ($i = 0; $i<($iSbdSize-1); $i++) {
 
464
                fwrite($FILE, pack("V", $i+1));
 
465
            }
 
466
            fwrite($FILE, pack("V", -2));
 
467
        }
 
468
        // Set for B
 
469
        for ($i = 0; $i<($iBsize-1); $i++) {
 
470
            fwrite($FILE, pack("V", $i+$iSbdSize+1));
 
471
        }
 
472
        fwrite($FILE, pack("V", -2));
 
473
      
 
474
        // Set for PPS
 
475
        for ($i = 0; $i<($iPpsCnt-1); $i++) {
 
476
            fwrite($FILE, pack("V", $i+$iSbdSize+$iBsize+1));
 
477
        }
 
478
        fwrite($FILE, pack("V", -2));
 
479
        // Set for BBD itself ( 0xFFFFFFFD : BBD)
 
480
        for ($i=0; $i<$iBdCnt;$i++) {
 
481
            fwrite($FILE, pack("V", 0xFFFFFFFD));
 
482
        }
 
483
        // Set for ExtraBDList
 
484
        for ($i=0; $i<$iBdExL;$i++) {
 
485
            fwrite($FILE, pack("V", 0xFFFFFFFC));
 
486
        }
 
487
        // Adjust for Block
 
488
        if (($iAllW + $iBdCnt) % $iBbCnt)
 
489
        {
 
490
            for ($i = 0; $i < ($iBbCnt - (($iAllW + $iBdCnt) % $iBbCnt)); $i++) {
 
491
                fwrite($FILE, pack("V", -1));
 
492
            }
 
493
        }
 
494
        // Extra BDList
 
495
        if ($iBdCnt > $i1stBdL)
 
496
        {
 
497
            $iN=0;
 
498
            $iNb=0;
 
499
            for ($i=$i1stBdL;$i<$iBdCnt; $i++, $iN++)
 
500
            {
 
501
                if ($iN>=($iBbCnt-1))
 
502
                {
 
503
                    $iN = 0;
 
504
                    $iNb++;
 
505
                    fwrite($FILE, pack("V", $iAll+$iBdCnt+$iNb));
 
506
                }
 
507
                fwrite($FILE, pack("V", $iBsize+$iSbdSize+$iPpsCnt+$i));
 
508
            }
 
509
            if (($iBdCnt-$i1stBdL) % ($iBbCnt-1))
 
510
            {
 
511
                for ($i = 0; $i < (($iBbCnt-1) - (($iBdCnt-$i1stBdL) % ($iBbCnt-1))); $i++) {
 
512
                    fwrite($FILE, pack("V", -1)); 
 
513
                }
 
514
            }
 
515
            fwrite($FILE, pack("V", -2));
 
516
        }
 
517
    }
 
518
}
 
519
?>