コード例 #1
0
 /**
  * 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();
 }