From 7ec91dfde7dbd2ba42a8a4fc86ee64db98625960 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Fri, 31 Mar 2023 19:05:17 -0400 Subject: [PATCH] LibCompress: Add a utility to GZIP compress an entire file This is copy-pasted from the gzip utility, along with its existing TODO. This is currently only needed by that utility, but this gives us API symmetry with GzipDecompressor, and helps ensure we won't end up in a situation where only one utility receives optimizations that should be received by all interested parties. --- Userland/Libraries/LibCompress/Gzip.cpp | 20 ++++++++++++++++++++ Userland/Libraries/LibCompress/Gzip.h | 1 + 2 files changed, 21 insertions(+) diff --git a/Userland/Libraries/LibCompress/Gzip.cpp b/Userland/Libraries/LibCompress/Gzip.cpp index d64a8fab6f..e47f010272 100644 --- a/Userland/Libraries/LibCompress/Gzip.cpp +++ b/Userland/Libraries/LibCompress/Gzip.cpp @@ -12,6 +12,8 @@ #include #include #include +#include +#include namespace Compress { @@ -262,4 +264,22 @@ ErrorOr GzipCompressor::compress_all(ReadonlyBytes bytes) return buffer; } +ErrorOr GzipCompressor::compress_file(StringView input_filename, NonnullOwnPtr output_stream) +{ + // We map the whole file instead of streaming to reduce size overhead (gzip header) and increase the deflate block size (better compression) + // TODO: automatically fallback to buffered streaming for very large files + RefPtr file; + ReadonlyBytes input_bytes; + + if (TRY(Core::System::stat(input_filename)).st_size > 0) { + file = TRY(Core::MappedFile::map(input_filename)); + input_bytes = file->bytes(); + } + + auto output_bytes = TRY(Compress::GzipCompressor::compress_all(input_bytes)); + TRY(output_stream->write_until_depleted(output_bytes)); + + return {}; +} + } diff --git a/Userland/Libraries/LibCompress/Gzip.h b/Userland/Libraries/LibCompress/Gzip.h index 6dcfbd5113..ef7f67767e 100644 --- a/Userland/Libraries/LibCompress/Gzip.h +++ b/Userland/Libraries/LibCompress/Gzip.h @@ -93,6 +93,7 @@ public: virtual void close() override; static ErrorOr compress_all(ReadonlyBytes bytes); + static ErrorOr compress_file(StringView input_file, NonnullOwnPtr output_stream); private: MaybeOwned m_output_stream;