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;