• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

classes/OLE/PPS/Root.php

Go to the documentation of this file.
00001 <?php
00002 /* vim: set expandtab tabstop=4 shiftwidth=4: */
00003 // +----------------------------------------------------------------------+
00004 // | PHP Version 4                                                        |
00005 // +----------------------------------------------------------------------+
00006 // | Copyright (c) 1997-2002 The PHP Group                                |
00007 // +----------------------------------------------------------------------+
00008 // | This source file is subject to version 2.02 of the PHP license,      |
00009 // | that is bundled with this package in the file LICENSE, and is        |
00010 // | available at through the world-wide-web at                           |
00011 // | http://www.php.net/license/2_02.txt.                                 |
00012 // | If you did not receive a copy of the PHP license and are unable to   |
00013 // | obtain it through the world-wide-web, please send a note to          |
00014 // | license@php.net so we can mail you a copy immediately.               |
00015 // +----------------------------------------------------------------------+
00016 // | Author: Xavier Noguer <xnoguer@php.net>                              |
00017 // | Based on OLE::Storage_Lite by Kawai, Takanori                        |
00018 // +----------------------------------------------------------------------+
00019 //
00020 // $Id: Root.php 4249 2004-06-16 14:14:02Z hschottm $
00021 
00022 
00023 require_once ('classes/OLE/PPS.php');
00024 
00032 class OLE_PPS_Root extends OLE_PPS
00033 {
00038     var $_tmp_dir;
00039     
00047     function OLE_PPS_Root($time_1st, $time_2nd, $raChild)
00048     {
00049         $this->_tmp_dir = '';
00050         $this->OLE_PPS(
00051            null, 
00052            OLE::Asc2Ucs('Root Entry'),
00053            OLE_PPS_TYPE_ROOT,
00054            null,
00055            null,
00056            null,
00057            $time_1st,
00058            $time_2nd,
00059            null,
00060            $raChild);
00061     }
00062 
00070     function setTempDir($dir)
00071     {
00072         if (is_dir($dir)) {
00073             $this->_tmp_dir = $dir;
00074             return true;
00075         }
00076         return false;
00077     }
00078 
00088     function save($filename)
00089     {
00090         // Initial Setting for saving
00091         $this->_BIG_BLOCK_SIZE  = pow(2,
00092                       ((isset($this->_BIG_BLOCK_SIZE))? $this->_adjust2($this->_BIG_BLOCK_SIZE)  : 9));
00093         $this->_SMALL_BLOCK_SIZE= pow(2, 
00094                       ((isset($this->_SMALL_BLOCK_SIZE))?  $this->_adjust2($this->_SMALL_BLOCK_SIZE): 6));
00095  
00096         // Open temp file if we are sending output to stdout
00097         if (($filename == '-') or ($filename == ''))
00098         {
00099             $this->_tmp_filename = tempnam($this->_tmp_dir, "OLE_PPS_Root");
00100             $this->_FILEH_ = @fopen($this->_tmp_filename,"w+b");
00101             if ($this->_FILEH_ == false) {
00102                 return $this->raiseError("Can't create temporary file.");
00103             }
00104         }
00105         else
00106         {
00107             $this->_FILEH_ = @fopen($filename, "wb");
00108             if ($this->_FILEH_ == false) {
00109                 return $this->raiseError("Can't open $filename. It may be in use or protected.");
00110             }
00111         }
00112         // Make an array of PPS's (for Save)
00113         $aList = array();
00114         $this->_savePpsSetPnt($aList);
00115         // calculate values for header
00116         list($iSBDcnt, $iBBcnt, $iPPScnt) = $this->_calcSize($aList); //, $rhInfo);
00117         // Save Header
00118         $this->_saveHeader($iSBDcnt, $iBBcnt, $iPPScnt);
00119   
00120         // Make Small Data string (write SBD)
00121         $this->_data = $this->_makeSmallData($aList);
00122   
00123         // Write BB
00124         $this->_saveBigData($iSBDcnt, $aList);
00125         // Write PPS
00126         $this->_savePps($aList);
00127         // Write Big Block Depot and BDList and Adding Header informations
00128         $this->_saveBbd($iSBDcnt, $iBBcnt, $iPPScnt);
00129         // Close File, send it to stdout if necessary
00130         if(($filename == '-') or ($filename == ''))
00131         {
00132             fseek($this->_FILEH_, 0);
00133             fpassthru($this->_FILEH_);
00134             @fclose($this->_FILEH_);
00135             // Delete the temporary file.
00136             @unlink($this->_tmp_filename);
00137         }
00138         else {
00139             @fclose($this->_FILEH_);
00140         }
00141         return true;
00142     }
00143 
00151     function _calcSize(&$raList) 
00152     {
00153         // Calculate Basic Setting
00154         list($iSBDcnt, $iBBcnt, $iPPScnt) = array(0,0,0);
00155         $iSmallLen = 0;
00156         $iSBcnt = 0;
00157         for ($i = 0; $i < count($raList); $i++) {
00158             if($raList[$i]->Type == OLE_PPS_TYPE_FILE) {
00159                 $raList[$i]->Size = $raList[$i]->_DataLen();
00160                 if($raList[$i]->Size < OLE_DATA_SIZE_SMALL) {
00161                     $iSBcnt += floor($raList[$i]->Size / $this->_SMALL_BLOCK_SIZE)
00162                                   + (($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)? 1: 0);
00163                 }
00164                 else {
00165                     $iBBcnt += (floor($raList[$i]->Size / $this->_BIG_BLOCK_SIZE) +
00166                         (($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)? 1: 0));
00167                 }
00168             }
00169         }
00170         $iSmallLen = $iSBcnt * $this->_SMALL_BLOCK_SIZE;
00171         $iSlCnt = floor($this->_BIG_BLOCK_SIZE / OLE_LONG_INT_SIZE);
00172         $iSBDcnt = floor($iSBcnt / $iSlCnt) + (($iSBcnt % $iSlCnt)? 1:0);
00173         $iBBcnt +=  (floor($iSmallLen / $this->_BIG_BLOCK_SIZE) +
00174                       (( $iSmallLen % $this->_BIG_BLOCK_SIZE)? 1: 0));
00175         $iCnt = count($raList);
00176         $iBdCnt = $this->_BIG_BLOCK_SIZE / OLE_PPS_SIZE;
00177         $iPPScnt = (floor($iCnt/$iBdCnt) + (($iCnt % $iBdCnt)? 1: 0));
00178    
00179         return array($iSBDcnt, $iBBcnt, $iPPScnt);
00180     }
00181 
00190     function _adjust2($i2)
00191     {
00192         $iWk = log($i2)/log(2);
00193         return ($iWk > floor($iWk))? floor($iWk)+1:$iWk;
00194     }
00195 
00204     function _saveHeader($iSBDcnt, $iBBcnt, $iPPScnt)
00205     {
00206         $FILE = $this->_FILEH_;
00207   
00208         // Calculate Basic Setting
00209         $iBlCnt = $this->_BIG_BLOCK_SIZE / OLE_LONG_INT_SIZE;
00210         $i1stBdL = ($this->_BIG_BLOCK_SIZE - 0x4C) / OLE_LONG_INT_SIZE;
00211   
00212         $iBdExL = 0;
00213         $iAll = $iBBcnt + $iPPScnt + $iSBDcnt;
00214         $iAllW = $iAll;
00215         $iBdCntW = floor($iAllW / $iBlCnt) + (($iAllW % $iBlCnt)? 1: 0);
00216         $iBdCnt = floor(($iAll + $iBdCntW) / $iBlCnt) + ((($iAllW+$iBdCntW) % $iBlCnt)? 1: 0);
00217   
00218         // Calculate BD count
00219         if ($iBdCnt >$i1stBdL)
00220         {
00221             while (1)
00222             {
00223                 $iBdExL++;
00224                 $iAllW++;
00225                 $iBdCntW = floor($iAllW / $iBlCnt) + (($iAllW % $iBlCnt)? 1: 0);
00226                 $iBdCnt = floor(($iAllW + $iBdCntW) / $iBlCnt) + ((($iAllW+$iBdCntW) % $iBlCnt)? 1: 0);
00227                 if ($iBdCnt <= ($iBdExL*$iBlCnt+ $i1stBdL)) {
00228                     break;
00229                 }
00230             }
00231         }
00232   
00233         // Save Header
00234         fwrite($FILE,
00235                   "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1"
00236                   . "\x00\x00\x00\x00"
00237                   . "\x00\x00\x00\x00"
00238                   . "\x00\x00\x00\x00"
00239                   . "\x00\x00\x00\x00"
00240                   . pack("v", 0x3b)
00241                   . pack("v", 0x03)
00242                   . pack("v", -2)
00243                   . pack("v", 9)
00244                   . pack("v", 6)
00245                   . pack("v", 0)
00246                   . "\x00\x00\x00\x00"
00247                   . "\x00\x00\x00\x00"
00248                   . pack("V", $iBdCnt) 
00249                   . pack("V", $iBBcnt+$iSBDcnt) //ROOT START
00250                   . pack("V", 0)
00251                   . pack("V", 0x1000)
00252                   . pack("V", 0)                  //Small Block Depot
00253                   . pack("V", 1)
00254           );
00255         // Extra BDList Start, Count
00256         if ($iBdCnt < $i1stBdL)
00257         {
00258             fwrite($FILE,
00259                       pack("V", -2).      // Extra BDList Start
00260                       pack("V", 0)        // Extra BDList Count
00261                   );
00262         }
00263         else
00264         {
00265             fwrite($FILE, pack("V", $iAll+$iBdCnt) . pack("V", $iBdExL));
00266         }
00267 
00268         // BDList
00269         for ($i=0; $i<$i1stBdL and $i < $iBdCnt; $i++) {
00270             fwrite($FILE, pack("V", $iAll+$i));
00271         }
00272         if ($i < $i1stBdL)
00273         {
00274             for ($j = 0; $j < ($i1stBdL-$i); $j++) {
00275                 fwrite($FILE, (pack("V", -1)));
00276             }
00277         }
00278     }
00279 
00287     function _saveBigData($iStBlk, &$raList)
00288     {
00289         $FILE = $this->_FILEH_;
00290    
00291         // cycle through PPS's
00292         for ($i = 0; $i < count($raList); $i++)
00293         {
00294             if($raList[$i]->Type != OLE_PPS_TYPE_DIR)
00295             {
00296                 $raList[$i]->Size = $raList[$i]->_DataLen();
00297                 if(($raList[$i]->Size >= OLE_DATA_SIZE_SMALL) or
00298                     (($raList[$i]->Type == OLE_PPS_TYPE_ROOT) and isset($raList[$i]->_data)))
00299                 {
00300                     // Write Data
00301                     if(isset($raList[$i]->_PPS_FILE))
00302                     {
00303                         $iLen = 0;
00304                         fseek($raList[$i]->_PPS_FILE, 0); // To The Top
00305                         while($sBuff = fread($raList[$i]->_PPS_FILE, 4096))
00306                         {
00307                             $iLen += strlen($sBuff);
00308                             fwrite($FILE, $sBuff);
00309                         }
00310                     }
00311                     else {
00312                         fwrite($FILE, $raList[$i]->_data);
00313                     }
00314            
00315                     if ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)
00316                     {
00317                         for ($j = 0; $j < ($this->_BIG_BLOCK_SIZE - ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)); $j++) {
00318                             fwrite($FILE, "\x00");
00319                         }
00320                     }
00321                     // Set For PPS
00322                     $raList[$i]->_StartBlock = $iStBlk;
00323                     $iStBlk += 
00324                             (floor($raList[$i]->Size / $this->_BIG_BLOCK_SIZE) +
00325                                 (($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)? 1: 0));
00326                 }
00327                 // Close file for each PPS, and unlink it
00328                 if (isset($raList[$i]->_PPS_FILE))
00329                 {
00330                     @fclose($raList[$i]->_PPS_FILE);
00331                     $raList[$i]->_PPS_FILE = null;
00332                     @unlink($raList[$i]->_tmp_filename);
00333                 }
00334             }
00335         }
00336     }
00337 
00344     function _makeSmallData(&$raList)
00345     {
00346         $sRes = '';
00347         $FILE = $this->_FILEH_;
00348         $iSmBlk = 0;
00349    
00350         for ($i = 0; $i < count($raList); $i++)
00351         {
00352             // Make SBD, small data string
00353             if ($raList[$i]->Type == OLE_PPS_TYPE_FILE)
00354             {
00355                 if ($raList[$i]->Size <= 0) {
00356                     continue;
00357                 }
00358                 if ($raList[$i]->Size < OLE_DATA_SIZE_SMALL)
00359                 {
00360                     $iSmbCnt = floor($raList[$i]->Size / $this->_SMALL_BLOCK_SIZE)
00361                                   + (($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)? 1: 0);
00362                     // Add to SBD
00363                     for ($j = 0; $j < ($iSmbCnt-1); $j++) {
00364                         fwrite($FILE, pack("V", $j+$iSmBlk+1));
00365                     }
00366                     fwrite($FILE, pack("V", -2));
00367                    
00368                     // Add to Data String(this will be written for RootEntry)
00369                     if ($raList[$i]->_PPS_FILE)
00370                     {
00371                         fseek($raList[$i]->_PPS_FILE, 0); // To The Top
00372                         while ($sBuff = fread($raList[$i]->_PPS_FILE, 4096)) {
00373                             $sRes .= $sBuff;
00374                         }
00375                     }
00376                     else {
00377                         $sRes .= $raList[$i]->_data;
00378                     }
00379                     if($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)
00380                     {
00381                         for ($j = 0; $j < ($this->_SMALL_BLOCK_SIZE - ($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)); $j++) {
00382                             $sRes .= "\x00";
00383                         }
00384                     }
00385                     // Set for PPS
00386                     $raList[$i]->_StartBlock = $iSmBlk;
00387                     $iSmBlk += $iSmbCnt;
00388                 }
00389             }
00390         }
00391         $iSbCnt = floor($this->_BIG_BLOCK_SIZE / OLE_LONG_INT_SIZE);
00392         if($iSmBlk % $iSbCnt)
00393         {
00394             for ($i = 0; $i < ($iSbCnt - ($iSmBlk % $iSbCnt)); $i++) {
00395                 fwrite($FILE, pack("V", -1));
00396             }
00397         }
00398         return $sRes;
00399     }
00400 
00407     function _savePps(&$raList) 
00408     {
00409         // Save each PPS WK
00410         for ($i = 0; $i < count($raList); $i++) {
00411             fwrite($this->_FILEH_, $raList[$i]->_getPpsWk());
00412         }
00413         // Adjust for Block
00414         $iCnt = count($raList);
00415         $iBCnt = $this->_BIG_BLOCK_SIZE / OLE_PPS_SIZE;
00416         if ($iCnt % $iBCnt)
00417         {
00418             for ($i = 0; $i < (($iBCnt - ($iCnt % $iBCnt)) * OLE_PPS_SIZE); $i++) {
00419                 fwrite($this->_FILEH_, "\x00");
00420             }
00421         }
00422     }
00423 
00432     function _saveBbd($iSbdSize, $iBsize, $iPpsCnt) 
00433     {
00434         $FILE = $this->_FILEH_;
00435         // Calculate Basic Setting
00436         $iBbCnt = $this->_BIG_BLOCK_SIZE / OLE_LONG_INT_SIZE;
00437         $i1stBdL = ($this->_BIG_BLOCK_SIZE - 0x4C) / OLE_LONG_INT_SIZE;
00438       
00439         $iBdExL = 0;
00440         $iAll = $iBsize + $iPpsCnt + $iSbdSize;
00441         $iAllW = $iAll;
00442         $iBdCntW = floor($iAllW / $iBbCnt) + (($iAllW % $iBbCnt)? 1: 0);
00443         $iBdCnt = floor(($iAll + $iBdCntW) / $iBbCnt) + ((($iAllW+$iBdCntW) % $iBbCnt)? 1: 0);
00444         // Calculate BD count
00445         if ($iBdCnt >$i1stBdL)
00446         {
00447             while (1)
00448             {
00449                 $iBdExL++;
00450                 $iAllW++;
00451                 $iBdCntW = floor($iAllW / $iBbCnt) + (($iAllW % $iBbCnt)? 1: 0);
00452                 $iBdCnt = floor(($iAllW + $iBdCntW) / $iBbCnt) + ((($iAllW+$iBdCntW) % $iBbCnt)? 1: 0);
00453                 if ($iBdCnt <= ($iBdExL*$iBbCnt+ $i1stBdL)) {
00454                     break;
00455                 }
00456             }
00457         }
00458       
00459         // Making BD
00460         // Set for SBD
00461         if ($iSbdSize > 0)
00462         {
00463             for ($i = 0; $i<($iSbdSize-1); $i++) {
00464                 fwrite($FILE, pack("V", $i+1));
00465             }
00466             fwrite($FILE, pack("V", -2));
00467         }
00468         // Set for B
00469         for ($i = 0; $i<($iBsize-1); $i++) {
00470             fwrite($FILE, pack("V", $i+$iSbdSize+1));
00471         }
00472         fwrite($FILE, pack("V", -2));
00473       
00474         // Set for PPS
00475         for ($i = 0; $i<($iPpsCnt-1); $i++) {
00476             fwrite($FILE, pack("V", $i+$iSbdSize+$iBsize+1));
00477         }
00478         fwrite($FILE, pack("V", -2));
00479         // Set for BBD itself ( 0xFFFFFFFD : BBD)
00480         for ($i=0; $i<$iBdCnt;$i++) {
00481             fwrite($FILE, pack("V", 0xFFFFFFFD));
00482         }
00483         // Set for ExtraBDList
00484         for ($i=0; $i<$iBdExL;$i++) {
00485             fwrite($FILE, pack("V", 0xFFFFFFFC));
00486         }
00487         // Adjust for Block
00488         if (($iAllW + $iBdCnt) % $iBbCnt)
00489         {
00490             for ($i = 0; $i < ($iBbCnt - (($iAllW + $iBdCnt) % $iBbCnt)); $i++) {
00491                 fwrite($FILE, pack("V", -1));
00492             }
00493         }
00494         // Extra BDList
00495         if ($iBdCnt > $i1stBdL)
00496         {
00497             $iN=0;
00498             $iNb=0;
00499             for ($i=$i1stBdL;$i<$iBdCnt; $i++, $iN++)
00500             {
00501                 if ($iN>=($iBbCnt-1))
00502                 {
00503                     $iN = 0;
00504                     $iNb++;
00505                     fwrite($FILE, pack("V", $iAll+$iBdCnt+$iNb));
00506                 }
00507                 fwrite($FILE, pack("V", $iBsize+$iSbdSize+$iPpsCnt+$i));
00508             }
00509             if (($iBdCnt-$i1stBdL) % ($iBbCnt-1))
00510             {
00511                 for ($i = 0; $i < (($iBbCnt-1) - (($iBdCnt-$i1stBdL) % ($iBbCnt-1))); $i++) {
00512                     fwrite($FILE, pack("V", -1)); 
00513                 }
00514             }
00515             fwrite($FILE, pack("V", -2));
00516         }
00517     }
00518 }
00519 ?>

Generated on Fri Dec 13 2013 09:06:35 for ILIAS Release_3_4_x_branch .rev 46804 by  doxygen 1.7.1