1
0
mirror of https://github.com/danog/byte-stream.git synced 2024-11-26 20:04:51 +01:00
byte-stream/lib/ZlibInputStream.php

103 lines
2.6 KiB
PHP
Raw Normal View History

2017-05-05 22:39:39 +02:00
<?php
namespace Amp\ByteStream;
use Amp\Promise;
use function Amp\call;
2017-05-25 17:51:25 +02:00
/**
* Allows decompression of input streams using Zlib.
*/
2018-09-21 22:45:13 +02:00
final class ZlibInputStream implements InputStream
{
2017-05-05 22:39:39 +02:00
private $source;
private $encoding;
private $options;
2017-05-05 22:39:39 +02:00
private $resource;
/**
2017-05-25 17:51:25 +02:00
* @param InputStream $source Input stream to read compressed data from.
* @param int $encoding Compression algorithm used, see `inflate_init()`.
* @param array $options Algorithm options, see `inflate_init()`.
*
* @throws StreamException
* @throws \Error
*
* @see http://php.net/manual/en/function.inflate-init.php
*/
2018-09-21 22:45:13 +02:00
public function __construct(InputStream $source, int $encoding, array $options = [])
{
2017-05-05 22:39:39 +02:00
$this->source = $source;
$this->encoding = $encoding;
$this->options = $options;
$this->resource = @\inflate_init($encoding, $options);
2017-05-05 22:39:39 +02:00
if ($this->resource === false) {
throw new StreamException("Failed initializing deflate context");
}
}
2017-05-25 17:51:25 +02:00
/** @inheritdoc */
2018-09-21 22:45:13 +02:00
public function read(): Promise
{
2017-05-05 22:39:39 +02:00
return call(function () {
if ($this->resource === null) {
return null;
}
2017-05-05 22:39:39 +02:00
$data = yield $this->source->read();
// Needs a double guard, as stream might have been closed while reading
if ($this->resource === null) {
return null;
}
2017-05-05 22:39:39 +02:00
if ($data === null) {
2017-10-06 22:25:55 +02:00
$decompressed = @\inflate_add($this->resource, "", \ZLIB_FINISH);
2017-05-05 22:39:39 +02:00
if ($decompressed === false) {
throw new StreamException("Failed adding data to deflate context");
}
$this->close();
2017-05-05 22:39:39 +02:00
return $decompressed;
}
2017-10-06 22:25:55 +02:00
$decompressed = @\inflate_add($this->resource, $data, \ZLIB_SYNC_FLUSH);
2017-05-05 22:39:39 +02:00
if ($decompressed === false) {
throw new StreamException("Failed adding data to deflate context");
}
return $decompressed;
});
}
2017-05-25 17:51:25 +02:00
/** @internal */
2018-09-21 22:45:13 +02:00
private function close()
{
$this->resource = null;
$this->source = null;
2017-05-05 22:39:39 +02:00
}
2017-05-25 17:51:25 +02:00
/**
* Gets the used compression encoding.
*
* @return int Encoding specified on construction time.
*/
2018-09-21 22:45:13 +02:00
public function getEncoding(): int
{
return $this->encoding;
}
2017-05-25 17:51:25 +02:00
/**
* Gets the used compression options.
*
* @return array Options array passed on construction time.
*/
2018-09-21 22:45:13 +02:00
public function getOptions(): array
{
return $this->options;
}
2017-05-07 22:14:45 +02:00
}