2026-04-19 17:28:44 -07:00
|
|
|
#pragma once
|
|
|
|
|
#include <cstddef>
|
|
|
|
|
#include <cstdint>
|
|
|
|
|
#include <cstring>
|
|
|
|
|
#include <span>
|
|
|
|
|
|
2026-05-01 10:47:08 -07:00
|
|
|
// Bounded writer over a caller-owned byte buffer. Tracks fill level and a
|
|
|
|
|
// sticky overflow flag so packing code can write blindly and check once at the
|
|
|
|
|
// end. Unlike std::span, it has a size cursor that grows toward capacity.
|
2026-04-19 17:28:44 -07:00
|
|
|
class span_writer {
|
|
|
|
|
uint8_t *m_data;
|
|
|
|
|
size_t m_capacity;
|
|
|
|
|
size_t m_size = 0;
|
|
|
|
|
bool m_overflow = false;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
span_writer(uint8_t *data, size_t capacity) : m_data(data), m_capacity(capacity) {}
|
|
|
|
|
span_writer(std::span<uint8_t> buf) : m_data(buf.data()), m_capacity(buf.size()) {}
|
|
|
|
|
|
|
|
|
|
void push_back(uint8_t v) {
|
|
|
|
|
if (m_size < m_capacity) m_data[m_size++] = v;
|
|
|
|
|
else m_overflow = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class It>
|
|
|
|
|
void insert(uint8_t *, It first, It last) {
|
|
|
|
|
while (first != last) {
|
|
|
|
|
if (m_size < m_capacity) m_data[m_size++] = *first++;
|
|
|
|
|
else { m_overflow = true; return; }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t size() const { return m_size; }
|
|
|
|
|
size_t capacity() const { return m_capacity; }
|
|
|
|
|
bool full() const { return m_size >= m_capacity; }
|
|
|
|
|
bool overflow() const { return m_overflow; }
|
|
|
|
|
|
|
|
|
|
uint8_t *data() { return m_data; }
|
|
|
|
|
const uint8_t *data() const { return m_data; }
|
|
|
|
|
|
|
|
|
|
uint8_t *begin() { return m_data; }
|
|
|
|
|
uint8_t *end() { return m_data + m_size; }
|
|
|
|
|
const uint8_t *begin() const { return m_data; }
|
|
|
|
|
const uint8_t *end() const { return m_data + m_size; }
|
|
|
|
|
|
|
|
|
|
span_writer subspan(size_t offset) {
|
|
|
|
|
return span_writer(m_data + offset, m_capacity - offset);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
span_writer subspan(size_t offset, size_t len) {
|
|
|
|
|
return span_writer(m_data + offset, len);
|
|
|
|
|
}
|
|
|
|
|
};
|