Files
limen/util/prepend_buffer.h

42 lines
1.2 KiB
C
Raw Permalink Normal View History

2026-04-19 17:28:44 -07:00
#pragma once
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <span>
// Buffer that grows in both directions from a midpoint. Payload is appended at
// the back; each protocol layer then prepends its header in reverse order
// (UDP, then IPv4, then Ethernet) without moving payload bytes. Lets the
// network stack build outbound frames bottom-up with no copies or scratch.
2026-04-19 17:28:44 -07:00
template <size_t N>
class prepend_buffer {
uint8_t m_buf[N];
size_t m_start = N / 2;
size_t m_end = N / 2;
public:
template <typename T>
T* prepend() {
m_start -= sizeof(T);
return reinterpret_cast<T*>(m_buf + m_start);
}
uint8_t* append(size_t len) {
uint8_t* p = m_buf + m_end;
m_end += len;
return p;
}
void append_copy(std::span<const uint8_t> data) {
memcpy(append(data.size()), data.data(), data.size());
}
uint8_t* payload_ptr() { return m_buf + m_end; }
uint8_t* data() { return m_buf + m_start; }
const uint8_t* data() const { return m_buf + m_start; }
size_t size() const { return m_end - m_start; }
std::span<const uint8_t> span() const { return {data(), size()}; }
};