#pragma once #include "../../stddef.hpp" #include "array_range.hpp" #include "types.hpp" namespace JabyEngine { class LZ4Decompressor { public: struct Result { Progress progress; size_t bytes_ready; constexpr operator bool() const { return this->progress != Progress::Error; } static constexpr Result new_error() { return {Progress::Error, 0}; } static constexpr Result new_done(size_t bytes_ready) { return {Progress::Done, bytes_ready}; } static constexpr Result new_in_progress(size_t bytes_ready) { return {Progress::InProgress, bytes_ready}; } }; private: struct State { enum struct Step { Disabled, ReadToken, ObtainLiteralLength, CopyLiterals, ObtainMatchOffset, ObtainMatchLength, CopyMatch, }; Step step = Step::Disabled; size_t literal_length = 0; size_t match_length = 0; uint16_t match_offset = 0; State() = default; void enable() { this->step = Step::ReadToken; this->literal_length = 0; this->match_length = 0; this->match_offset = 0xFFFF; } void disable() { this->step = Step::Disabled; } }; private: uint8_t* dst_adr = nullptr; State state; static bool obtain_any_length(ArrayRange& data, uint32_t &dst_length); public: LZ4Decompressor() = default; LZ4Decompressor(uint8_t* dst_adr) : LZ4Decompressor() { LZ4Decompressor::setup(dst_adr); } void setup(uint8_t* dst_adr); void disable(); Result process(ArrayRange data, bool is_last); }; }