summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Schumacher <timschumi@gmx.de>2022-12-27 11:40:23 +0100
committerAndreas Kling <kling@serenityos.org>2023-01-10 10:28:26 +0100
commita212bc3052a00528c9c570f6be21072c02e5e1e7 (patch)
treea18cc52120dce7d9b1e7ae2a897968345a457d5a
parentb4b80b7ec69ce2ed2b9ec68da9776ced89bc595f (diff)
downloadserenity-a212bc3052a00528c9c570f6be21072c02e5e1e7.zip
LibCompress: Port `GzipCompressor` to `Core::Stream`
-rw-r--r--Tests/LibCompress/TestGzip.cpp2
-rw-r--r--Userland/Libraries/LibCompress/Gzip.cpp51
-rw-r--r--Userland/Libraries/LibCompress/Gzip.h16
-rw-r--r--Userland/Utilities/gzip.cpp27
-rw-r--r--Userland/Utilities/tar.cpp10
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);