28 BitWriter(std::vector<uint8_t>& bytes,
size_t capacity)
30 , m_capacity(capacity)
33 m_bytes.reserve(capacity);
51 void bits(uint32_t value, uint32_t width) {
52 if (width == 0 || width > 32)
return;
53 if (m_bit + width > m_capacity * 8u) {
58 const uint64_t field =
static_cast<uint64_t
>(value) & ((uint64_t(1) << width) - 1u);
59 m_word |= field << m_wordBits;
62 while (m_wordBits >= 8) {
63 m_bytes.push_back(
static_cast<uint8_t
>(m_word));
69 void boolean(
bool value) {
bits(value ? 1u : 0u, 1); }
70 void u8(uint8_t value) {
bits(value, 8); }
71 void u16(uint16_t value) {
bits(value, 16); }
72 void u32(uint32_t value) {
bits(value, 32); }
75 void u64(uint64_t value) {
76 bits(
static_cast<uint32_t
>(value >> 32), 32);
77 bits(
static_cast<uint32_t
>(value), 32);
81 void f32(
float value) {
83 std::memcpy(&raw, &value,
sizeof(raw));
96 void append(
const uint8_t* bytes,
size_t count) {
97 if (m_bit + count > m_capacity * 8u) {
104 for (; done + 8 <= count; done += 8)
bits(bytes[done >> 3], 8);
105 if (done < count)
bits(bytes[done >> 3],
static_cast<uint32_t
>(count - done));
125 if (m_wordBits > 0) m_bytes.push_back(
static_cast<uint8_t
>(m_word));
131 std::vector<uint8_t>& m_bytes;
133 size_t m_capacity = 0;
136 uint32_t m_wordBits = 0;
137 bool m_overflowed =
false;
147 BitReader(
const uint8_t* bytes,
size_t size) : m_bytes(bytes), m_size(size) {}
149 ~BitReader() =
default;
151 BitReader(
const BitReader& other) =
delete;
152 BitReader& operator=(
const BitReader& other) =
delete;
154 BitReader(BitReader && other) =
delete;
155 BitReader& operator=(BitReader && other) =
delete;
158 uint32_t bits(uint32_t width) {
159 if (width == 0 || width > 32)
return 0;
160 if (m_failed || m_bit + width > m_size * 8u) {
166 while (m_wordBits < width) {
167 m_word |=
static_cast<uint64_t
>(m_bytes[m_next++]) << m_wordBits;
170 const uint32_t value =
static_cast<uint32_t
>(m_word & ((uint64_t(1) << width) - 1u));
177 bool boolean() {
return bits(1) != 0; }
178 uint8_t u8() {
return static_cast<uint8_t
>(bits(8)); }
179 uint16_t u16() {
return static_cast<uint16_t
>(bits(16)); }
180 uint32_t u32() {
return bits(32); }
191 const uint64_t high = bits(32);
192 const uint64_t low = bits(32);
193 return (high << 32) | low;
197 const uint32_t raw = bits(32);
199 std::memcpy(&value, &raw,
sizeof(value));
207 const uint8_t* m_bytes =
nullptr;
213 uint32_t m_wordBits = 0;
214 bool m_failed =
false;
bool failed() const
True when a read ran past the end; sticky once set.
Definition bit_stream.h:204
uint64_t u64()
Read back the pair u64 wrote, high half first.
Definition bit_stream.h:190
Packs values to the bit into a byte buffer.
Definition bit_stream.h:19
BitWriter(std::vector< uint8_t > &bytes, size_t capacity)
Write into bytes, filling at most capacity of them.
Definition bit_stream.h:28
size_t bitCount() const
Bits written so far.
Definition bit_stream.h:109
size_t byteCount() const
Whole bytes needed to carry what has been written.
Definition bit_stream.h:112
void append(const uint8_t *bytes, size_t count)
Write count bits from bytes, starting at its first bit.
Definition bit_stream.h:96
void bits(uint32_t value, uint32_t width)
Write the low width bits of value.
Definition bit_stream.h:51
void f32(float value)
A float as its exact bits, for the values quantisation would spoil.
Definition bit_stream.h:81
void finish()
Flush the last partial byte into the buffer.
Definition bit_stream.h:124
bool overflowed() const
True when a write did not fit.
Definition bit_stream.h:121
void u64(uint64_t value)
Two words, high first, because the field width is capped at 32.
Definition bit_stream.h:75