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:
@@ -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 };
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user