LibDEFLATE: Allow decompression from multiple byte spans

Before we required the compressed data to live in a single contiguous
chunch of memory.
This commit is contained in:
2026-04-11 19:47:44 +03:00
parent 2984927be5
commit fed9dbefdf
2 changed files with 29 additions and 8 deletions

View File

@@ -3,6 +3,8 @@
#include <BAN/Vector.h> #include <BAN/Vector.h>
#include <BAN/ByteSpan.h> #include <BAN/ByteSpan.h>
#include <string.h>
namespace LibDEFLATE namespace LibDEFLATE
{ {
@@ -10,6 +12,10 @@ namespace LibDEFLATE
{ {
public: public:
BitInputStream(BAN::ConstByteSpan data) BitInputStream(BAN::ConstByteSpan data)
: m_data_wrapper(data)
, m_data({ &m_data_wrapper, 1 })
{ }
BitInputStream(BAN::Span<BAN::ConstByteSpan> data)
: m_data(data) : m_data(data)
{ } { }
@@ -19,11 +25,14 @@ namespace LibDEFLATE
while (m_bit_buffer_len < count) while (m_bit_buffer_len < count)
{ {
while (!m_data.empty() && m_data[0].empty())
m_data = m_data.slice(1);
if (m_data.empty()) if (m_data.empty())
return BAN::Error::from_errno(ENOBUFS); return BAN::Error::from_errno(ENOBUFS);
m_bit_buffer |= m_data[0] << m_bit_buffer_len;
m_bit_buffer |= m_data[0][0] << m_bit_buffer_len;
m_bit_buffer_len += 8; m_bit_buffer_len += 8;
m_data = m_data.slice(1); m_data[0] = m_data[0].slice(1);
} }
return m_bit_buffer & ((1 << count) - 1); return m_bit_buffer & ((1 << count) - 1);
@@ -49,10 +58,18 @@ namespace LibDEFLATE
bytes--; bytes--;
} }
if (bytes > m_data.size()) while (bytes)
return BAN::Error::from_errno(EINVAL); {
memcpy(output, m_data.data(), bytes); while (!m_data.empty() && m_data[0].empty())
m_data = m_data.slice(bytes); m_data = m_data.slice(1);
if (m_data.empty())
return BAN::Error::from_errno(ENOBUFS);
const size_t to_copy = BAN::Math::min(m_data[0].size(), bytes);
memcpy(output, m_data[0].data(), to_copy);
m_data[0] = m_data[0].slice(to_copy);
output += to_copy;
bytes -= to_copy;
}
return {}; return {};
} }
@@ -65,7 +82,8 @@ namespace LibDEFLATE
} }
private: private:
BAN::ConstByteSpan m_data; BAN::ConstByteSpan m_data_wrapper;
BAN::Span<BAN::ConstByteSpan> m_data;
uint32_t m_bit_buffer { 0 }; uint32_t m_bit_buffer { 0 };
uint8_t m_bit_buffer_len { 0 }; uint8_t m_bit_buffer_len { 0 };
}; };

View File

@@ -1,6 +1,5 @@
#pragma once #pragma once
#include <BAN/ByteSpan.h> #include <BAN/ByteSpan.h>
#include <BAN/NoCopyMove.h> #include <BAN/NoCopyMove.h>
#include <BAN/Vector.h> #include <BAN/Vector.h>
@@ -22,6 +21,10 @@ namespace LibDEFLATE
: m_type(type) : m_type(type)
, m_stream(data) , m_stream(data)
{ } { }
Decompressor(BAN::Span<BAN::ConstByteSpan> data, StreamType type)
: m_type(type)
, m_stream(data)
{ }
BAN::ErrorOr<BAN::Vector<uint8_t>> decompress(); BAN::ErrorOr<BAN::Vector<uint8_t>> decompress();