102 $this->_file_handle =
$fh;
104 $signature = fread(
$fh, 8);
105 if (
"\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" != $signature) {
109 if (fread(
$fh, 2) !=
"\xFE\xFF") {
114 $this->bigBlockSize = pow(2, self::_readInt2(
$fh));
115 $this->smallBlockSize = pow(2, self::_readInt2(
$fh));
120 $bbatBlockCount = self::_readInt4(
$fh);
123 $directoryFirstBlockId = self::_readInt4(
$fh);
128 $this->bigBlockThreshold = self::_readInt4(
$fh);
130 $sbatFirstBlockId = self::_readInt4(
$fh);
132 $sbbatBlockCount = self::_readInt4(
$fh);
134 $mbatFirstBlockId = self::_readInt4(
$fh);
136 $mbbatBlockCount = self::_readInt4(
$fh);
137 $this->bbat =
array();
141 $mbatBlocks =
array();
142 for ($i = 0; $i < 109; ++$i) {
143 $mbatBlocks[] = self::_readInt4(
$fh);
148 for ($i = 0; $i < $mbbatBlockCount; ++$i) {
150 for ($j = 0; $j < $this->bigBlockSize / 4 - 1; ++$j) {
151 $mbatBlocks[] = self::_readInt4(
$fh);
159 for ($i = 0; $i < $bbatBlockCount; ++$i) {
162 for ($j = 0 ; $j < $this->bigBlockSize / 4; ++$j) {
163 $this->bbat[] = self::_readInt4(
$fh);
168 $this->sbat =
array();
169 $shortBlockCount = $sbbatBlockCount * $this->bigBlockSize / 4;
170 $sbatFh = $this->
getStream($sbatFirstBlockId);
171 for ($blockId = 0; $blockId < $shortBlockCount; ++$blockId) {
172 $this->sbat[$blockId] = self::_readInt4($sbatFh);
199 static $isRegistered =
false;
200 if (!$isRegistered) {
201 stream_wrapper_register(
'ole-chainedblockstream',
202 'PHPExcel_Shared_OLE_ChainedBlockStream');
203 $isRegistered =
true;
209 $GLOBALS[
'_OLE_INSTANCES'][] = $this;
210 $instanceId = end(array_keys(
$GLOBALS[
'_OLE_INSTANCES']));
212 $path =
'ole-chainedblockstream://oleInstanceId=' . $instanceId;
214 $path .=
'&blockId=' . $blockIdOrPps->_StartBlock;
215 $path .=
'&size=' . $blockIdOrPps->Size;
217 $path .=
'&blockId=' . $blockIdOrPps;
219 return fopen(
$path,
'r');
230 list(, $tmp) = unpack(
"c", fread(
$fh, 1));
242 list(, $tmp) = unpack(
"v", fread(
$fh, 2));
254 list(, $tmp) = unpack(
"V", fread(
$fh, 4));
269 for ($pos = 0; ; $pos += 128) {
270 fseek(
$fh, $pos, SEEK_SET);
271 $nameUtf16 = fread(
$fh, 64);
272 $nameLength = self::_readInt2(
$fh);
273 $nameUtf16 = substr($nameUtf16, 0, $nameLength - 2);
275 $name = str_replace(
"\x00",
"", $nameUtf16);
276 $type = self::_readInt1(
$fh);
278 case self::OLE_PPS_TYPE_ROOT:
282 case self::OLE_PPS_TYPE_DIR:
284 null, null, null, null,
array());
286 case self::OLE_PPS_TYPE_FILE:
292 fseek(
$fh, 1, SEEK_CUR);
295 $pps->PrevPps = self::_readInt4(
$fh);
296 $pps->NextPps = self::_readInt4(
$fh);
297 $pps->DirPps = self::_readInt4(
$fh);
298 fseek(
$fh, 20, SEEK_CUR);
299 $pps->Time1st = self::OLE2LocalDate(fread(
$fh, 8));
300 $pps->Time2nd = self::OLE2LocalDate(fread(
$fh, 8));
301 $pps->_StartBlock = self::_readInt4(
$fh);
302 $pps->Size = self::_readInt4(
$fh);
303 $pps->No = count($this->_list);
304 $this->_list[] = $pps;
307 if (isset($this->root) &&
316 foreach ($this->_list as $pps) {
317 if ($pps->Type == self::OLE_PPS_TYPE_DIR || $pps->Type == self::OLE_PPS_TYPE_ROOT) {
318 $nos =
array($pps->DirPps);
319 $pps->children =
array();
321 $no = array_pop($nos);
323 $childPps = $this->_list[$no];
324 $nos[] = $childPps->PrevPps;
325 $nos[] = $childPps->NextPps;
326 $pps->children[] = $childPps;
345 return isset($this->_list[$index]) &&
346 ($pps = $this->_list[$index]) &&
347 ($pps->PrevPps == -1 ||
348 $this->_ppsTreeComplete($pps->PrevPps)) &&
349 ($pps->NextPps == -1 ||
350 $this->_ppsTreeComplete($pps->NextPps)) &&
351 ($pps->DirPps == -1 ||
352 $this->_ppsTreeComplete($pps->DirPps));
365 if (isset($this->_list[$index])) {
366 return ($this->_list[$index]->Type == self::OLE_PPS_TYPE_FILE);
381 if (isset($this->_list[$index])) {
382 return ($this->_list[$index]->Type == self::OLE_PPS_TYPE_ROOT);
395 return count($this->_list);
410 public function getData($index, $position, $length)
413 if (!isset($this->_list[$index]) || ($position >= $this->_list[$index]->Size) || ($position < 0)) {
417 $data = stream_get_contents(
$fh, $length, $position);
432 if (isset($this->_list[$index])) {
433 return $this->_list[$index]->Size;
449 for ($i = 0; $i < strlen($ascii); ++$i) {
450 $rawname .= $ascii{$i} .
"\x00";
467 return "\x00\x00\x00\x00\x00\x00\x00\x00";
471 $factor = pow(2, 32);
476 $big_date = $days*24*3600 + gmmktime(
date(
"H",$date),
date(
"i",$date),
date(
"s",$date),
479 $big_date *= 10000000;
481 $high_part = floor($big_date / $factor);
483 $low_part = floor((($big_date / $factor) - $high_part) * $factor);
488 for ($i = 0; $i < 4; ++$i) {
489 $hex = $low_part % 0x100;
490 $res .= pack(
'c', $hex);
493 for ($i = 0; $i < 4; ++$i) {
494 $hex = $high_part % 0x100;
495 $res .= pack(
'c', $hex);
511 if (strlen($string) != 8) {
512 return new PEAR_Error(
"Expecting 8 byte string");
517 list(, $high_part) = unpack(
'V', substr($string, 4, 4));
518 list(, $low_part) = unpack(
'V', substr($string, 0, 4));
520 $big_date = ($high_part * $factor) + $low_part;
522 $big_date /= 10000000;
528 $big_date -= $days * 24 * 3600;
529 return floor($big_date);
static Asc2Ucs($ascii)
Utility function to transform ASCII text to Unicode.
getDataLength($index)
Gets the data length from a PPS If there is no PPS for the index given, it will return 0...
isRoot($index)
Checks whether a PPS is a Root PPS or not.
ppsTotal()
Gives the total number of PPS's found in the OLE container.
static _readInt1($fh)
Reads a signed char.
static _readInt4($fh)
Reads an unsigned long (4 octets).
read($file)
Reads an OLE container from the contents of the file given.
isFile($index)
Checks whether a PPS is a File PPS or not.
_readPpsWks($blockId)
Gets information about all PPS's on the OLE container from the PPS WK's creates an OLE_PPS object for...
_getBlockOffset($blockId)
_ppsTreeComplete($index)
It checks whether the PPS tree is complete (all PPS's read) starting with the given PPS (not necessar...
date( 'd-M-Y', $objPHPExcel->getProperties() ->getCreated())
getData($index, $position, $length)
Gets data from a PPS If there is no PPS for the index given, it will return an empty string...
getStream($blockIdOrPps)
Returns a stream for use with fread() etc.
static OLE2LocalDate($string)
Returns a timestamp from an OLE container's date.
const OLE_DATA_SIZE_SMALL
Create styles array
The data for the language used.
static _readInt2($fh)
Reads an unsigned short (2 octets).
if(!file_exists("$old.txt")) if($old===$new) if(file_exists("$new.txt")) $file
$GLOBALS['_OLE_INSTANCES']
static LocalDate2OLE($date=null)
Utility function Returns a string for the OLE container with the date given.