No = false; $this->Name = Asc2Ucs('Root Entry'); $this->Type = PpsType_Root; $this->PrevPps = false; $this->NextPps = false; $this->DirPps = false; $this->Time1st = $raTime1st; $this->Time2nd = $raTime2nd; $this->StartBlock = false; $this->Size = false; $this->Data = false; $this->Child = $raChild; } #------------------------------------------------------------------------------ # save (OLE::Storage_Lite::PPS::Root) #------------------------------------------------------------------------------ function save($sFile, $bNoAs=false, $rhInfo=false) { #0.Initial Setting for saving if (!$rhInfo) { $rhInfo=new stdClass(); } $rhInfo->_BIG_BLOCK_SIZE=pow(2, (9)); $rhInfo->_SMALL_BLOCK_SIZE=pow(2, (($rhInfo->_SMALL_BLOCK_SIZE) ? _adjust2($rhInfo->_SMALL_BLOCK_SIZE) : 6)); $rhInfo->_SMALL_SIZE = 0x1000; $rhInfo->_PPS_SIZE = 0x80; #1.Open File #1.1 $sFile is Ref of scalar if(is_resource($sFile)) { $oIo=$sFile; $rhInfo->_FILEH_ = $oIo; } #1.2 $sFile is a simple filename string else { $oIo=fopen("$sFile", "wb"); $rhInfo->_FILEH_ = $oIo; } $iBlk = 0; #1. Make an array of PPS (for Save) $aList=array(); $list=array(&$this); if($bNoAs) { $this->_savePpsSetPnt2($list, $aList, $rhInfo); } else { $this->_savePpsSetPnt($list, $aList, $rhInfo); } list($iSBDcnt, $iBBcnt, $iPPScnt) = $this->_calcSize($aList, $rhInfo); #2.Save Header $this->_saveHeader($rhInfo, $iSBDcnt, $iBBcnt, $iPPScnt); #3.Make Small Data string (write SBD) $sSmWk = $this->_makeSmallData($aList, $rhInfo); $this->Data = $sSmWk; #Small Datas become RootEntry Data #4. Write BB $iBBlk = $iSBDcnt; $this->_saveBigData($iBBlk, $aList, $rhInfo); #5. Write PPS $this->_savePps($aList, $rhInfo); #6. Write BD and BDList and Adding Header informations $this->_saveBbd($iSBDcnt, $iBBcnt, $iPPScnt, $rhInfo); #7.Close File fclose($rhInfo->_FILEH_); } #------------------------------------------------------------------------------ # _calcSize (OLE::Storage_Lite::PPS) #------------------------------------------------------------------------------ function _calcSize(&$raList, $rhInfo) { #0. Calculate Basic Setting $iSBDcnt=0; $iBBcnt=0; $iPPScnt = 0; $iSmallLen = 0; $iSBcnt = 0; for ($c=0;$cType==PpsType_File) { $oPps->Size = $oPps->_DataLen(); #Mod if($oPps->Size < $rhInfo->_SMALL_SIZE) { $iSBcnt += floor($oPps->Size / $rhInfo->_SMALL_BLOCK_SIZE) + (($oPps->Size % $rhInfo->_SMALL_BLOCK_SIZE) ? 1 : 0); } else { $iBBcnt += (floor($oPps->Size/ $rhInfo->_BIG_BLOCK_SIZE) + (($oPps->Size % $rhInfo->_BIG_BLOCK_SIZE)? 1: 0)); } } } $iSmallLen = $iSBcnt * $rhInfo->_SMALL_BLOCK_SIZE; $iSlCnt = floor($rhInfo->_BIG_BLOCK_SIZE / LongIntSize); $iSBDcnt = floor($iSBcnt / $iSlCnt)+ (($iSBcnt % $iSlCnt) ? 1 : 0); $iBBcnt += (floor($iSmallLen/ $rhInfo->_BIG_BLOCK_SIZE) + (( $iSmallLen% $rhInfo->_BIG_BLOCK_SIZE) ? 1 : 0)); $iCnt = sizeof($raList); $iBdCnt = $rhInfo->_BIG_BLOCK_SIZE/PpsSize; $iPPScnt = (floor($iCnt/$iBdCnt) + (($iCnt % $iBdCnt) ? 1 : 0)); return array($iSBDcnt, $iBBcnt, $iPPScnt); } #------------------------------------------------------------------------------ # _adjust2 (OLE::Storage_Lite::PPS::Root) #------------------------------------------------------------------------------ function _adjust2($i2) { $iWk = log($i2)/log(2); return ($iWk > int($iWk)) ? floor($iWk)+1 : $iWk; } #------------------------------------------------------------------------------ # _saveHeader (OLE::Storage_Lite::PPS::Root) #------------------------------------------------------------------------------ function _saveHeader($rhInfo, $iSBDcnt, $iBBcnt, $iPPScnt) { $FILE = $rhInfo->_FILEH_; #0. Calculate Basic Setting $iBlCnt = $rhInfo->_BIG_BLOCK_SIZE / LongIntSize; $i1stBdL = ($rhInfo->_BIG_BLOCK_SIZE - 0x4C) / LongIntSize; $iBdExL = 0; $iAll = $iBBcnt + $iPPScnt + $iSBDcnt; $iAllW = $iAll; $iBdCntW = floor($iAllW / $iBlCnt) + (($iAllW % $iBlCnt) ? 1 : 0); $iBdCnt = floor(($iAll + $iBdCntW) / $iBlCnt) + ((($iAllW+$iBdCntW) % $iBlCnt) ? 1 : 0); //my $i; #0.1 Calculate BD count if ($iBdCnt > $i1stBdL) { // TODO: is do-while correct here? do { $iBdExL++; $iAllW++; $iBdCntW = floor($iAllW / $iBlCnt) + (($iAllW % $iBlCnt) ? 1 : 0); $iBdCnt = floor(($iAllW + $iBdCntW) / $iBlCnt) + ((($iAllW+$iBdCntW) % $iBlCnt) ? 1 : 0); } while($iBdCnt > ($iBdExL*$iBlCnt+ $i1stBdL)); } #1.Save Header fputs($FILE, "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1". "\x00\x00\x00\x00". "\x00\x00\x00\x00". "\x00\x00\x00\x00". "\x00\x00\x00\x00". pack("v", 0x3b). pack("v", 0x03). pack("v", -2). pack("v", 9). pack("v", 6). pack("v", 0). "\x00\x00\x00\x00". "\x00\x00\x00\x00". pack("V", $iBdCnt). pack("V", $iBBcnt+$iSBDcnt). #ROOT START pack("V", 0). pack("V", 0x1000). pack("V", 0). #Small Block Depot pack("V", 1) ); #2. Extra BDList Start, Count if($iBdCnt < $i1stBdL) { fputs($FILE, pack("V", -2). #Extra BDList Start pack("V", 0) #Extra BDList Count ); } else { fputs($FILE, pack("V", $iAll+$iBdCnt). pack("V", $iBdExL) ); } #3. BDList for ($i=0;($i<$i1stBdL) && ($i < $iBdCnt); $i++) { fputs($FILE, pack("V", $iAll+$i)); } if ($i<$i1stBdL) { // TODO: Check, if str_repeat is binary safe fputs($FILE, str_repeat((pack("V", -1)), ($i1stBdL-$i))); } } #------------------------------------------------------------------------------ # _saveBigData (OLE::Storage_Lite::PPS) #------------------------------------------------------------------------------ function _saveBigData(&$iStBlk, &$raList, $rhInfo) { //return;//!!! $iRes = 0; $FILE = $rhInfo->_FILEH_; #1.Write Big (ge 0x1000) Data into Block for ($c=0;$cType!=PpsType_Dir) { #print "PPS: $oPps DEF:", defined($oPps->{Data}), "\n"; $oPps->Size = $oPps->_DataLen(); #Mod if(($oPps->Size >= $rhInfo->_SMALL_SIZE) || (($oPps->Type == PpsType_Root) && $oPps->Data!==false)) { #1.1 Write Data #Check for update if($oPps->_PPS_FILE) { //my $sBuff; $iLen = 0; fseek($oPps->_PPS_FILE, 0, SEEK_SET); #To The Top while ($sBuff=fread($oPps->_PPS_FILE, 4096)) { $iLen += length($sBuff); fputs($FILE, $sBuff); #Check for update } } else { fputs($FILE, $oPps->Data); } if ($oPps->Size % $rhInfo->_BIG_BLOCK_SIZE) { // TODO: Check, if str_repeat() is binary safe fputs($FILE, str_repeat("\x00", ($rhInfo->_BIG_BLOCK_SIZE - ($oPps->Size % $rhInfo->_BIG_BLOCK_SIZE))) ); } #1.2 Set For PPS $oPps->StartBlock = $iStBlk; $iStBlk += (floor($oPps->Size/ $rhInfo->_BIG_BLOCK_SIZE) + (($oPps->Size % $rhInfo->_BIG_BLOCK_SIZE) ? 1 : 0)); } } } } #------------------------------------------------------------------------------ # _savePps (OLE::Storage_Lite::PPS::Root) #------------------------------------------------------------------------------ function _savePps(&$raList, $rhInfo) { #0. Initial $FILE = $rhInfo->_FILEH_; #2. Save PPS for ($c=0;$c_savePpsWk($rhInfo); } #3. Adjust for Block $iCnt = sizeof($raList); $iBCnt = $rhInfo->_BIG_BLOCK_SIZE / $rhInfo->_PPS_SIZE; if($iCnt % $iBCnt) { fputs($FILE, str_repeat("\x00", (($iBCnt - ($iCnt % $iBCnt)) * $rhInfo->_PPS_SIZE))); } return (floor($iCnt / $iBCnt) + (($iCnt % $iBCnt) ? 1 : 0)); } #------------------------------------------------------------------------------ # _savePpsSetPnt2 (OLE::Storage_Lite::PPS::Root) # For Test #------------------------------------------------------------------------------ function _savePpsSetPnt2(&$aThis, &$raList, $rhInfo) { #1. make Array as Children-Relations #1.1 if No Children if (!is_array($aThis) || sizeof($aThis)==0) { return 0xFFFFFFFF; } elseif (sizeof($aThis)==1) { #1.2 Just Only one array_push($raList, $aThis[0]); $aThis[0]->No = sizeof($raList)-1; $aThis[0]->PrevPps = 0xFFFFFFFF; $aThis[0]->NextPps = 0xFFFFFFFF; $aThis[0]->DirPps = $this->_savePpsSetPnt2($aThis[0]->Child, $raList, $rhInfo); return $aThis[0]->No; } else { #1.3 Array $iCnt = sizeof($aThis); #1.3.1 Define Center $iPos = 0; #int($iCnt/ 2); #$iCnt $aWk = $aThis; $aPrev = (sizeof($aThis) > 2) ? array_splice($aWk, 1, 1) : array(); #$iPos); $aNext = array_splice($aWk, 1); #, $iCnt - $iPos -1); $aThis[$iPos]->PrevPps = $this->_savePpsSetPnt2($aPrev, $raList, $rhInfo); array_push($raList, $aThis[$iPos]); $aThis[$iPos]->No = sizeof($raList)-1; #1.3.2 Devide a array into Previous,Next $aThis[$iPos]->NextPps = $this->_savePpsSetPnt2($aNext, $raList, $rhInfo); $aThis[$iPos]->DirPps = $this->_savePpsSetPnt2($aThis[$iPos]->Child, $raList, $rhInfo); return $aThis[$iPos]->No; } } #------------------------------------------------------------------------------ # _savePpsSetPnt2 (OLE::Storage_Lite::PPS::Root) # For Test #------------------------------------------------------------------------------ function _savePpsSetPnt2s(&$aThis, &$raList, $rhInfo) { #1. make Array as Children-Relations #1.1 if No Children if (!is_array($aThis) || sizeof($aThis)==0) { return 0xFFFFFFFF; } elseif (sizeof($aThis)==1) { #1.2 Just Only one array_push($raList, $aThis[0]); $aThis[0]->No = sizeof($raList)-1; $aThis[0]->PrevPps = 0xFFFFFFFF; $aThis[0]->NextPps = 0xFFFFFFFF; $aThis[0]->DirPps = $this->_savePpsSetPnt2($aThis[0]->Child, $raList, $rhInfo); return $aThis[0]->No; } else { #1.3 Array $iCnt = sizeof($aThis); #1.3.1 Define Center $iPos = 0; #int($iCnt/ 2); #$iCnt array_push($raList, $aThis[$iPos]); $aThis[$iPos]->No = sizeof($raList)-1; $aWk = $aThis; #1.3.2 Devide a array into Previous,Next $aPrev = array_splice($aWk, 0, $iPos); $aNext = array_splice($aWk, 1, $iCnt - $iPos - 1); $aThis[$iPos]->PrevPps = $this->_savePpsSetPnt2($aPrev, $raList, $rhInfo); $aThis[$iPos]->NextPps = $this->_savePpsSetPnt2($aNext, $raList, $rhInfo); $aThis[$iPos]->DirPps = $this->_savePpsSetPnt2($aThis[$iPos]->Child, $raList, $rhInfo); return $aThis[$iPos]->No; } } #------------------------------------------------------------------------------ # _savePpsSetPnt (OLE::Storage_Lite::PPS::Root) #------------------------------------------------------------------------------ function _savePpsSetPnt(&$aThis, &$raList, $rhInfo) { //print "yyy type: ".gettype($aThis)."
\n"; //print "yyy name: ".$aThis[0]->Name."
\n"; #1. make Array as Children-Relations #1.1 if No Children if (!is_array($aThis) || sizeof($aThis)==0) { return 0xFFFFFFFF; } elseif (sizeof($aThis)==1) { #1.2 Just Only one array_push($raList, $aThis[0]); $aThis[0]->No = sizeof($raList)-1; $aThis[0]->PrevPps = 0xFFFFFFFF; $aThis[0]->NextPps = 0xFFFFFFFF; $aThis[0]->DirPps = $this->_savePpsSetPnt($aThis[0]->Child, $raList, $rhInfo); return $aThis[0]->No; } else { #1.3 Array $iCnt = sizeof($aThis); #1.3.1 Define Center $iPos = floor($iCnt/2); #$iCnt array_push($raList, $aThis[$iPos]); $aThis[$iPos]->No = sizeof($raList)-1; $aWk = $aThis; #1.3.2 Devide a array into Previous,Next $aPrev = splice($aWk, 0, $iPos); $aNext = splice($aWk, 1, $iCnt - $iPos - 1); $aThis[$iPos]->PrevPps = $this->_savePpsSetPnt($aPrev, $raList, $rhInfo); $aThis[$iPos]->NextPps = $this->_savePpsSetPnt($aNext, $raList, $rhInfo); $aThis[$iPos]->DirPps = $this->_savePpsSetPnt($aThis[$iPos]->Child, $raList, $rhInfo); return $aThis[$iPos]->No; } } #------------------------------------------------------------------------------ # _savePpsSetPnt (OLE::Storage_Lite::PPS::Root) #------------------------------------------------------------------------------ function _savePpsSetPnt1(&$aThis, &$raList, $rhInfo) { #1. make Array as Children-Relations #1.1 if No Children if (!is_array($aThis) || sizeof($aThis)==0) { return 0xFFFFFFFF; } elseif (sizeof($aThis)==1) { #1.2 Just Only one array_push($raList, $aThis[0]); $aThis[0]->No = sizeof($raList)-1; $aThis[0]->PrevPps = 0xFFFFFFFF; $aThis[0]->NextPps = 0xFFFFFFFF; $aThis[0]->DirPps = $this->_savePpsSetPnt($aThis[0]->Child, $raList, $rhInfo); return $aThis[0]->No; } else { #1.3 Array $iCnt = sizeof($aThis); #1.3.1 Define Center $iPos = floor($iCnt / 2); #$iCnt array_push($raList, $aThis[$iPos]); $aThis[$iPos]->No = sizeof($raList)-1; $aWk = $aThis; #1.3.2 Devide a array into Previous,Next $aPrev = splice($aWk, 0, $iPos); $aNext = splice($aWk, 1, $iCnt - $iPos - 1); $aThis[$iPos]->PrevPps = $this->_savePpsSetPnt($aPrev, $raList, $rhInfo); $aThis[$iPos]->NextPps = $this->_savePpsSetPnt($aNext, $raList, $rhInfo); $aThis[$iPos]->DirPps = $this->_savePpsSetPnt($aThis[$iPos]->Child, $raList, $rhInfo); return $aThis[$iPos]->No; } } #------------------------------------------------------------------------------ # _saveBbd (OLE::Storage_Lite) #------------------------------------------------------------------------------ function _saveBbd($iSbdSize, $iBsize, $iPpsCnt, $rhInfo) { $FILE = $rhInfo->_FILEH_; #0. Calculate Basic Setting $iBbCnt = $rhInfo->_BIG_BLOCK_SIZE / LongIntSize; $i1stBdL = ($rhInfo->_BIG_BLOCK_SIZE - 0x4C) / LongIntSize; $iBdExL = 0; $iAll = $iBsize + $iPpsCnt + $iSbdSize; $iAllW = $iAll; $iBdCntW = floor($iAllW / $iBbCnt) + (($iAllW % $iBbCnt) ? 1 : 0); $iBdCnt = floor(($iAll + $iBdCntW) / $iBbCnt) + ((($iAllW+$iBdCntW) % $iBbCnt)? 1: 0); //my $i; #0.1 Calculate BD count if ($iBdCnt >$i1stBdL) { // TODO: do-while correct here? do { $iBdExL++; $iAllW++; $iBdCntW = floor($iAllW / $iBbCnt) + (($iAllW % $iBbCnt) ? 1 : 0); $iBdCnt = floor(($iAllW + $iBdCntW) / $iBbCnt) + ((($iAllW+$iBdCntW) % $iBbCnt) ? 1 : 0); } while ($iBdCnt > ($iBdExL*$iBbCnt+$i1stBdL)); } #1. Making BD #1.1 Set for SBD if($iSbdSize > 0) { for ($i = 0; $i<($iSbdSize-1); $i++) { fputs($FILE, pack("V", $i+1)); } fputs($FILE, pack("V", -2)); } #1.2 Set for B for ($i = 0; $i<($iBsize-1); $i++) { fputs($FILE, pack("V", $i+$iSbdSize+1)); } fputs($FILE, pack("V", -2)); #1.3 Set for PPS for ($i = 0; $i<($iPpsCnt-1); $i++) { fputs($FILE, pack("V", $i+$iSbdSize+$iBsize+1)); } fputs($FILE, pack("V", -2)); #1.4 Set for BBD itself ( 0xFFFFFFFD : BBD) for ($i=0; $i<$iBdCnt;$i++) { fputs($FILE, pack("V", 0xFFFFFFFD)); } #1.5 Set for ExtraBDList for ($i=0; $i<$iBdExL;$i++) { fputs($FILE, pack("V", 0xFFFFFFFC)); } #1.6 Adjust for Block if(($iAllW + $iBdCnt) % $iBbCnt) { fputs($FILE, str_repeat(pack("V", -1), ($iBbCnt - (($iAllW + $iBdCnt) % $iBbCnt)))); } #2.Extra BDList if($iBdCnt > $i1stBdL) { $iN=0; $iNb=0; for ($i=$i1stBdL;$i<$iBdCnt; $i++, $iN++) { if($iN>=($iBbCnt-1)) { $iN = 0; $iNb++; fputs($FILE, pack("V", $iAll+$iBdCnt+$iNb)); } fputs($FILE, pack("V", $iBsize+$iSbdSize+$iPpsCnt+$i)); } if(($iBdCnt-$i1stBdL) % ($iBbCnt-1)) { fputs($FILE, str_repeat(pack("V", -1), (($iBbCnt-1) - (($iBdCnt-$i1stBdL) % ($iBbCnt-1))))); } fputs($FILE, pack("V", -2)); } } } ?>