Example #1
0
 /**
  * Initializes the instance.
  *
  * @param string $string The raw string containing the data to be read.
  */
 public function __construct($string)
 {
     parent::__construct($string);
     $this->buffer = 0;
     $this->bufferSize = 0;
 }
Example #2
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();
 }
Example #3
0
 /**
  * Retrieve the list of the data sections contained in this CHM.
  *
  * @throws Exception Throws an Exception in case of errors.
  */
 protected function retrieveSectionList()
 {
     $nameList = $this->getEntryByPath('::DataSpace/NameList');
     if ($nameList === null) {
         throw new Exception("Missing required entry: '::DataSpace/NameList'");
     }
     if ($nameList->getContentSectionIndex() !== 0) {
         throw new Exception("The content of the entry '{$nameList->getPath()}' should be in section 0, but it's in section {$nameList->getContentSection()}");
     }
     $nameListReader = new StringReader($nameList->getContents());
     /* Length */
     $nameListReader->readUInt16();
     $numSections = $nameListReader->readUInt16();
     if ($numSections === 0) {
         throw new Exception('No content section defined.');
     }
     for ($i = 0; $i < $numSections; ++$i) {
         $nameLength = $nameListReader->readUInt16();
         $utf16name = $nameListReader->readString($nameLength * 2);
         $nameListReader->readUInt16();
         $name = iconv('UTF-16LE', 'UTF-8', $utf16name);
         switch ($name) {
             case 'Uncompressed':
                 break;
             case 'MSCompressed':
                 if ($i === 0) {
                     throw new Exception('First data section should be Uncompressed');
                 } else {
                     $this->sections[$i] = new Section\MSCompressedSection($this);
                 }
                 break;
             default:
                 throw new Exception("Unknown data section: {$name}");
         }
     }
 }