/* * Copyright (c) 2023, Tim Schumacher * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include namespace Compress { // This is based on the human-language description of the LZMA2 format on the English Wikipedia. // https://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Markov_chain_algorithm#LZMA2_format class Lzma2Decompressor : public Stream { public: /// Creates a decompressor that does not require the leading byte indicating the dictionary size. static ErrorOr> create_from_raw_stream(MaybeOwned, u32 dictionary_size); virtual ErrorOr read_some(Bytes) override; virtual ErrorOr write_some(ReadonlyBytes) override; virtual bool is_eof() const override; virtual bool is_open() const override; virtual void close() override; private: Lzma2Decompressor(MaybeOwned, CircularBuffer dictionary); MaybeOwned m_stream; CircularBuffer m_dictionary; // Our dictionary is always initialized, but LZMA2 requires that the first chunk resets the dictionary. bool m_dictionary_initialized { false }; bool m_found_end_of_stream { false }; Optional> m_current_chunk_stream; bool m_in_uncompressed_chunk { false }; Optional> m_last_lzma_stream; Optional m_last_lzma_options; }; }