diff options
-rw-r--r-- | Userland/Libraries/LibCompress/Deflate.cpp | 34 | ||||
-rw-r--r-- | Userland/Libraries/LibCompress/Deflate.h | 4 |
2 files changed, 20 insertions, 18 deletions
diff --git a/Userland/Libraries/LibCompress/Deflate.cpp b/Userland/Libraries/LibCompress/Deflate.cpp index c2a3370f35..36497a7467 100644 --- a/Userland/Libraries/LibCompress/Deflate.cpp +++ b/Userland/Libraries/LibCompress/Deflate.cpp @@ -139,7 +139,8 @@ ErrorOr<bool> DeflateDecompressor::CompressedBlock::try_read_more() return Error::from_string_literal("Invalid deflate literal/length symbol"); if (symbol < 256) { - m_decompressor.m_output_stream << static_cast<u8>(symbol); + u8 byte_symbol = symbol; + m_decompressor.m_output_buffer.write({ &byte_symbol, sizeof(byte_symbol) }); return true; } else if (symbol == 256) { m_eof = true; @@ -157,12 +158,9 @@ ErrorOr<bool> DeflateDecompressor::CompressedBlock::try_read_more() for (size_t idx = 0; idx < length; ++idx) { u8 byte = 0; - m_decompressor.m_output_stream.read({ &byte, sizeof(byte) }, distance); + TRY(m_decompressor.m_output_buffer.read_with_seekback({ &byte, sizeof(byte) }, distance)); - if (m_decompressor.m_output_stream.handle_any_error()) - return Error::from_string_literal("A back reference was requested that was too far back"); - - m_decompressor.m_output_stream << byte; + m_decompressor.m_output_buffer.write({ &byte, sizeof(byte) }); } return true; @@ -180,21 +178,25 @@ ErrorOr<bool> DeflateDecompressor::UncompressedBlock::try_read_more() if (m_bytes_remaining == 0) return false; - auto const nread = min(m_bytes_remaining, m_decompressor.m_output_stream.remaining_contiguous_space()); - m_bytes_remaining -= nread; - - TRY(m_decompressor.m_input_stream->read(m_decompressor.m_output_stream.reserve_contiguous_space(nread))); + Array<u8, 4096> temporary_buffer; + auto readable_bytes = temporary_buffer.span().trim(min(m_bytes_remaining, m_decompressor.m_output_buffer.empty_space())); + auto read_bytes = TRY(m_decompressor.m_input_stream->read(readable_bytes)); + auto written_bytes = m_decompressor.m_output_buffer.write(read_bytes); + VERIFY(read_bytes.size() == written_bytes); + m_bytes_remaining -= written_bytes; return true; } ErrorOr<NonnullOwnPtr<DeflateDecompressor>> DeflateDecompressor::construct(Core::Stream::Handle<Core::Stream::Stream> stream) { - return TRY(adopt_nonnull_own_or_enomem(new (nothrow) DeflateDecompressor(move(stream)))); + auto output_buffer = TRY(CircularBuffer::create_empty(32 * KiB)); + return TRY(adopt_nonnull_own_or_enomem(new (nothrow) DeflateDecompressor(move(stream), move(output_buffer)))); } -DeflateDecompressor::DeflateDecompressor(Core::Stream::Handle<Core::Stream::Stream> stream) +DeflateDecompressor::DeflateDecompressor(Core::Stream::Handle<Core::Stream::Stream> stream, CircularBuffer output_buffer) : m_input_stream(make<Core::Stream::LittleEndianInputBitStream>(move(stream))) + , m_output_buffer(move(output_buffer)) { } @@ -257,10 +259,10 @@ ErrorOr<Bytes> DeflateDecompressor::read(Bytes bytes) } if (m_state == State::ReadingCompressedBlock) { - auto nread = m_output_stream.read(slice); + auto nread = m_output_buffer.read(slice).size(); while (nread < slice.size() && TRY(m_compressed_block.try_read_more())) { - nread += m_output_stream.read(slice.slice(nread)); + nread += m_output_buffer.read(slice.slice(nread)).size(); } total_read += nread; @@ -274,10 +276,10 @@ ErrorOr<Bytes> DeflateDecompressor::read(Bytes bytes) } if (m_state == State::ReadingUncompressedBlock) { - auto nread = m_output_stream.read(slice); + auto nread = m_output_buffer.read(slice).size(); while (nread < slice.size() && TRY(m_uncompressed_block.try_read_more())) { - nread += m_output_stream.read(slice.slice(nread)); + nread += m_output_buffer.read(slice.slice(nread)).size(); } total_read += nread; diff --git a/Userland/Libraries/LibCompress/Deflate.h b/Userland/Libraries/LibCompress/Deflate.h index 5ed55123b8..63ffca599b 100644 --- a/Userland/Libraries/LibCompress/Deflate.h +++ b/Userland/Libraries/LibCompress/Deflate.h @@ -88,7 +88,7 @@ public: static ErrorOr<ByteBuffer> decompress_all(ReadonlyBytes); private: - DeflateDecompressor(Core::Stream::Handle<Core::Stream::Stream> stream); + DeflateDecompressor(Core::Stream::Handle<Core::Stream::Stream> stream, CircularBuffer buffer); ErrorOr<u32> decode_length(u32); ErrorOr<u32> decode_distance(u32); @@ -103,7 +103,7 @@ private: }; Core::Stream::Handle<Core::Stream::LittleEndianInputBitStream> m_input_stream; - CircularDuplexStream<32 * KiB> m_output_stream; + CircularBuffer m_output_buffer; }; class DeflateCompressor final : public Core::Stream::Stream { |