mirror of
https://github.com/Rogiel/php-mpq
synced 2025-12-06 08:23:05 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a8091dfa7d |
@@ -49,7 +49,7 @@ class DeflateCompression implements Compression {
|
||||
*/
|
||||
public function decompress($data, $length) {
|
||||
$output = @gzinflate(substr($data, 0, $length), $length);
|
||||
if(!is_string($output)) {
|
||||
if($output === false) {
|
||||
throw new InvalidInputDataException('The decompression input data is invalid.', $output);
|
||||
}
|
||||
return $output;
|
||||
|
||||
@@ -81,6 +81,10 @@ class MPQFile {
|
||||
$this->stream = $stream;
|
||||
}
|
||||
|
||||
function __destruct() {
|
||||
$this->stream->close();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
|
||||
public function isParsed() {
|
||||
@@ -98,9 +102,10 @@ class MPQFile {
|
||||
if($signature == "MPQ27") {
|
||||
$this->userData = UserData::parse($parser);
|
||||
$this->stream->seek($this->getUserDataOffset());
|
||||
|
||||
$signature = $this->parseSignature($parser);
|
||||
}
|
||||
|
||||
$signature = $this->parseSignature($parser);
|
||||
if($signature == "MPQ26") {
|
||||
$this->header = Header::parse($parser);
|
||||
}
|
||||
@@ -137,6 +142,7 @@ class MPQFile {
|
||||
// $offsetFix++;
|
||||
// }
|
||||
}
|
||||
|
||||
return new BlockTable($blocks);
|
||||
}
|
||||
|
||||
@@ -151,7 +157,7 @@ class MPQFile {
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
|
||||
private function getUserDataOffset() {
|
||||
public function getUserDataOffset() {
|
||||
$userData = $this->getUserData();
|
||||
if($userData === null) {
|
||||
return 0;
|
||||
@@ -200,7 +206,7 @@ class MPQFile {
|
||||
|
||||
$sectors = array();
|
||||
if($block->isChecksumed() || !$block->isSingleUnit()) {
|
||||
$blockSize = $block->getCompressedSize();
|
||||
$blockSize = 512 * (1 << $this->getHeader()->getBlockSize());
|
||||
$fileSize = $block->getSize();
|
||||
|
||||
for ($i = $fileSize; $i > 0; $i -= $blockSize) {
|
||||
|
||||
@@ -35,6 +35,7 @@ use Rogiel\MPQ\Exception\Compression\CompressionException;
|
||||
use Rogiel\MPQ\Metadata\Block;
|
||||
use Rogiel\MPQ\MPQFile;
|
||||
use Rogiel\MPQ\Stream\CompressedStream;
|
||||
use Rogiel\MPQ\Stream\MemoryStream;
|
||||
use Rogiel\MPQ\Stream\Parser\BinaryStreamParser;
|
||||
use Rogiel\MPQ\Stream\Stream;
|
||||
|
||||
@@ -109,7 +110,7 @@ class BlockStream implements Stream {
|
||||
}
|
||||
|
||||
public function readBytes($bytes) {
|
||||
if($this->eof()) {
|
||||
if($this->eof()) {
|
||||
return false;
|
||||
}
|
||||
if(($this->position + $bytes) > $this->block->getSize()) {
|
||||
@@ -119,7 +120,11 @@ class BlockStream implements Stream {
|
||||
if($this->buffer === NULL) {
|
||||
$this->buffer = $this->readSector($this->currentSector);
|
||||
$this->positionInSector = 0;
|
||||
} else if($this->positionInSector >= strlen($this->buffer)) {
|
||||
} else if($this->positionInSector >= strlen($this->buffer)) {
|
||||
if(!isset($this->sectors[$this->currentSector->getIndex() + 1])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->currentSector = $this->sectors[$this->currentSector->getIndex() + 1];
|
||||
$this->buffer = $this->readSector($this->currentSector);
|
||||
$this->positionInSector = 0;
|
||||
@@ -157,23 +162,28 @@ class BlockStream implements Stream {
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
|
||||
private function readSector(Sector $sector) {
|
||||
$this->stream->seek($this->file->getUserData()->getHeaderOffset()
|
||||
$this->stream->seek($this->file->getUserDataOffset()
|
||||
+ $this->block->getFilePos()
|
||||
+ $sector->getStart());
|
||||
|
||||
$compressedStream = $this->createCompressedStream();
|
||||
return $compressedStream->readBytes($sector->getLength());
|
||||
$compressedStream = $this->createCompressedStream($sector);
|
||||
return $compressedStream->readBytes($this->block->getSize());
|
||||
}
|
||||
|
||||
private function createCompressedStream() {
|
||||
private function createCompressedStream(Sector $sector) {
|
||||
$stream = $this->stream;
|
||||
|
||||
if($this->block->isCompressed() && $this->block->getSize() > $this->block->getCompressedSize()) {
|
||||
if($this->block->isCompressed() && $this->block->getSize() > $this->block->getCompressedSize()) {
|
||||
$parser = new BinaryStreamParser($this->stream);
|
||||
$compressionType = $parser->readByte();
|
||||
switch ($compressionType) {
|
||||
case 0x00: return $stream;
|
||||
case 0x02: return new CompressedStream($stream, new DeflateCompression());
|
||||
case 0x02: {
|
||||
$len = $parser->readUInt16();
|
||||
$blockData = $stream->readBytes($len);
|
||||
return new MemoryStream(gzinflate($blockData));
|
||||
}
|
||||
// case 0x02: return new CompressedStream($stream, new DeflateCompression());
|
||||
case 0x10: return new CompressedStream($stream, new BZIPCompression());
|
||||
default:
|
||||
throw new CompressionException(sprintf('Invalid compression format: %s', $compressionType));
|
||||
|
||||
@@ -40,14 +40,22 @@ class FileStream implements Stream {
|
||||
$this->handle = fopen($file, 'r');
|
||||
}
|
||||
|
||||
public function __clone() {
|
||||
$this->handle = fopen($this->file, 'r');
|
||||
}
|
||||
|
||||
function __destruct() {
|
||||
$this->close();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function close() {
|
||||
fclose($this->handle);
|
||||
}
|
||||
@fclose($this->handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -84,10 +92,4 @@ class FileStream implements Stream {
|
||||
return feof($this->handle);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
|
||||
public function __clone() {
|
||||
return new FileStream($this->file);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -69,6 +69,17 @@ class BinaryStreamParser {
|
||||
return $this->stream->readBytes($size);
|
||||
}
|
||||
|
||||
public function readCString($debug=false) {
|
||||
$str = '';
|
||||
while(true) {
|
||||
$c = $this->stream->readBytes(1);
|
||||
if($c == "\0") {
|
||||
return $str;
|
||||
}
|
||||
$str .= (string) $c;
|
||||
}
|
||||
}
|
||||
|
||||
public function eof() {
|
||||
return $this->stream->eof();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user