ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
PhpOffice\PhpSpreadsheet\Shared\OLE Class Reference

OLE package base class. More...

+ Collaboration diagram for PhpOffice\PhpSpreadsheet\Shared\OLE:

Public Member Functions

 read ($file)
 Reads an OLE container from the contents of the file given. More...
 
 getBlockOffset ($blockId)
 
 getStream ($blockIdOrPps)
 Returns a stream for use with fread() etc. More...
 
 readPpsWks ($blockId)
 Gets information about all PPS's on the OLE container from the PPS WK's creates an OLE_PPS object for each one. More...
 
 isFile ($index)
 Checks whether a PPS is a File PPS or not. More...
 
 isRoot ($index)
 Checks whether a PPS is a Root PPS or not. More...
 
 ppsTotal ()
 Gives the total number of PPS's found in the OLE container. More...
 
 getData ($index, $position, $length)
 Gets data from a PPS If there is no PPS for the index given, it will return an empty string. More...
 
 getDataLength ($index)
 Gets the data length from a PPS If there is no PPS for the index given, it will return 0. More...
 

Static Public Member Functions

static ascToUcs ($ascii)
 Utility function to transform ASCII text to Unicode. More...
 
static localDateToOLE ($date)
 Utility function Returns a string for the OLE container with the date given. More...
 
static OLE2LocalDate ($oleTimestamp)
 Returns a timestamp from an OLE container's date. More...
 

Data Fields

const OLE_PPS_TYPE_ROOT = 5
 
const OLE_PPS_TYPE_DIR = 1
 
const OLE_PPS_TYPE_FILE = 2
 
const OLE_DATA_SIZE_SMALL = 0x1000
 
const OLE_LONG_INT_SIZE = 4
 
const OLE_PPS_SIZE = 0x80
 
 $_file_handle
 
 $_list = []
 
 $root
 
 $bbat
 
 $sbat
 
 $bigBlockSize
 
 $smallBlockSize
 
 $bigBlockThreshold
 

Private Member Functions

 ppsTreeComplete ($index)
 It checks whether the PPS tree is complete (all PPS's read) starting with the given PPS (not necessarily root). More...
 

Static Private Member Functions

static readInt1 ($fh)
 Reads a signed char. More...
 
static readInt2 ($fh)
 Reads an unsigned short (2 octets). More...
 
static readInt4 ($fh)
 Reads an unsigned long (4 octets). More...
 

Detailed Description

OLE package base class.

Author
Xavier Noguer xnogu.nosp@m.er@p.nosp@m.hp.ne.nosp@m.t
Christian Schmidt schmi.nosp@m.dt@p.nosp@m.hp.ne.nosp@m.t

Definition at line 43 of file OLE.php.

Member Function Documentation

◆ ascToUcs()

static PhpOffice\PhpSpreadsheet\Shared\OLE::ascToUcs (   $ascii)
static

Utility function to transform ASCII text to Unicode.

Parameters
string$asciiThe ASCII string to transform
Returns
string The string in Unicode

Definition at line 478 of file OLE.php.

References $i.

Referenced by PhpOffice\PhpSpreadsheet\Shared\OLE\PPS\Root\__construct(), and PhpOffice\PhpSpreadsheet\Writer\Xls\save().

479  {
480  $rawname = '';
481  $iMax = strlen($ascii);
482  for ($i = 0; $i < $iMax; ++$i) {
483  $rawname .= $ascii[$i]
484  . "\x00";
485  }
486 
487  return $rawname;
488  }
$i
Definition: disco.tpl.php:19
+ Here is the caller graph for this function:

◆ getBlockOffset()

PhpOffice\PhpSpreadsheet\Shared\OLE::getBlockOffset (   $blockId)
Parameters
int$blockIdbyte offset from beginning of file
Returns
int

Definition at line 206 of file OLE.php.

References PhpOffice\PhpSpreadsheet\Shared\OLE\$bigBlockSize.

Referenced by PhpOffice\PhpSpreadsheet\Shared\OLE\read().

207  {
208  return 512 + $blockId * $this->bigBlockSize;
209  }
+ Here is the caller graph for this function:

◆ getData()

PhpOffice\PhpSpreadsheet\Shared\OLE::getData (   $index,
  $position,
  $length 
)

Gets data from a PPS If there is no PPS for the index given, it will return an empty string.

Parameters
int$indexThe index for the PPS
int$positionThe position from which to start reading (relative to the PPS)
int$lengthThe amount of bytes to read (at most)
Returns
string The binary string containing the data requested
See also
OLE_PPS_File::getStream()

Definition at line 441 of file OLE.php.

References $data, $index, and PhpOffice\PhpSpreadsheet\Shared\OLE\getStream().

442  {
443  // if position is not valid return empty string
444  if (!isset($this->_list[$index]) || ($position >= $this->_list[$index]->Size) || ($position < 0)) {
445  return '';
446  }
447  $fh = $this->getStream($this->_list[$index]);
448  $data = stream_get_contents($fh, $length, $position);
449  fclose($fh);
450 
451  return $data;
452  }
getStream($blockIdOrPps)
Returns a stream for use with fread() etc.
Definition: OLE.php:219
$index
Definition: metadata.php:60
$data
Definition: bench.php:6
+ Here is the call graph for this function:

◆ getDataLength()

PhpOffice\PhpSpreadsheet\Shared\OLE::getDataLength (   $index)

Gets the data length from a PPS If there is no PPS for the index given, it will return 0.

Parameters
int$indexThe index for the PPS
Returns
int The amount of bytes in data the PPS has

Definition at line 462 of file OLE.php.

References $index.

463  {
464  if (isset($this->_list[$index])) {
465  return $this->_list[$index]->Size;
466  }
467 
468  return 0;
469  }
$index
Definition: metadata.php:60

◆ getStream()

PhpOffice\PhpSpreadsheet\Shared\OLE::getStream (   $blockIdOrPps)

Returns a stream for use with fread() etc.

External callers should use ::getStream().

Parameters
int | OLE\PPS$blockIdOrPpsblock id or PPS
Returns
resource read-only stream

Definition at line 219 of file OLE.php.

References PhpOffice\PhpSpreadsheet\Shared\$GLOBALS, $keys, and $path.

Referenced by PhpOffice\PhpSpreadsheet\Shared\OLE\getData(), PhpOffice\PhpSpreadsheet\Shared\OLE\read(), and PhpOffice\PhpSpreadsheet\Shared\OLE\readPpsWks().

220  {
221  static $isRegistered = false;
222  if (!$isRegistered) {
223  stream_wrapper_register('ole-chainedblockstream', ChainedBlockStream::class);
224  $isRegistered = true;
225  }
226 
227  // Store current instance in global array, so that it can be accessed
228  // in OLE_ChainedBlockStream::stream_open().
229  // Object is removed from self::$instances in OLE_Stream::close().
230  $GLOBALS['_OLE_INSTANCES'][] = $this;
231  $keys = array_keys($GLOBALS['_OLE_INSTANCES']);
232  $instanceId = end($keys);
233 
234  $path = 'ole-chainedblockstream://oleInstanceId=' . $instanceId;
235  if ($blockIdOrPps instanceof OLE\PPS) {
236  $path .= '&blockId=' . $blockIdOrPps->startBlock;
237  $path .= '&size=' . $blockIdOrPps->Size;
238  } else {
239  $path .= '&blockId=' . $blockIdOrPps;
240  }
241 
242  return fopen($path, 'rb');
243  }
$path
Definition: aliased.php:25
$GLOBALS['_OLE_INSTANCES']
Definition: OLE.php:35
$keys
+ Here is the caller graph for this function:

◆ isFile()

PhpOffice\PhpSpreadsheet\Shared\OLE::isFile (   $index)

Checks whether a PPS is a File PPS or not.

If there is no PPS for the index given, it will return false.

Parameters
int$indexThe index for the PPS
Returns
bool true if it's a File PPS, false otherwise

Definition at line 392 of file OLE.php.

References $index.

393  {
394  if (isset($this->_list[$index])) {
395  return $this->_list[$index]->Type == self::OLE_PPS_TYPE_FILE;
396  }
397 
398  return false;
399  }
$index
Definition: metadata.php:60

◆ isRoot()

PhpOffice\PhpSpreadsheet\Shared\OLE::isRoot (   $index)

Checks whether a PPS is a Root PPS or not.

If there is no PPS for the index given, it will return false.

Parameters
int$indexthe index for the PPS
Returns
bool true if it's a Root PPS, false otherwise

Definition at line 409 of file OLE.php.

References $index.

410  {
411  if (isset($this->_list[$index])) {
412  return $this->_list[$index]->Type == self::OLE_PPS_TYPE_ROOT;
413  }
414 
415  return false;
416  }
$index
Definition: metadata.php:60

◆ localDateToOLE()

static PhpOffice\PhpSpreadsheet\Shared\OLE::localDateToOLE (   $date)
static

Utility function Returns a string for the OLE container with the date given.

Parameters
float | int$dateA timestamp
Returns
string The string for the OLE container

Definition at line 498 of file OLE.php.

References $i, and $res.

Referenced by PhpOffice\PhpSpreadsheet\Shared\OLE\PPS\getPpsWk(), and PhpOffice\PhpSpreadsheet\Writer\Xls\writeSummaryPropOle().

499  {
500  if (!$date) {
501  return "\x00\x00\x00\x00\x00\x00\x00\x00";
502  }
503  $dateTime = Date::dateTimeFromTimestamp("$date");
504 
505  // factor used for separating numbers into 4 bytes parts
506  $factor = 2 ** 32;
507 
508  // days from 1-1-1601 until the beggining of UNIX era
509  $days = 134774;
510  // calculate seconds
511  $big_date = $days * 24 * 3600 + (float) $dateTime->format('U');
512  // multiply just to make MS happy
513  $big_date *= 10000000;
514 
515  $high_part = floor($big_date / $factor);
516  // lower 4 bytes
517  $low_part = floor((($big_date / $factor) - $high_part) * $factor);
518 
519  // Make HEX string
520  $res = '';
521 
522  for ($i = 0; $i < 4; ++$i) {
523  $hex = $low_part % 0x100;
524  $res .= pack('c', $hex);
525  $low_part /= 0x100;
526  }
527  for ($i = 0; $i < 4; ++$i) {
528  $hex = $high_part % 0x100;
529  $res .= pack('c', $hex);
530  $high_part /= 0x100;
531  }
532 
533  return $res;
534  }
foreach($_POST as $key=> $value) $res
$i
Definition: disco.tpl.php:19
+ Here is the caller graph for this function:

◆ OLE2LocalDate()

static PhpOffice\PhpSpreadsheet\Shared\OLE::OLE2LocalDate (   $oleTimestamp)
static

Returns a timestamp from an OLE container's date.

Parameters
string$oleTimestampA binary string with the encoded date
Returns
float|int The Unix timestamp corresponding to the string

Definition at line 543 of file OLE.php.

References PhpOffice\PhpSpreadsheet\Shared\IntOrFloat\evaluate().

Referenced by PhpOffice\PhpSpreadsheet\Reader\Xls\readDocumentSummaryInformation(), and PhpOffice\PhpSpreadsheet\Reader\Xls\readSummaryInformation().

544  {
545  if (strlen($oleTimestamp) != 8) {
546  throw new ReaderException('Expecting 8 byte string');
547  }
548 
549  // convert to units of 100 ns since 1601:
550  $unpackedTimestamp = unpack('v4', $oleTimestamp);
551  $timestampHigh = (float) $unpackedTimestamp[4] * 65536 + (float) $unpackedTimestamp[3];
552  $timestampLow = (float) $unpackedTimestamp[2] * 65536 + (float) $unpackedTimestamp[1];
553 
554  // translate to seconds since 1601:
555  $timestampHigh /= 10000000;
556  $timestampLow /= 10000000;
557 
558  // days from 1601 to 1970:
559  $days = 134774;
560 
561  // translate to seconds since 1970:
562  $unixTimestamp = floor(65536.0 * 65536.0 * $timestampHigh + $timestampLow - $days * 24 * 3600 + 0.5);
563 
564  return IntOrFloat::evaluate($unixTimestamp);
565  }
static evaluate($value)
Help some functions with large results operate correctly on 32-bit, by returning result as int when p...
Definition: IntOrFloat.php:15
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ppsTotal()

PhpOffice\PhpSpreadsheet\Shared\OLE::ppsTotal ( )

Gives the total number of PPS's found in the OLE container.

Returns
int The total number of PPS's found in the OLE container

Definition at line 423 of file OLE.php.

424  {
425  return count($this->_list);
426  }

◆ ppsTreeComplete()

PhpOffice\PhpSpreadsheet\Shared\OLE::ppsTreeComplete (   $index)
private

It checks whether the PPS tree is complete (all PPS's read) starting with the given PPS (not necessarily root).

Parameters
int$indexThe index of the PPS from which we are checking
Returns
bool Whether the PPS tree for the given PPS is complete

Definition at line 372 of file OLE.php.

References $index.

Referenced by PhpOffice\PhpSpreadsheet\Shared\OLE\readPpsWks().

373  {
374  return isset($this->_list[$index]) &&
375  ($pps = $this->_list[$index]) &&
376  ($pps->PrevPps == -1 ||
377  $this->ppsTreeComplete($pps->PrevPps)) &&
378  ($pps->NextPps == -1 ||
379  $this->ppsTreeComplete($pps->NextPps)) &&
380  ($pps->DirPps == -1 ||
381  $this->ppsTreeComplete($pps->DirPps));
382  }
$index
Definition: metadata.php:60
+ Here is the caller graph for this function:

◆ read()

PhpOffice\PhpSpreadsheet\Shared\OLE::read (   $file)

Reads an OLE container from the contents of the file given.

public

Parameters
string$file
Returns
bool true on success, PEAR_Error on failure

Definition at line 117 of file OLE.php.

References $i, PhpOffice\PhpSpreadsheet\Shared\OLE\getBlockOffset(), PhpOffice\PhpSpreadsheet\Shared\OLE\getStream(), and PhpOffice\PhpSpreadsheet\Shared\OLE\readPpsWks().

118  {
119  $fh = fopen($file, 'rb');
120  if (!$fh) {
121  throw new ReaderException("Can't open file $file");
122  }
123  $this->_file_handle = $fh;
124 
125  $signature = fread($fh, 8);
126  if ("\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" != $signature) {
127  throw new ReaderException("File doesn't seem to be an OLE container.");
128  }
129  fseek($fh, 28);
130  if (fread($fh, 2) != "\xFE\xFF") {
131  // This shouldn't be a problem in practice
132  throw new ReaderException('Only Little-Endian encoding is supported.');
133  }
134  // Size of blocks and short blocks in bytes
135  $this->bigBlockSize = 2 ** self::readInt2($fh);
136  $this->smallBlockSize = 2 ** self::readInt2($fh);
137 
138  // Skip UID, revision number and version number
139  fseek($fh, 44);
140  // Number of blocks in Big Block Allocation Table
141  $bbatBlockCount = self::readInt4($fh);
142 
143  // Root chain 1st block
144  $directoryFirstBlockId = self::readInt4($fh);
145 
146  // Skip unused bytes
147  fseek($fh, 56);
148  // Streams shorter than this are stored using small blocks
149  $this->bigBlockThreshold = self::readInt4($fh);
150  // Block id of first sector in Short Block Allocation Table
151  $sbatFirstBlockId = self::readInt4($fh);
152  // Number of blocks in Short Block Allocation Table
153  $sbbatBlockCount = self::readInt4($fh);
154  // Block id of first sector in Master Block Allocation Table
155  $mbatFirstBlockId = self::readInt4($fh);
156  // Number of blocks in Master Block Allocation Table
157  $mbbatBlockCount = self::readInt4($fh);
158  $this->bbat = [];
159 
160  // Remaining 4 * 109 bytes of current block is beginning of Master
161  // Block Allocation Table
162  $mbatBlocks = [];
163  for ($i = 0; $i < 109; ++$i) {
164  $mbatBlocks[] = self::readInt4($fh);
165  }
166 
167  // Read rest of Master Block Allocation Table (if any is left)
168  $pos = $this->getBlockOffset($mbatFirstBlockId);
169  for ($i = 0; $i < $mbbatBlockCount; ++$i) {
170  fseek($fh, $pos);
171  for ($j = 0; $j < $this->bigBlockSize / 4 - 1; ++$j) {
172  $mbatBlocks[] = self::readInt4($fh);
173  }
174  // Last block id in each block points to next block
175  $pos = $this->getBlockOffset(self::readInt4($fh));
176  }
177 
178  // Read Big Block Allocation Table according to chain specified by $mbatBlocks
179  for ($i = 0; $i < $bbatBlockCount; ++$i) {
180  $pos = $this->getBlockOffset($mbatBlocks[$i]);
181  fseek($fh, $pos);
182  for ($j = 0; $j < $this->bigBlockSize / 4; ++$j) {
183  $this->bbat[] = self::readInt4($fh);
184  }
185  }
186 
187  // Read short block allocation table (SBAT)
188  $this->sbat = [];
189  $shortBlockCount = $sbbatBlockCount * $this->bigBlockSize / 4;
190  $sbatFh = $this->getStream($sbatFirstBlockId);
191  for ($blockId = 0; $blockId < $shortBlockCount; ++$blockId) {
192  $this->sbat[$blockId] = self::readInt4($sbatFh);
193  }
194  fclose($sbatFh);
195 
196  $this->readPpsWks($directoryFirstBlockId);
197 
198  return true;
199  }
getStream($blockIdOrPps)
Returns a stream for use with fread() etc.
Definition: OLE.php:219
readPpsWks($blockId)
Gets information about all PPS&#39;s on the OLE container from the PPS WK&#39;s creates an OLE_PPS object for...
Definition: OLE.php:295
$i
Definition: disco.tpl.php:19
+ Here is the call graph for this function:

◆ readInt1()

static PhpOffice\PhpSpreadsheet\Shared\OLE::readInt1 (   $fh)
staticprivate

Reads a signed char.

Parameters
resource$fhfile handle
Returns
int

Definition at line 252 of file OLE.php.

253  {
254  [, $tmp] = unpack('c', fread($fh, 1));
255 
256  return $tmp;
257  }

◆ readInt2()

static PhpOffice\PhpSpreadsheet\Shared\OLE::readInt2 (   $fh)
staticprivate

Reads an unsigned short (2 octets).

Parameters
resource$fhfile handle
Returns
int

Definition at line 266 of file OLE.php.

267  {
268  [, $tmp] = unpack('v', fread($fh, 2));
269 
270  return $tmp;
271  }

◆ readInt4()

static PhpOffice\PhpSpreadsheet\Shared\OLE::readInt4 (   $fh)
staticprivate

Reads an unsigned long (4 octets).

Parameters
resource$fhfile handle
Returns
int

Definition at line 280 of file OLE.php.

281  {
282  [, $tmp] = unpack('V', fread($fh, 4));
283 
284  return $tmp;
285  }

◆ readPpsWks()

PhpOffice\PhpSpreadsheet\Shared\OLE::readPpsWks (   $blockId)

Gets information about all PPS's on the OLE container from the PPS WK's creates an OLE_PPS object for each one.

Parameters
int$blockIdthe block id of the first block
Returns
bool true on success, PEAR_Error on failure

Definition at line 295 of file OLE.php.

References $name, $type, PhpOffice\PhpSpreadsheet\Shared\OLE\getStream(), and PhpOffice\PhpSpreadsheet\Shared\OLE\ppsTreeComplete().

Referenced by PhpOffice\PhpSpreadsheet\Shared\OLE\read().

296  {
297  $fh = $this->getStream($blockId);
298  for ($pos = 0; true; $pos += 128) {
299  fseek($fh, $pos, SEEK_SET);
300  $nameUtf16 = fread($fh, 64);
301  $nameLength = self::readInt2($fh);
302  $nameUtf16 = substr($nameUtf16, 0, $nameLength - 2);
303  // Simple conversion from UTF-16LE to ISO-8859-1
304  $name = str_replace("\x00", '', $nameUtf16);
305  $type = self::readInt1($fh);
306  switch ($type) {
307  case self::OLE_PPS_TYPE_ROOT:
308  $pps = new OLE\PPS\Root(null, null, []);
309  $this->root = $pps;
310 
311  break;
312  case self::OLE_PPS_TYPE_DIR:
313  $pps = new OLE\PPS(null, null, null, null, null, null, null, null, null, []);
314 
315  break;
316  case self::OLE_PPS_TYPE_FILE:
317  $pps = new OLE\PPS\File($name);
318 
319  break;
320  default:
321  throw new Exception('Unsupported PPS type');
322  }
323  fseek($fh, 1, SEEK_CUR);
324  $pps->Type = $type;
325  $pps->Name = $name;
326  $pps->PrevPps = self::readInt4($fh);
327  $pps->NextPps = self::readInt4($fh);
328  $pps->DirPps = self::readInt4($fh);
329  fseek($fh, 20, SEEK_CUR);
330  $pps->Time1st = self::OLE2LocalDate(fread($fh, 8));
331  $pps->Time2nd = self::OLE2LocalDate(fread($fh, 8));
332  $pps->startBlock = self::readInt4($fh);
333  $pps->Size = self::readInt4($fh);
334  $pps->No = count($this->_list);
335  $this->_list[] = $pps;
336 
337  // check if the PPS tree (starting from root) is complete
338  if (isset($this->root) && $this->ppsTreeComplete($this->root->No)) {
339  break;
340  }
341  }
342  fclose($fh);
343 
344  // Initialize $pps->children on directories
345  foreach ($this->_list as $pps) {
346  if ($pps->Type == self::OLE_PPS_TYPE_DIR || $pps->Type == self::OLE_PPS_TYPE_ROOT) {
347  $nos = [$pps->DirPps];
348  $pps->children = [];
349  while ($nos) {
350  $no = array_pop($nos);
351  if ($no != -1) {
352  $childPps = $this->_list[$no];
353  $nos[] = $childPps->PrevPps;
354  $nos[] = $childPps->NextPps;
355  $pps->children[] = $childPps;
356  }
357  }
358  }
359  }
360 
361  return true;
362  }
$type
getStream($blockIdOrPps)
Returns a stream for use with fread() etc.
Definition: OLE.php:219
ppsTreeComplete($index)
It checks whether the PPS tree is complete (all PPS&#39;s read) starting with the given PPS (not necessar...
Definition: OLE.php:372
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Field Documentation

◆ $_file_handle

PhpOffice\PhpSpreadsheet\Shared\OLE::$_file_handle

Definition at line 57 of file OLE.php.

◆ $_list

PhpOffice\PhpSpreadsheet\Shared\OLE::$_list = []

Definition at line 64 of file OLE.php.

◆ $bbat

PhpOffice\PhpSpreadsheet\Shared\OLE::$bbat

Definition at line 78 of file OLE.php.

◆ $bigBlockSize

PhpOffice\PhpSpreadsheet\Shared\OLE::$bigBlockSize

Definition at line 92 of file OLE.php.

Referenced by PhpOffice\PhpSpreadsheet\Shared\OLE\getBlockOffset().

◆ $bigBlockThreshold

PhpOffice\PhpSpreadsheet\Shared\OLE::$bigBlockThreshold

Definition at line 106 of file OLE.php.

◆ $root

PhpOffice\PhpSpreadsheet\Shared\OLE::$root

Definition at line 71 of file OLE.php.

◆ $sbat

PhpOffice\PhpSpreadsheet\Shared\OLE::$sbat

Definition at line 85 of file OLE.php.

◆ $smallBlockSize

PhpOffice\PhpSpreadsheet\Shared\OLE::$smallBlockSize

Definition at line 99 of file OLE.php.

◆ OLE_DATA_SIZE_SMALL

const PhpOffice\PhpSpreadsheet\Shared\OLE::OLE_DATA_SIZE_SMALL = 0x1000

◆ OLE_LONG_INT_SIZE

◆ OLE_PPS_SIZE

const PhpOffice\PhpSpreadsheet\Shared\OLE::OLE_PPS_SIZE = 0x80

◆ OLE_PPS_TYPE_DIR

const PhpOffice\PhpSpreadsheet\Shared\OLE::OLE_PPS_TYPE_DIR = 1

Definition at line 46 of file OLE.php.

Referenced by PhpOffice\PhpSpreadsheet\Shared\OLE\PPS\Root\saveBigData().

◆ OLE_PPS_TYPE_FILE

◆ OLE_PPS_TYPE_ROOT

const PhpOffice\PhpSpreadsheet\Shared\OLE::OLE_PPS_TYPE_ROOT = 5

The documentation for this class was generated from the following file: