From 98187667421cb4cc09432c8948128754a7004382 Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Mon, 26 Dec 2022 18:42:39 +0100 Subject: [PATCH] LibCompress: Port `ZlibCompressor` to `Core::Stream` --- Userland/Libraries/LibCompress/Zlib.cpp | 65 +++++++++++++++---------- Userland/Libraries/LibCompress/Zlib.h | 22 ++++++--- 2 files changed, 54 insertions(+), 33 deletions(-) diff --git a/Userland/Libraries/LibCompress/Zlib.cpp b/Userland/Libraries/LibCompress/Zlib.cpp index 8c9ea5e4ef..40c67acf8c 100644 --- a/Userland/Libraries/LibCompress/Zlib.cpp +++ b/Userland/Libraries/LibCompress/Zlib.cpp @@ -10,6 +10,7 @@ #include #include #include +#include namespace Compress { @@ -68,21 +69,22 @@ u32 ZlibDecompressor::checksum() return m_checksum; } -ErrorOr> ZlibCompressor::construct(OutputStream& stream, ZlibCompressionLevel compression_level) +ErrorOr> ZlibCompressor::construct(Core::Stream::Handle stream, ZlibCompressionLevel compression_level) { // Zlib only defines Deflate as a compression method. auto compression_method = ZlibCompressionMethod::Deflate; - auto zlib_compressor = TRY(adopt_nonnull_own_or_enomem(new (nothrow) ZlibCompressor(stream, compression_level))); - zlib_compressor->write_header(compression_method, compression_level); + auto zlib_compressor = TRY(adopt_nonnull_own_or_enomem(new (nothrow) ZlibCompressor(move(stream), compression_level))); + TRY(zlib_compressor->write_header(compression_method, compression_level)); return zlib_compressor; } -ZlibCompressor::ZlibCompressor(OutputStream& stream, ZlibCompressionLevel compression_level) - : m_output_stream(stream) +ZlibCompressor::ZlibCompressor(Core::Stream::Handle stream, ZlibCompressionLevel compression_level) + : m_ak_output_stream(make(*stream)) + , m_output_stream(move(stream)) // FIXME: Find a way to compress with Deflate's "Best" compression level. - , m_compressor(make(stream, static_cast(compression_level))) + , m_compressor(make(*m_ak_output_stream, static_cast(compression_level))) { } @@ -91,7 +93,7 @@ ZlibCompressor::~ZlibCompressor() VERIFY(m_finished); } -void ZlibCompressor::write_header(ZlibCompressionMethod compression_method, ZlibCompressionLevel compression_level) +ErrorOr ZlibCompressor::write_header(ZlibCompressionMethod compression_method, ZlibCompressionLevel compression_level) { u8 compression_info = 0; if (compression_method == ZlibCompressionMethod::Deflate) { @@ -110,10 +112,17 @@ void ZlibCompressor::write_header(ZlibCompressionMethod compression_method, Zlib // FIXME: Support pre-defined dictionaries. - m_output_stream << header.as_u16; + TRY(m_output_stream->write(header.as_u16.bytes())); + + return {}; } -size_t ZlibCompressor::write(ReadonlyBytes bytes) +ErrorOr ZlibCompressor::read(Bytes) +{ + return Error::from_errno(EBADF); +} + +ErrorOr ZlibCompressor::write(ReadonlyBytes bytes) { VERIFY(!m_finished); @@ -122,17 +131,21 @@ size_t ZlibCompressor::write(ReadonlyBytes bytes) return n_written; } -bool ZlibCompressor::write_or_error(ReadonlyBytes bytes) +bool ZlibCompressor::is_eof() const { - if (write(bytes) < bytes.size()) { - set_fatal_error(); - return false; - } - - return true; + return false; } -void ZlibCompressor::finish() +bool ZlibCompressor::is_open() const +{ + return m_output_stream->is_open(); +} + +void ZlibCompressor::close() +{ +} + +ErrorOr ZlibCompressor::finish() { VERIFY(!m_finished); @@ -140,24 +153,26 @@ void ZlibCompressor::finish() static_cast(m_compressor.ptr())->final_flush(); NetworkOrdered adler_sum = m_adler32_checksum.digest(); - m_output_stream << adler_sum; + TRY(m_output_stream->write(adler_sum.bytes())); m_finished = true; + + return {}; } ErrorOr ZlibCompressor::compress_all(ReadonlyBytes bytes, ZlibCompressionLevel compression_level) { - DuplexMemoryStream output_stream; - auto zlib_stream = TRY(ZlibCompressor::construct(output_stream, compression_level)); + auto output_stream = TRY(try_make()); + auto zlib_stream = TRY(ZlibCompressor::construct(Core::Stream::Handle(*output_stream), compression_level)); - zlib_stream->write_or_error(bytes); + TRY(zlib_stream->write_entire_buffer(bytes)); - zlib_stream->finish(); + TRY(zlib_stream->finish()); - if (zlib_stream->handle_any_error()) - return Error::from_string_literal("Underlying ZlibStream indicated an error"); + auto buffer = TRY(ByteBuffer::create_uninitialized(output_stream->used_buffer_size())); + TRY(output_stream->read_entire_buffer(buffer.bytes())); - return output_stream.copy_into_contiguous_buffer(); + return buffer; } } diff --git a/Userland/Libraries/LibCompress/Zlib.h b/Userland/Libraries/LibCompress/Zlib.h index 1f6222e2c5..56b663773e 100644 --- a/Userland/Libraries/LibCompress/Zlib.h +++ b/Userland/Libraries/LibCompress/Zlib.h @@ -12,6 +12,7 @@ #include #include #include +#include #include namespace Compress { @@ -60,23 +61,28 @@ private: ReadonlyBytes m_data_bytes; }; -class ZlibCompressor : public OutputStream { +class ZlibCompressor : public Core::Stream::Stream { public: - static ErrorOr> construct(OutputStream&, ZlibCompressionLevel = ZlibCompressionLevel::Default); + static ErrorOr> construct(Core::Stream::Handle, ZlibCompressionLevel = ZlibCompressionLevel::Default); ~ZlibCompressor(); - size_t write(ReadonlyBytes) override; - bool write_or_error(ReadonlyBytes) override; - void finish(); + virtual ErrorOr read(Bytes) override; + virtual ErrorOr write(ReadonlyBytes) override; + virtual bool is_eof() const override; + virtual bool is_open() const override; + virtual void close() override; + ErrorOr finish(); static ErrorOr compress_all(ReadonlyBytes bytes, ZlibCompressionLevel = ZlibCompressionLevel::Default); private: - ZlibCompressor(OutputStream&, ZlibCompressionLevel); - void write_header(ZlibCompressionMethod, ZlibCompressionLevel); + ZlibCompressor(Core::Stream::Handle, ZlibCompressionLevel); + ErrorOr write_header(ZlibCompressionMethod, ZlibCompressionLevel); bool m_finished { false }; - OutputBitStream m_output_stream; + // FIXME: Remove this once DeflateCompressor is ported to Core::Stream. + NonnullOwnPtr m_ak_output_stream; + Core::Stream::Handle m_output_stream; NonnullOwnPtr m_compressor; Crypto::Checksum::Adler32 m_adler32_checksum; };