diff --git a/Userland/Libraries/LibCompress/Deflate.cpp b/Userland/Libraries/LibCompress/Deflate.cpp index 5beeb55ea6..2a87bcbdfa 100644 --- a/Userland/Libraries/LibCompress/Deflate.cpp +++ b/Userland/Libraries/LibCompress/Deflate.cpp @@ -189,6 +189,11 @@ ErrorOr DeflateDecompressor::UncompressedBlock::try_read_more() return true; } +ErrorOr> DeflateDecompressor::construct(Core::Stream::Handle stream) +{ + return TRY(adopt_nonnull_own_or_enomem(new (nothrow) DeflateDecompressor(move(stream)))); +} + DeflateDecompressor::DeflateDecompressor(Core::Stream::Handle stream) : m_input_stream(make(move(stream))) { @@ -311,12 +316,12 @@ void DeflateDecompressor::close() ErrorOr DeflateDecompressor::decompress_all(ReadonlyBytes bytes) { auto memory_stream = TRY(Core::Stream::FixedMemoryStream::construct(bytes)); - DeflateDecompressor deflate_stream { move(memory_stream) }; + auto deflate_stream = TRY(DeflateDecompressor::construct(move(memory_stream))); DuplexMemoryStream output_stream; auto buffer = TRY(ByteBuffer::create_uninitialized(4096)); - while (!deflate_stream.is_eof()) { - auto const slice = TRY(deflate_stream.read(buffer)); + while (!deflate_stream->is_eof()) { + auto const slice = TRY(deflate_stream->read(buffer)); output_stream.write_or_error(slice); } diff --git a/Userland/Libraries/LibCompress/Deflate.h b/Userland/Libraries/LibCompress/Deflate.h index 22b60730df..5ed55123b8 100644 --- a/Userland/Libraries/LibCompress/Deflate.h +++ b/Userland/Libraries/LibCompress/Deflate.h @@ -76,7 +76,7 @@ public: friend CompressedBlock; friend UncompressedBlock; - DeflateDecompressor(Core::Stream::Handle stream); + static ErrorOr> construct(Core::Stream::Handle stream); ~DeflateDecompressor(); virtual ErrorOr read(Bytes) override; @@ -88,6 +88,8 @@ public: static ErrorOr decompress_all(ReadonlyBytes); private: + DeflateDecompressor(Core::Stream::Handle stream); + ErrorOr decode_length(u32); ErrorOr decode_distance(u32); ErrorOr decode_codes(CanonicalCode& literal_code, Optional& distance_code); diff --git a/Userland/Libraries/LibCompress/Gzip.cpp b/Userland/Libraries/LibCompress/Gzip.cpp index 0a6f7dd978..32f1cd17f2 100644 --- a/Userland/Libraries/LibCompress/Gzip.cpp +++ b/Userland/Libraries/LibCompress/Gzip.cpp @@ -39,6 +39,18 @@ bool BlockHeader::supported_by_implementation() const return true; } +ErrorOr> GzipDecompressor::Member::construct(BlockHeader header, Core::Stream::Stream& stream) +{ + auto deflate_stream = TRY(DeflateDecompressor::construct(Core::Stream::Handle(stream))); + return TRY(adopt_nonnull_own_or_enomem(new (nothrow) Member(header, move(deflate_stream)))); +} + +GzipDecompressor::Member::Member(BlockHeader header, NonnullOwnPtr stream) + : m_header(header) + , m_stream(move(stream)) +{ +} + GzipDecompressor::GzipDecompressor(NonnullOwnPtr stream) : m_input_stream(move(stream)) { @@ -58,8 +70,8 @@ ErrorOr GzipDecompressor::read(Bytes bytes) auto slice = bytes.slice(total_read); - if (m_current_member.has_value()) { - auto current_slice = TRY(current_member().m_stream.read(slice)); + if (m_current_member) { + auto current_slice = TRY(current_member().m_stream->read(slice)); current_member().m_checksum.update(current_slice); current_member().m_nread += current_slice.size(); @@ -131,7 +143,7 @@ ErrorOr GzipDecompressor::read(Bytes bytes) // FIXME: we should probably verify this instead of just assuming it matches } - m_current_member.emplace(header, *m_input_stream); + m_current_member = TRY(Member::construct(header, *m_input_stream)); continue; } } diff --git a/Userland/Libraries/LibCompress/Gzip.h b/Userland/Libraries/LibCompress/Gzip.h index 5a038515ab..45c4b01733 100644 --- a/Userland/Libraries/LibCompress/Gzip.h +++ b/Userland/Libraries/LibCompress/Gzip.h @@ -56,25 +56,24 @@ public: private: class Member { public: - Member(BlockHeader header, Core::Stream::Stream& stream) - : m_header(header) - , m_stream(Core::Stream::Handle(stream)) - { - } + static ErrorOr> construct(BlockHeader header, Core::Stream::Stream&); BlockHeader m_header; - DeflateDecompressor m_stream; + NonnullOwnPtr m_stream; Crypto::Checksum::CRC32 m_checksum; size_t m_nread { 0 }; + + private: + Member(BlockHeader, NonnullOwnPtr); }; - Member const& current_member() const { return m_current_member.value(); } - Member& current_member() { return m_current_member.value(); } + Member const& current_member() const { return *m_current_member; } + Member& current_member() { return *m_current_member; } NonnullOwnPtr m_input_stream; u8 m_partial_header[sizeof(BlockHeader)]; size_t m_partial_header_offset { 0 }; - Optional m_current_member; + OwnPtr m_current_member {}; bool m_eof { false }; };