96    public function read(
string $pFilename): void
 
  102        $this->
data = file_get_contents($pFilename, 
false, 
null, 0, 8);
 
  105        $identifierOle = pack(
'CCCCCCCC', 0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1);
 
  106        if ($this->
data != $identifierOle) {
 
  107            throw new ReaderException(
'The filename ' . $pFilename . 
' is not recognised as an OLE file');
 
  111        $this->
data = file_get_contents($pFilename);
 
  114        $this->numBigBlockDepotBlocks = 
self::getInt4d($this->
data, self::NUM_BIG_BLOCK_DEPOT_BLOCKS_POS);
 
  120        $this->sbdStartBlock = 
self::getInt4d($this->
data, self::SMALL_BLOCK_DEPOT_BLOCK_POS);
 
  126        $this->numExtensionBlocks = 
self::getInt4d($this->
data, self::NUM_EXTENSION_BLOCK_POS);
 
  128        $bigBlockDepotBlocks = [];
 
  133        if ($this->numExtensionBlocks != 0) {
 
  137        for (
$i = 0; 
$i < $bbdBlocks; ++
$i) {
 
  143            $pos = ($this->extensionBlock + 1) * self::BIG_BLOCK_SIZE;
 
  144            $blocksToRead = min($this->numBigBlockDepotBlocks - $bbdBlocks, self::BIG_BLOCK_SIZE / 4 - 1);
 
  146            for (
$i = $bbdBlocks; 
$i < $bbdBlocks + $blocksToRead; ++
$i) {
 
  151            $bbdBlocks += $blocksToRead;
 
  152            if ($bbdBlocks < $this->numBigBlockDepotBlocks) {
 
  158        $this->bigBlockChain = 
'';
 
  159        $bbs = self::BIG_BLOCK_SIZE / 4;
 
  161            $pos = ($bigBlockDepotBlocks[
$i] + 1) * self::BIG_BLOCK_SIZE;
 
  163            $this->bigBlockChain .= substr($this->
data, $pos, 4 * $bbs);
 
  169        $this->smallBlockChain = 
'';
 
  170        while ($sbdBlock != -2) {
 
  171            $pos = ($sbdBlock + 1) * self::BIG_BLOCK_SIZE;
 
  173            $this->smallBlockChain .= substr($this->
data, $pos, 4 * $bbs);
 
  181        $this->entry = $this->
readData($block);
 
  201        if ($this->props[
$stream][
'size'] < self::SMALL_BLOCK_THRESHOLD) {
 
  202            $rootdata = $this->
readData($this->props[$this->rootentry][
'startBlock']);
 
  204            $block = $this->props[
$stream][
'startBlock'];
 
  206            while ($block != -2) {
 
  208                $streamData .= substr($rootdata, $pos, self::SMALL_BLOCK_SIZE);
 
  216        if ($this->props[
$stream][
'size'] % self::BIG_BLOCK_SIZE != 0) {
 
  220        if ($numBlocks == 0) {
 
  224        $block = $this->props[
$stream][
'startBlock'];
 
  226        while ($block != -2) {
 
  227            $pos = ($block + 1) * self::BIG_BLOCK_SIZE;
 
  228            $streamData .= substr($this->
data, $pos, self::BIG_BLOCK_SIZE);
 
  247        while ($block != -2) {
 
  248            $pos = ($block + 1) * self::BIG_BLOCK_SIZE;
 
  249            $data .= substr($this->
data, $pos, self::BIG_BLOCK_SIZE);
 
  264        $entryLen = strlen($this->entry);
 
  265        while ($offset < $entryLen) {
 
  267            $d = substr($this->entry, $offset, self::PROPERTY_STORAGE_BLOCK_SIZE);
 
  270            $nameSize = ord(
$d[self::SIZE_OF_NAME_POS]) | (ord(
$d[self::SIZE_OF_NAME_POS + 1]) << 8);
 
  273            $type = ord(
$d[self::TYPE_POS]);
 
  281            $name = str_replace(
"\x00", 
'', substr(
$d, 0, $nameSize));
 
  286                'startBlock' => $startBlock,
 
  291            $upName = strtoupper(
$name);
 
  294            if (($upName === 
'WORKBOOK') || ($upName === 
'BOOK')) {
 
  295                $this->wrkbook = count($this->props) - 1;
 
  296            } elseif ($upName === 
'ROOT ENTRY' || $upName === 
'R') {
 
  298                $this->rootentry = count($this->props) - 1;
 
  302            if (
$name == chr(5) . 
'SummaryInformation') {
 
  303                $this->summaryInformation = count($this->props) - 1;
 
  307            if (
$name == chr(5) . 
'DocumentSummaryInformation') {
 
  308                $this->documentSummaryInformation = count($this->props) - 1;
 
  327            throw new ReaderException(
'Parameter pos=' . $pos . 
' is invalid.');
 
  330        $len = strlen(
$data);
 
  331        if ($len < $pos + 4) {
 
  332            $data .= str_repeat(
"\0", $pos + 4 - $len);
 
  338        $_or_24 = ord(
$data[$pos + 3]);
 
  339        if ($_or_24 >= 128) {
 
  341            $_ord_24 = -abs((256 - $_or_24) << 24);
 
  343            $_ord_24 = ($_or_24 & 127) << 24;
 
  346        return ord(
$data[$pos]) | (ord(
$data[$pos + 1]) << 8) | (ord(
$data[$pos + 2]) << 16) | $_ord_24;
 
An exception for terminatinating execution or to throw for unit testing.
static assertFile($filename)
Assert that given path is an existing file and is readable, otherwise throw exception.
const ROOT_START_BLOCK_POS
const NUM_BIG_BLOCK_DEPOT_BLOCKS_POS
getStream($stream)
Extract binary stream data.
static getInt4d($data, $pos)
Read 4 bytes of data at specified position.
const SMALL_BLOCK_THRESHOLD
$documentSummaryInformation
const EXTENSION_BLOCK_POS
readData($bl)
Read a standard stream (by joining sectors using information from SAT).
readPropertySets()
Read entries in the directory stream.
const PROPERTY_STORAGE_BLOCK_SIZE
const SMALL_BLOCK_DEPOT_BLOCK_POS
read(string $pFilename)
Read the file.
const NUM_EXTENSION_BLOCK_POS
const BIG_BLOCK_DEPOT_BLOCKS_POS
for( $i=6;$i< 13;$i++) for($i=1; $i< 13; $i++) $d
$stream
PHP stream implementation.