-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add support for uncompressed and LZ4 compressed chunks
- Loading branch information
1 parent
7ccec35
commit 7a0fc84
Showing
9 changed files
with
453 additions
and
145 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
.idea/ | ||
vendor/ | ||
test.php |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
<?php | ||
|
||
namespace Aternos\Thanos\Reader; | ||
|
||
use Exception; | ||
|
||
/** | ||
* @package Aternos\Thanos\Reader | ||
*/ | ||
abstract class BufferedReader implements ReaderInterface | ||
{ | ||
/** | ||
* @var int | ||
*/ | ||
protected int $offset; | ||
|
||
/** | ||
* @var int | ||
*/ | ||
protected int $length; | ||
|
||
/** | ||
* @var int | ||
*/ | ||
protected int $resourcePointer; | ||
|
||
/** | ||
* @var int | ||
*/ | ||
protected int $pointer = 0; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
protected string $data = ''; | ||
|
||
/** | ||
* @var resource | ||
*/ | ||
protected $resource; | ||
|
||
/** | ||
* ZlibReader constructor. | ||
* | ||
* @param $resource | ||
* @param int $offset | ||
* @param int $length | ||
*/ | ||
public function __construct( | ||
$resource, | ||
int $offset, | ||
int $length | ||
) { | ||
$this->offset = $offset; | ||
$this->resourcePointer = $offset; | ||
$this->length = $length; | ||
$this->resource = $resource; | ||
} | ||
|
||
/** | ||
* Read $length bytes of data | ||
* | ||
* @param int $length | ||
* @return string | ||
* @throws Exception | ||
*/ | ||
public function read(int $length): string | ||
{ | ||
$readLength = max( | ||
$length - (strlen($this->data) - $this->pointer), | ||
0 | ||
); | ||
|
||
if ($readLength > 0) { | ||
$chunk = ""; | ||
while (strlen($chunk) < $readLength && $this->getRemainingRawLength() > 0) { | ||
$chunk .= $this->getRawChunk($readLength - strlen($chunk)); | ||
} | ||
$this->data .= $chunk; | ||
} | ||
|
||
$data = substr($this->data, $this->pointer, $length); | ||
$this->pointer += strlen($data); | ||
|
||
return $data; | ||
} | ||
|
||
/** | ||
* @param int $length | ||
* @return string | ||
* @throws Exception | ||
*/ | ||
protected function readRaw(int $length): string | ||
{ | ||
if ($length <= 0) { | ||
return ''; | ||
} | ||
fseek($this->resource, $this->resourcePointer); | ||
$rawData = fread( | ||
$this->resource, | ||
min( | ||
$length, | ||
$this->getRemainingRawLength() | ||
) | ||
); | ||
if($rawData === false) { | ||
throw new Exception("Failed to read compressed input data."); | ||
} | ||
|
||
$this->resourcePointer = ftell($this->resource) ?: $this->resourcePointer + strlen($rawData); | ||
return $rawData; | ||
} | ||
|
||
/** | ||
* @return int | ||
*/ | ||
protected function getRemainingRawLength(): int | ||
{ | ||
return $this->offset + $this->length - $this->resourcePointer; | ||
} | ||
|
||
/** | ||
* Read and uncompress a chunk of data | ||
* $length is just a suggestion, the actual length of the returned data may be longer or shorter | ||
* | ||
* @param int $length | ||
* @return string | ||
*/ | ||
protected abstract function getRawChunk(int $length): string; | ||
|
||
/** | ||
* Set pointer position to $offset | ||
* | ||
* @param int $offset | ||
*/ | ||
public function seek(int $offset): void | ||
{ | ||
$this->pointer = max($offset, 0); | ||
} | ||
|
||
/** | ||
* Set pointer position to 0 | ||
* | ||
*/ | ||
public function rewind(): void | ||
{ | ||
$this->pointer = 0; | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
public function reset(): void | ||
{ | ||
$this->data = ''; | ||
$this->pointer = 0; | ||
$this->resourcePointer = $this->offset; | ||
} | ||
|
||
public function eof(): bool | ||
{ | ||
return ($this->resourcePointer >= $this->offset + $this->length || feof($this->resource)) | ||
&& $this->pointer >= strlen($this->data); | ||
} | ||
|
||
/** | ||
* Get current pointer position | ||
* | ||
* @return int | ||
*/ | ||
public function tell(): int | ||
{ | ||
return $this->pointer; | ||
} | ||
} |
Oops, something went wrong.