2#include "../utility/assert.h"
3#include "../utility/crc.h"
4#include "../utility/endian.h"
5#include "../utility/meta.h"
22 template<
typename Policy>
33 template<
typename... Ts,
34 typename = std::enable_if_t<std::is_constructible_v<Policy, Ts...>>>
36 noexcept(std::is_nothrow_constructible_v<Policy, Ts...>) :
37 m_Policy(std::forward<Ts>(args) ...),
45 m_Policy(std::move(other.m_Policy)),
46 m_Scratch(other.m_Scratch),
47 m_ScratchBits(other.m_ScratchBits),
48 m_WordIndex(other.m_WordIndex)
51 other.m_ScratchBits = 0;
52 other.m_WordIndex = 0;
59 m_Policy = std::move(rhs.m_Policy);
60 m_Scratch = rhs.m_Scratch;
61 m_ScratchBits = rhs.m_ScratchBits;
62 m_WordIndex = rhs.m_WordIndex;
65 rhs.m_ScratchBits = 0;
75 [[nodiscard]]
const uint8_t*
get_buffer() const noexcept {
return reinterpret_cast<const uint8_t*
>(m_Policy.get_buffer()); }
94 [[nodiscard]]
bool can_serialize_bits(uint32_t num_bits)
const noexcept {
return m_Policy.can_serialize_bits(num_bits); }
107 [[nodiscard]] uint32_t
get_total_bits() const noexcept {
return m_Policy.get_total_bits(); }
118 BS_ASSERT(num_bytes * 8U >= num_bits_read);
122 uint32_t remainder = (num_bytes * 8U - num_bits_read) % 32U;
133 uint32_t max = num_bytes / 4;
136 for (uint32_t i = offset; i < max; i++)
150 [[nodiscard]]
bool pad(uint32_t num_bytes)
noexcept
182 BS_ASSERT(num_bits > 0U && num_bits <= 32U);
199 if (m_ScratchBits < num_bits)
201 const uint32_t* ptr = m_Policy.get_buffer() + m_WordIndex;
204 m_Scratch |= ptr_value;
205 m_ScratchBits += 32U;
209 uint32_t offset = 64U - num_bits;
210 value =
static_cast<uint32_t
>(m_Scratch >> offset);
212 m_Scratch <<= num_bits;
213 m_ScratchBits -= num_bits;
231 uint32_t* word_buffer =
reinterpret_cast<uint32_t*
>(bytes);
232 uint32_t num_words = num_bits / 32U;
234 if (m_ScratchBits % 32U == 0U && num_words > 0U)
236 BS_ASSERT(m_Policy.extend(num_words * 32U));
239 std::memcpy(word_buffer, m_Policy.get_buffer() + m_WordIndex, num_words * 4U);
241 m_WordIndex += num_words;
246 for (uint32_t i = 0U; i < num_words; i++)
258 if (num_bits % 32 == 0)
261 uint32_t remaining_bits = num_bits - num_words * 32U;
263 uint32_t num_bytes = (remaining_bits - 1U) / 8U + 1U;
264 for (uint32_t i = 0; i < num_bytes; i++)
269 bytes[num_words * 4 + i] =
static_cast<uint8_t
>(value);
309 uint32_t m_ScratchBits;
310 uint32_t m_WordIndex;
#define BS_ASSERT(...)
Definition assert.h:15
A stream for reading objects from a tightly packed buffer.
Definition bit_reader.h:24
static constexpr bool writing
Definition bit_reader.h:26
bool serialize_bytes(uint8_t *bytes, uint32_t num_bits) noexcept
Reads the first num_bits bits of the given byte array, 32 bits at a time.
Definition bit_reader.h:224
uint32_t get_num_bits_serialized() const noexcept
Returns the number of bits which have been read from the buffer.
Definition bit_reader.h:81
uint32_t get_remaining_bits() const noexcept
Returns the number of bits which have not been read yet.
Definition bit_reader.h:101
bool serialize(Trait &&arg, Args &&... args) noexcept(utility::is_deduce_serialize_noexcept_v< Trait, bit_reader, Args... >)
Reads from the buffer, by trying to deduce the trait.
Definition bit_reader.h:300
uint32_t get_num_bytes_serialized() const noexcept
Returns the number of bytes which have been read from the buffer.
Definition bit_reader.h:87
bool can_serialize_bits(uint32_t num_bits) const noexcept
Returns whether the num_bits be read from the buffer.
Definition bit_reader.h:94
bit_reader(Ts &&... args) noexcept(std::is_nothrow_constructible_v< Policy, Ts... >)
Construct a reader with the parameters passed to the underlying policy.
Definition bit_reader.h:35
const uint8_t * get_buffer() const noexcept
Returns the buffer that this reader is currently serializing from.
Definition bit_reader.h:75
bit_reader & operator=(bit_reader &&rhs) noexcept
Definition bit_reader.h:57
bit_reader & operator=(const bit_reader &)=delete
bool pad(uint32_t num_bytes) noexcept
Pads the buffer up with the given number of bytes.
Definition bit_reader.h:150
bool serialize(Args &&... args) noexcept(utility::is_serialize_noexcept_v< Trait, bit_reader, Args... >)
Reads from the buffer, using the given Trait.
Definition bit_reader.h:284
static constexpr bool reading
Definition bit_reader.h:27
bit_reader(const bit_reader &)=delete
bool align() noexcept
Pads the buffer with up to 8 zeros, so that the next read is byte-aligned @notes Return false if the ...
Definition bit_reader.h:160
bool serialize_bits(uint32_t &value, uint32_t num_bits) noexcept
Reads the first num_bits bits of value from the buffer.
Definition bit_reader.h:180
uint32_t get_total_bits() const noexcept
Returns the size of the buffer, in bits.
Definition bit_reader.h:107
bool pad_to_size(uint32_t num_bytes) noexcept
Pads the buffer up to the given number of bytes.
Definition bit_reader.h:114
bit_reader(bit_reader &&other) noexcept
Definition bit_reader.h:44
constexpr bool is_deduce_serialize_noexcept_v
Definition meta.h:104
has_serialize_t< deduce_trait_t< Trait, Stream, Args... >, Stream, Trait, Args... > has_deduce_serialize_t
Definition meta.h:101
constexpr bool is_serialize_noexcept_v
Definition meta.h:40
BS_CONSTEXPR uint32_t to_big_endian32(uint32_t value)
Definition endian.h:104
typename deduce_trait< void, Trait, Stream, Args... >::type deduce_trait_t
Definition meta.h:96
std::void_t< decltype(serialize_traits< T >::serialize(std::declval< Stream & >(), std::declval< Args >()...))> has_serialize_t
Definition meta.h:17
Definition bounded_range.h:28
A class for specializing trait serialization functions.
Definition serialize_traits.h:11