diff options
author | Tim Schumacher <timschumi@gmx.de> | 2022-12-27 11:40:23 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2023-01-10 10:28:26 +0100 |
commit | a212bc3052a00528c9c570f6be21072c02e5e1e7 (patch) | |
tree | a18cc52120dce7d9b1e7ae2a897968345a457d5a | |
parent | b4b80b7ec69ce2ed2b9ec68da9776ced89bc595f (diff) | |
download | serenity-a212bc3052a00528c9c570f6be21072c02e5e1e7.zip |
LibCompress: Port `GzipCompressor` to `Core::Stream`
-rw-r--r-- | Tests/LibCompress/TestGzip.cpp | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibCompress/Gzip.cpp | 51 | ||||
-rw-r--r-- | Userland/Libraries/LibCompress/Gzip.h | 16 | ||||
-rw-r--r-- | Userland/Utilities/gzip.cpp | 27 | ||||
-rw-r--r-- | Userland/Utilities/tar.cpp | 10 |
5 files changed, 50 insertions, 56 deletions
diff --git a/Tests/LibCompress/TestGzip.cpp b/Tests/LibCompress/TestGzip.cpp index 90c0acf045..2f90725aea 100644 --- a/Tests/LibCompress/TestGzip.cpp +++ b/Tests/LibCompress/TestGzip.cpp @@ -90,7 +90,7 @@ TEST_CASE(gzip_round_trip) auto original = ByteBuffer::create_uninitialized(1024).release_value(); fill_with_random(original.data(), 1024); auto compressed = Compress::GzipCompressor::compress_all(original); - EXPECT(compressed.has_value()); + EXPECT(!compressed.is_error()); auto uncompressed = Compress::GzipDecompressor::decompress_all(compressed.value()); EXPECT(!uncompressed.is_error()); EXPECT(uncompressed.value() == original); diff --git a/Userland/Libraries/LibCompress/Gzip.cpp b/Userland/Libraries/LibCompress/Gzip.cpp index 2aeccf7757..4f2426d04c 100644 --- a/Userland/Libraries/LibCompress/Gzip.cpp +++ b/Userland/Libraries/LibCompress/Gzip.cpp @@ -173,12 +173,17 @@ ErrorOr<size_t> GzipDecompressor::write(ReadonlyBytes) VERIFY_NOT_REACHED(); } -GzipCompressor::GzipCompressor(OutputStream& stream) - : m_output_stream(stream) +GzipCompressor::GzipCompressor(Core::Stream::Handle<Core::Stream::Stream> stream) + : m_output_stream(move(stream)) { } -size_t GzipCompressor::write(ReadonlyBytes bytes) +ErrorOr<Bytes> GzipCompressor::read(Bytes) +{ + return Error::from_errno(EBADF); +} + +ErrorOr<size_t> GzipCompressor::write(ReadonlyBytes bytes) { BlockHeader header; header.identification_1 = 0x1f; @@ -188,39 +193,45 @@ size_t GzipCompressor::write(ReadonlyBytes bytes) header.modification_time = 0; header.extra_flags = 3; // DEFLATE sets 2 for maximum compression and 4 for minimum compression header.operating_system = 3; // unix - m_output_stream << Bytes { &header, sizeof(header) }; - DeflateCompressor compressed_stream { m_output_stream }; - VERIFY(compressed_stream.write_or_error(bytes)); + TRY(m_output_stream->write_entire_buffer({ &header, sizeof(header) })); + Core::Stream::WrapInAKOutputStream wrapped_stream { *m_output_stream }; + DeflateCompressor compressed_stream { wrapped_stream }; + if (!compressed_stream.write_or_error(bytes)) + return Error::from_string_literal("Underlying DeflateCompressor indicated an error"); compressed_stream.final_flush(); Crypto::Checksum::CRC32 crc32; crc32.update(bytes); LittleEndian<u32> digest = crc32.digest(); LittleEndian<u32> size = bytes.size(); - m_output_stream << digest << size; + TRY(m_output_stream->write_entire_buffer(digest.bytes())); + TRY(m_output_stream->write_entire_buffer(size.bytes())); return bytes.size(); } -bool GzipCompressor::write_or_error(ReadonlyBytes bytes) +bool GzipCompressor::is_eof() const { - if (write(bytes) < bytes.size()) { - set_fatal_error(); - return false; - } - return true; } -Optional<ByteBuffer> GzipCompressor::compress_all(ReadonlyBytes bytes) +bool GzipCompressor::is_open() const { - DuplexMemoryStream output_stream; - GzipCompressor gzip_stream { output_stream }; + return m_output_stream->is_open(); +} - gzip_stream.write_or_error(bytes); +void GzipCompressor::close() +{ +} - if (gzip_stream.handle_any_error()) - return {}; +ErrorOr<ByteBuffer> GzipCompressor::compress_all(ReadonlyBytes bytes) +{ + auto output_stream = TRY(try_make<Core::Stream::AllocatingMemoryStream>()); + GzipCompressor gzip_stream { Core::Stream::Handle<Core::Stream::Stream>(*output_stream) }; - return output_stream.copy_into_contiguous_buffer(); + TRY(gzip_stream.write_entire_buffer(bytes)); + + auto buffer = TRY(ByteBuffer::create_uninitialized(output_stream->used_buffer_size())); + TRY(output_stream->read_entire_buffer(buffer.bytes())); + return buffer; } } diff --git a/Userland/Libraries/LibCompress/Gzip.h b/Userland/Libraries/LibCompress/Gzip.h index 74ab4a7b6a..5a038515ab 100644 --- a/Userland/Libraries/LibCompress/Gzip.h +++ b/Userland/Libraries/LibCompress/Gzip.h @@ -79,18 +79,20 @@ private: bool m_eof { false }; }; -class GzipCompressor final : public OutputStream { +class GzipCompressor final : public Core::Stream::Stream { public: - GzipCompressor(OutputStream&); - ~GzipCompressor() = default; + GzipCompressor(Core::Stream::Handle<Core::Stream::Stream>); - size_t write(ReadonlyBytes) override; - bool write_or_error(ReadonlyBytes) override; + virtual ErrorOr<Bytes> read(Bytes) override; + virtual ErrorOr<size_t> write(ReadonlyBytes) override; + virtual bool is_eof() const override; + virtual bool is_open() const override; + virtual void close() override; - static Optional<ByteBuffer> compress_all(ReadonlyBytes bytes); + static ErrorOr<ByteBuffer> compress_all(ReadonlyBytes bytes); private: - OutputStream& m_output_stream; + Core::Stream::Handle<Core::Stream::Stream> m_output_stream; }; } diff --git a/Userland/Utilities/gzip.cpp b/Userland/Utilities/gzip.cpp index 991ff21674..4271aa4f28 100644 --- a/Userland/Utilities/gzip.cpp +++ b/Userland/Utilities/gzip.cpp @@ -50,33 +50,14 @@ ErrorOr<int> serenity_main(Main::Arguments arguments) input_bytes = file->bytes(); } - AK::Optional<ByteBuffer> output_bytes; + ByteBuffer output_bytes; if (decompress) output_bytes = TRY(Compress::GzipDecompressor::decompress_all(input_bytes)); else - output_bytes = Compress::GzipCompressor::compress_all(input_bytes); + output_bytes = TRY(Compress::GzipCompressor::compress_all(input_bytes)); - if (!output_bytes.has_value()) { - warnln("Failed gzip {} input file", decompress ? "decompressing"sv : "compressing"sv); - return 1; - } - - auto success = false; - if (write_to_stdout) { - auto stdout = Core::OutputFileStream { Core::File::standard_output() }; - success = stdout.write_or_error(output_bytes.value()); - } else { - auto output_stream_result = Core::OutputFileStream::open(output_filename); - if (output_stream_result.is_error()) { - warnln("Failed opening output file for writing: {}", output_stream_result.error()); - return 1; - } - success = output_stream_result.value().write_or_error(output_bytes.value()); - } - if (!success) { - warnln("Failed writing to output"); - return 1; - } + auto output_stream = write_to_stdout ? TRY(Core::Stream::File::standard_output()) : TRY(Core::Stream::File::open(output_filename, Core::Stream::OpenMode::Write)); + TRY(output_stream->write_entire_buffer(output_bytes)); if (!keep_input_files) { TRY(Core::System::unlink(input_filename)); diff --git a/Userland/Utilities/tar.cpp b/Userland/Utilities/tar.cpp index 55355d07e9..58b3a50726 100644 --- a/Userland/Utilities/tar.cpp +++ b/Userland/Utilities/tar.cpp @@ -207,18 +207,18 @@ ErrorOr<int> serenity_main(Main::Arguments arguments) return 1; } - auto file = Core::File::standard_output(); + NonnullOwnPtr<Core::Stream::Stream> output_stream = TRY(Core::Stream::File::standard_output()); if (!archive_file.is_empty()) - file = TRY(Core::File::open(archive_file, Core::OpenMode::WriteOnly)); + output_stream = TRY(Core::Stream::File::open(archive_file, Core::Stream::OpenMode::Write)); if (!directory.is_empty()) TRY(Core::System::chdir(directory)); - NonnullOwnPtr<OutputStream> file_output_stream = make<Core::OutputFileStream>(file); - NonnullOwnPtr<OutputStream> gzip_output_stream = make<Compress::GzipCompressor>(*file_output_stream); + if (gzip) + output_stream = TRY(try_make<Compress::GzipCompressor>(move(output_stream))); - Archive::TarOutputStream tar_stream(make<Core::Stream::WrappedAKOutputStream>(move((gzip) ? gzip_output_stream : file_output_stream))); + Archive::TarOutputStream tar_stream(move(output_stream)); auto add_file = [&](DeprecatedString path) -> ErrorOr<void> { auto file = Core::File::construct(path); |