/** * Initializes the instance. * * @param CHM $chm The parent CHM file. * * @throws Exception Throws an Exception in case of errors. */ public function __construct(CHM $chm) { parent::__construct($chm); $controlDataEntry = $chm->getEntryByPath('::DataSpace/Storage/MSCompressed/ControlData'); if ($controlDataEntry === null) { throw new Exception("Missing required entry: '::DataSpace/Storage/MSCompressed/ControlData'"); } if ($controlDataEntry->getContentSectionIndex() !== 0) { throw new Exception("The content of the entry '{$controlDataEntry->getPath()}' should be in section 0, but it's in section {$controlDataEntry->getContentSectionIndex()}"); } $controlDataReader = new StringReader($controlDataEntry->getContents()); $lzxc = new LZXC($controlDataReader); $this->resetInterval = $lzxc->getResetInterval(); $this->windowSize = $lzxc->getWindowSize() * 32768; $this->cachedBlocks = new LRUCache(1 + $lzxc->getCacheSize() << 2); $resetTableEntry = $chm->getEntryByPath('::DataSpace/Storage/MSCompressed/Transform/{7FC28940-9D31-11D0-9B27-00A0C91E9C7C}/InstanceData/ResetTable'); if ($resetTableEntry === null) { throw new Exception("Missing required entry: '::DataSpace/Storage/MSCompressed/Transform/{7FC28940-9D31-11D0-9B27-00A0C91E9C7C}/InstanceData/ResetTable'"); } if ($resetTableEntry->getContentSectionIndex() !== 0) { throw new Exception("The content of the entry '{$resetTableEntry->getPath()}' should be in section 0, but it's in section {$resetTableEntry->getContentSectionIndex()}"); } $resetTableReader = new StringReader($resetTableEntry->getContents()); $resetTableVersion = $resetTableReader->readUInt32(); if ($resetTableVersion !== 2) { throw new Exception("Unsupported LZX Reset Table version: {$resetTableVersion}"); } $addressTableSize = $resetTableReader->readUInt32(); /* Size of table entry (8) */ $resetTableReader->readUInt32(); /* Header length (40) */ $resetTableReader->readUInt32(); $this->uncompressedLength = $resetTableReader->readUInt64(); $this->compressedLength = $resetTableReader->readUInt64(); $this->blockSize = $resetTableReader->readUInt64(); // We do not support block sizes bigger than 32-bit integers $this->addressTable = array(); for ($i = 0; $i < $addressTableSize; ++$i) { $this->addressTable[$i] = $resetTableReader->readUInt64(); } $contentEntry = $chm->getEntryByPath('::DataSpace/Storage/MSCompressed/Content'); if ($contentEntry === null) { throw new Exception("Missing required entry: '::DataSpace/Storage/MSCompressed/Content"); } if ($this->compressedLength > $contentEntry->getLength()) { throw new Exception("Compressed section size should be {$this->compressedLength}, but it's {$contentEntry->getLength()}"); } $this->sectionOffset = $chm->getITSF()->getContentOffset() + $contentEntry->getOffset(); }
/** * Initializes the instance. * * @param CHM $chm The parent CHM file. */ public function __construct(CHM $chm) { parent::__construct($chm); $this->sectionOffset = $chm->getITSF()->getContentOffset(); }