31#ifndef CCSDS124_BITBUFFER_HPP
32#define CCSDS124_BITBUFFER_HPP
51template <std::
size_t MaxBytes = MAX_OUTPUT_BYTES>
class BitBuffer {
56 constexpr BitBuffer() noexcept : data_{}, num_bits_(0), acc_(0), acc_len_(0) {}
72 [[nodiscard]] std::size_t
size() const noexcept {
83 constexpr std::size_t max_bits = MaxBytes * 8;
84 if (num_bits_ >= max_bits) {
89 acc_ = (acc_ << 1) | (static_cast<std::uint32_t>(bit) & 1U);
109 constexpr std::size_t max_bits = MaxBytes * 8;
110 if (num_bits_ + num_bits > max_bits) {
115 std::size_t full_bytes = num_bits >> 3;
116 for (std::size_t i = 0; i < full_bytes; ++i) {
124 std::size_t remaining_bits = num_bits & 7;
125 if (remaining_bits > 0) {
127 std::uint32_t value = bytes[full_bytes] >> (8 - remaining_bits);
145 if (num_bits == 0 || num_bits > 24) {
149 constexpr std::size_t max_bits = MaxBytes * 8;
150 if (num_bits_ + num_bits > max_bits) {
155 std::uint32_t mask = (1U << num_bits) - 1U;
156 std::uint32_t masked_value = value & mask;
158 acc_ = (acc_ << num_bits) | masked_value;
159 acc_len_ += num_bits;
160 num_bits_ += num_bits;
176 template <std::
size_t N>
178 constexpr std::size_t max_bits = MaxBytes * 8;
179 if (num_bits_ + num_bits > max_bits) {
183 std::size_t bits_to_append = (num_bits < N) ? num_bits : N;
184 std::size_t bit_pos = 0;
187 while (bit_pos + 24 <= bits_to_append) {
188 std::size_t word_idx = bit_pos >> 5;
189 std::size_t bit_in_word = bit_pos & 31;
192 if (bit_in_word <= 8) {
194 std::uint32_t word = bv.data()[word_idx];
195 value = (word >> (8 - bit_in_word)) & 0xFFFFFFU;
196 }
else if (bit_in_word + 24 <= 32) {
198 std::uint32_t word = bv.data()[word_idx];
199 value = (word >> (32 - bit_in_word - 24)) & 0xFFFFFFU;
203 for (std::size_t i = 0; i < 24; ++i) {
204 value = (value << 1) | static_cast<std::uint32_t>(bv.get_bit(bit_pos + i));
216 std::size_t remaining = bits_to_append - bit_pos;
218 std::uint32_t value = 0;
219 for (std::size_t i = 0; i < remaining; ++i) {
220 value = (value << 1) | static_cast<std::uint32_t>(bv.get_bit(bit_pos + i));
251 std::size_t
to_bytes(std::uint8_t* bytes, std::size_t max_bytes)
const noexcept {
253 std::size_t num_bytes = (num_bits_ + 7) / 8;
254 if (num_bytes > max_bytes) {
255 num_bytes = max_bytes;
259 std::size_t flushed_bytes = (num_bits_ - acc_len_) / 8;
260 if (flushed_bytes > num_bytes) {
261 flushed_bytes = num_bytes;
263 if (flushed_bytes > 0) {
264 std::memcpy(bytes, data_.data(), flushed_bytes);
268 if (acc_len_ > 0 && flushed_bytes < num_bytes) {
270 bytes[flushed_bytes] =
static_cast<std::uint8_t
>(acc_ << (8 - acc_len_));
277 std::array<std::uint8_t, MaxBytes> data_;
278 std::size_t num_bits_;
280 std::size_t acc_len_;
285 void flush_acc() noexcept {
286 while (acc_len_ >= 8) {
289 std::size_t byte_index = (num_bits_ - acc_len_ - 8) / 8;
290 data_[byte_index] =
static_cast<std::uint8_t
>(acc_ >> acc_len_);
293 acc_ &= (1U << acc_len_) - 1U;
Fixed-length bit vector with static allocation.
Variable-length bit buffer with static allocation.
Error append_bitvector(const BitVector< N > &bv) noexcept
Append all bits from a BitVector.
void clear() noexcept
Clear buffer to empty state.
Error append_bit(int bit) noexcept
Append a single bit.
Error append_bitvector(const BitVector< N > &bv, std::size_t num_bits) noexcept
Append bits from a BitVector.
std::size_t size() const noexcept
Get number of bits in buffer.
Error append_value(std::uint32_t value, std::size_t num_bits) noexcept
Append multiple bits from a value.
std::size_t to_bytes(std::uint8_t *bytes, std::size_t max_bytes) const noexcept
Convert bit buffer to byte array.
constexpr BitBuffer() noexcept
Default constructor - initializes to empty state.
Error append_bits(const std::uint8_t *bytes, std::size_t num_bits) noexcept
Append multiple bits from byte array.
Fixed-length bit vector with compile-time size.
CCSDS 124.0-B-1 compile-time configuration.
CCSDS 124.0-B-1 error handling.
Error
Error codes for error-code-based error handling.
@ Overflow
Buffer overflow.
@ InvalidArg
Invalid argument.