From 00488262cff699007da20a56e008fb079f25acd3 Mon Sep 17 00:00:00 2001 From: Paul Duncan Date: Sun, 2 Sep 2018 13:40:44 -0400 Subject: add StreamWriter --- examples/07-stream_writer.php | 30 +++++++++++++ src/ZipStream.php | 97 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 125 insertions(+), 2 deletions(-) create mode 100644 examples/07-stream_writer.php diff --git a/examples/07-stream_writer.php b/examples/07-stream_writer.php new file mode 100644 index 0000000..d94e7ac --- /dev/null +++ b/examples/07-stream_writer.php @@ -0,0 +1,30 @@ + new StreamWriter($out_stream), +]); + +# add a file named "hello.txt" to output archive, containing +# the string "hello world!" +$zip->add_file('hello.txt', 'hello world!'); + +# finalize archive +$zip->close(); + +# close output stream +fclose($out_stream); diff --git a/src/ZipStream.php b/src/ZipStream.php index 2759d4d..b3f41dd 100644 --- a/src/ZipStream.php +++ b/src/ZipStream.php @@ -177,8 +177,6 @@ final class HTTPResponseWriter implements Writer { * @api * * {@example ../examples/06-file_writer.php} - * - * @see Writer */ final class FileWriter implements Writer { /** @var string Output file path. */ @@ -303,6 +301,101 @@ final class FileWriter implements Writer { } }; +/** + * Write generated zip archive to a stream. + * + * @api + * + * {@example ../examples/07-stream_writer.php} + */ +final class StreamWriter implements Writer { + /** @var resource Output stream. */ + public $stream; + + const STREAM_WRITER_STATE_INIT = 0; + const STREAM_WRITER_STATE_OPEN = 1; + const STREAM_WRITER_STATE_CLOSED = 2; + const STREAM_WRITER_STATE_ERROR = 3; + + /** + * Create a new StreamWriter. + * + * @api + */ + public function __construct($stream) { + # check stream + if (!is_resource($stream)) { + $this->state = self::STREAM_WRITER_STATE_ERROR; + throw new Error('stream is not a resource'); + } + + # set state, cache stream + $this->state = self::STREAM_WRITER_STATE_INIT; + $this->stream = $stream; + } + + public function set(string $key, string $val) : void { + # ignore metadata + } + + public function open() : void { + # set state + $this->state = self::STREAM_WRITER_STATE_OPEN; + } + + /** + * Write archive contents. + * + * @param string $data Archive file data. + * + * @return void + */ + public function write(string $data) : void { + # check state + if ($this->state != self::STREAM_WRITER_STATE_OPEN) { + # set state, raise error + $this->state = self::STREAM_WRITER_STATE_ERROR; + throw new Error("invalid output state"); + } + + # write data + $len = fwrite($this->stream, $data); + + # check for error + if ($len === false) { + # set state, raise error + $this->state = self::STREAM_WRITER_STATE_ERROR; + throw new Error('fwrite() failed'); + } + } + + /** + * Finish writing archive data. + * + * @return void + */ + public function close() : void { + # check state + if ($this->state == self::STREAM_WRITER_STATE_CLOSED) { + return; + } else if ($this->state != self::STREAM_WRITER_STATE_OPEN) { + # set state, raise error + $this->state = self::STREAM_WRITER_STATE_ERROR; + throw new Error("invalid output state"); + } + + # flush output + if (!@fflush($this->stream)) { + # set state, raise error + $this->state = self::STREAM_WRITER_STATE_ERROR; + throw new Error("fflush() failed"); + } + + # set state + $this->state = self::STREAM_WRITER_STATE_CLOSED; + } +}; + /** * Convert a UNIX timestamp into DOS date and time components. * @internal -- cgit v1.2.3