|
Moodle
2.2.1
http://www.collinsharper.com
|
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,v 1.4 2010/12/14 17:35:58 moodlerobot Exp $ 00021 00022 00023 require_once ('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 ?>