nfTlWNl rn Ѻq$³*AӪ}# po_ŭ[[vDMLr\ '^)>!QXrlv ՙ7\uHRfnf7\uHRfnf7\uHRfnfG y5#w%rin /#oQI$l ĢQ$3 ĢQ$305Ӽ؝uxMMv)"~Wd;7\uHRfnf7\uHRfnf7\uHRfnf/b'yZmG/wǥ'J,ltHк>.֢2}Mu^9tkK/ ĢQ$3J,LCqA)7\uHRfnf7\uHRfnf7\uHRfnfG y5#w%r@O@~W,/0=ShaȵY y^αnBY JԨlaآ88}C ĢQ$3aScI}d[z&/߭;]=iSОhl ( |_R_ٍ 44ER[j-^>CaL>oLJ3"&Zn\[{[pbj@o;Gֈ,vܐ(i'zcjT?  z :$f~MFS 7Z 4R8Eklx͜ 'mP:?TAJ,LCqA)7\uHRfnf7\uHRfnf7\uHRfnfG y5#w%r~ݹfE͓qP'Un鮐5;" ĢQ$305Ӽ؝uxnu*N=?δ&jz }1%Ñޢ)R( cZ ĢQ$3XXOj=17\uHRfnf7\uHRfnf7\uHRfnf7\uHRfnfWT4 b\`Lٔ*ܝIcz"Va! Ĵo$_+ʏAQoHҳ\aNT\Rj$;͖IŲkq^H^R6Ԕ1~4s)#E"({m~"ȔqX'y)M+l;3[ba39aBjQ8"ːUG+^S8M+N4f3bSy)r g )?4C_=N"P i@x>\L'gh㜆qGi~Ktfgc(97eI oDN 2YəMC]9;Cok OGr;O8Gk,QDZu*Ne6lxV}XHO{؂- <\,G,ÔBZZh֗D Si~\lu-(ǡQgb`V,xV}XHO{N#S&lbqkIJ@$};i`G r$cl&N 8MW\V/@ ܯΡp$L2R4&ze^ՋBӊdygZ碛@7ײgPvzD]]]Pw~YK%?7r$cl&N 8MW\VgkS{M3^"ZBP!뫖0 XEA)D'P[Fv㡴&r$cl&N [Fa %#̩}kT#L؀Ȧ9UQ DxcӿJebT $,I[cO!- HzX&x~k'JU@PƀI(@JYp*8W46 >|132p/4Wzo?ܨ:PZGsUhͩa[eJ;j*-JLljL7O&3N=Z(K7 E!];@ jMLY -A\p6`ZX4ltT`s<_ʓzsi/[tͨĄϚm KfcAmB!|Fy(aMe[& =}j K\bGpQ=G`'i{k1~%JV|Kc[s?R-.ވMX+Y>%2)vC]4 ,MlظnD0L=_|.ՃbcU'*P,@2~ЦyiajK0_LmlVVu/rtOZhPo!sz1Жwv i6pQrSA>)ǥٰrϬz;?ImdI`JK11㱾 G;6ݷ ?tKkLlsWy3.Z0kؑT'@3Z{euU!jeaTو&y{?ɝ\O7%T썊Q-!Vof5bk*˷+dNV-nQW%xo[Bqehu"ȁ0@M dr;O8Gk,ƸEզ$4;m'5+NU D2wE7}:/'V#p&ϰyXƉĊ758f+;tyq{ UЗ4NSQ0by ?'D!P~a[w3޿EvLv{9QROtbv͸Ys7B*DsrVIx$AGKG ttGG#8a4lv,SP۸]l(wAj]Ǎ(f&P?) 8lRo~>JpA|+j[6} *[DKK1q`@z'}%x`U픑G7 |NNTNIA@1*ir?9OZ7[Gw_G=|>Bݳ-׽b%d=hn~p_$ c7A?UYNdM5f]ێQX=UF`!KY9ڬKl6t2uS-A*uj=ĿQC9=D>7>c09'>Vg9~&]uz:/ 䢔%Gcv/whBe7x0ո55^дE'->sK1^Hw`)Mu -Y)GU`[sW%%Jq\ ]ׯ5WJ1oe1Xj^ѹNn@1?eq2.g8Y LAVXچ7+#϶A\j)it=:F)4{2xżFDw4%x'N:kP aL Rw B`k s{7ަ<"v<`i)fGV&VV +H*ZmQo1I~k0gHf]΂\4+;W,:eNS9 n int The amount of data (in bytes) */ public function getDataLen() { //if (!isset($this->_data)) { // return 0; //} return strlen($this->_data); } /** * Returns a string with the PPS's WK (What is a WK?). * * @return string The binary string */ public function getPpsWk() { $ret = str_pad($this->Name, 64, "\x00"); $ret .= pack('v', strlen($this->Name) + 2) // 66 . pack('c', $this->Type) // 67 . pack('c', 0x00) //UK // 68 . pack('V', $this->PrevPps) //Prev // 72 . pack('V', $this->NextPps) //Next // 76 . pack('V', $this->DirPps) //Dir // 80 . "\x00\x09\x02\x00" // 84 . "\x00\x00\x00\x00" // 88 . "\xc0\x00\x00\x00" // 92 . "\x00\x00\x00\x46" // 96 // Seems to be ok only for Root . "\x00\x00\x00\x00" // 100 . OLE::localDateToOLE($this->Time1st) // 108 . OLE::localDateToOLE($this->Time2nd) // 116 . pack('V', $this->startBlock ?? 0) // 120 . pack('V', $this->Size) // 124 . pack('V', 0); // 128 return $ret; } /** * Updates index and pointers to previous, next and children PPS's for this * PPS. I don't think it'll work with Dir PPS's. * * @param array $raList Reference to the array of PPS's for the whole OLE * container * @param mixed $to_save * @param mixed $depth * * @return int The index for this PPS */ public static function savePpsSetPnt(&$raList, $to_save, $depth = 0) { if (!is_array($to_save) || (empty($to_save))) { return 0xFFFFFFFF; } elseif (count($to_save) == 1) { $cnt = count($raList); // If the first entry, it's the root... Don't clone it! $raList[$cnt] = ($depth == 0) ? $to_save[0] : clone $to_save[0]; $raList[$cnt]->No = $cnt; $raList[$cnt]->PrevPps = 0xFFFFFFFF; $raList[$cnt]->NextPps = 0xFFFFFFFF; $raList[$cnt]->DirPps = self::savePpsSetPnt($raList, @$raList[$cnt]->children, $depth++); } else { $iPos = (int) floor(count($to_save) / 2); $aPrev = array_slice($to_save, 0, $iPos); $aNext = array_slice($to_save, $iPos + 1); $cnt = count($raList); // If the first entry, it's the root... Don't clone it! $raList[$cnt] = ($depth == 0) ? $to_save[$iPos] : clone $to_save[$iPos]; $raList[$cnt]->No = $cnt; $raList[$cnt]->PrevPps = self::savePpsSetPnt($raList, $aPrev, $depth++); $raList[$cnt]->NextPps = self::savePpsSetPnt($raList, $aNext, $depth++); $raList[$cnt]->DirPps = self::savePpsSetPnt($raList, @$raList[$cnt]->children, $depth++); } return $cnt; } }