19inline void PutU8(std::vector<std::uint8_t>& out, std::uint8_t v)
27inline void PutU16(std::vector<std::uint8_t>& out, std::uint16_t v)
30 out.push_back(
static_cast<std::uint8_t
>(v &
LowByteMask));
36inline void PutU32(std::vector<std::uint8_t>& out, std::uint32_t v)
41 out.push_back(
static_cast<std::uint8_t
>(v &
LowByteMask));
48inline void PutBytes(std::vector<std::uint8_t>& out,
const std::uint8_t* data, std::size_t len)
50 out.insert(out.end(), data, data + len);
57template <std::
size_t N>
58inline void PutFixed(std::vector<std::uint8_t>& out,
const std::array<std::uint8_t, N>& data)
60 out.insert(out.end(), data.begin(), data.end());
79 explicit Reader(std::span<const std::uint8_t> bytes)
86 explicit Reader(
const std::vector<std::uint8_t>& v)
107 [[nodiscard]]
const std::uint8_t*
Cursor()
const
119 throw std::out_of_range(
"wire::Reader: not enough data");
149 static_cast<std::uint32_t
>(
data[
pos + 3]);
168 template <std::
size_t N>
172 std::array<std::uint8_t, N> v{};
173 std::memcpy(v.data(),
data +
pos, N);
Lightweight cursor for parsing a big-endian byte buffer without copies.
std::uint8_t U8()
Read and consume one byte.
const std::uint8_t * Cursor() const
Pointer to the next unread byte.
std::size_t Position() const
Current read offset from the start of the buffer.
std::uint32_t U32()
Read and consume a big-endian 32-bit value.
const std::uint8_t * data
Pointer to the start of the underlying buffer (not owned).
Reader(const std::uint8_t *data, std::size_t len)
Construct a reader over a raw pointer/length pair.
std::size_t Remaining() const
Number of bytes not yet consumed.
std::array< std::uint8_t, N > Fixed()
Read and consume a fixed-size byte array.
Reader(std::span< const std::uint8_t > bytes)
Construct a reader over a byte span.
std::size_t pos
Current read offset from the start of the buffer.
void Need(std::size_t n) const
Assert that at least n bytes remain.
void Skip(std::size_t n)
Advance the read position without returning the skipped bytes.
Reader(const std::vector< std::uint8_t > &v)
Construct a reader over an existing byte vector.
std::vector< std::uint8_t > ReadBytes(std::size_t n)
Read and consume a variable-length byte range.
std::uint16_t U16()
Read and consume a big-endian 16-bit value.
std::size_t len
Total length of the underlying buffer in bytes.
void PutU16(std::vector< std::uint8_t > &out, std::uint16_t v)
Append a 16-bit value to a buffer in big-endian order.
void PutBytes(std::vector< std::uint8_t > &out, const std::uint8_t *data, std::size_t len)
Append a raw byte range to a buffer.
void PutU8(std::vector< std::uint8_t > &out, std::uint8_t v)
Append a single byte to a buffer.
void PutU32(std::vector< std::uint8_t > &out, std::uint32_t v)
Append a 32-bit value to a buffer in big-endian order.
void PutFixed(std::vector< std::uint8_t > &out, const std::array< std::uint8_t, N > &data)
Append a fixed-size byte array to a buffer.
static constexpr int OneOctetShift
The bit-shift distance required to move data across a single octet.
static constexpr int ThreeOctetsShift
The bit-shift distance required to move data across three octets.
static constexpr int TwoOctetsShift
The bit-shift distance required to move data across two octets.
static constexpr std::uint8_t LowByteMask
Bitmask used to isolate the lowest significant byte (8 bits) of a larger integer.