96 lines
2.6 KiB
C++
96 lines
2.6 KiB
C++
#pragma once
|
|
|
|
#include "byte_buffer.h"
|
|
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <limits>
|
|
#include <type_traits>
|
|
|
|
namespace bitstream
|
|
{
|
|
struct fixed_policy
|
|
{
|
|
/**
|
|
* @brief Construct a stream pointing to the given byte array with @p num_bytes size
|
|
* @param bytes The byte array to serialize to/from. Must be 4-byte aligned and the size must be a multiple of 4
|
|
* @param num_bytes The number of bytes in the array
|
|
*/
|
|
fixed_policy(void* buffer, uint32_t num_bits) noexcept :
|
|
m_Buffer(static_cast<uint32_t*>(buffer)),
|
|
m_NumBitsSerialized(0),
|
|
m_TotalBits(num_bits) {}
|
|
|
|
/**
|
|
* @brief Construct a stream pointing to the given @p buffer
|
|
* @param buffer The buffer to serialize to/from
|
|
* @param num_bits The maximum number of bits that we can read
|
|
*/
|
|
template<size_t Size>
|
|
fixed_policy(byte_buffer<Size>& buffer, uint32_t num_bits) noexcept :
|
|
m_Buffer(reinterpret_cast<uint32_t*>(buffer.Bytes)),
|
|
m_NumBitsSerialized(0),
|
|
m_TotalBits(num_bits) {}
|
|
|
|
/**
|
|
* @brief Construct a stream pointing to the given @p buffer
|
|
* @param buffer The buffer to serialize to/from
|
|
*/
|
|
template<size_t Size>
|
|
fixed_policy(byte_buffer<Size>& buffer) noexcept :
|
|
m_Buffer(reinterpret_cast<uint32_t*>(buffer.Bytes)),
|
|
m_NumBitsSerialized(0),
|
|
m_TotalBits(Size * 8) {}
|
|
|
|
uint32_t* get_buffer() const noexcept { return m_Buffer; }
|
|
|
|
// TODO: Transition sizes to size_t
|
|
uint32_t get_num_bits_serialized() const noexcept { return m_NumBitsSerialized; }
|
|
|
|
bool can_serialize_bits(uint32_t num_bits) const noexcept { return m_NumBitsSerialized + num_bits <= m_TotalBits; }
|
|
|
|
uint32_t get_total_bits() const noexcept { return m_TotalBits; }
|
|
|
|
bool extend(uint32_t num_bits) noexcept
|
|
{
|
|
if (!can_serialize_bits(num_bits))
|
|
return false;
|
|
|
|
m_NumBitsSerialized += num_bits;
|
|
return true;
|
|
}
|
|
|
|
uint32_t* m_Buffer;
|
|
// TODO: Transition sizes to size_t
|
|
uint32_t m_NumBitsSerialized;
|
|
uint32_t m_TotalBits;
|
|
};
|
|
|
|
template<typename T>
|
|
struct growing_policy
|
|
{
|
|
growing_policy(T& container) noexcept :
|
|
m_Buffer(container),
|
|
m_NumBitsSerialized(0) {}
|
|
|
|
uint32_t* get_buffer() const noexcept { return m_Buffer.data(); }
|
|
|
|
uint32_t get_num_bits_serialized() const noexcept { return m_NumBitsSerialized; }
|
|
|
|
bool can_serialize_bits(uint32_t num_bits) const noexcept { return true; }
|
|
|
|
uint32_t get_total_bits() const noexcept { return (std::numeric_limits<uint32_t>::max)(); }
|
|
|
|
bool extend(uint32_t num_bits)
|
|
{
|
|
m_NumBitsSerialized += num_bits;
|
|
uint32_t num_bytes = (m_NumBitsSerialized - 1) / 8U + 1;
|
|
m_Buffer.resize(num_bytes);
|
|
return true;
|
|
}
|
|
|
|
T& m_Buffer;
|
|
|
|
uint32_t m_NumBitsSerialized;
|
|
};
|
|
} |