1#include "cohesive_packet.hpp"
8constexpr unsigned layer_index(OsiLayer layer)
10 return static_cast<unsigned>(layer);
13static_assert(layer_index(min_osi_layer()) == 1,
"Lowest OSI layer index broken");
19 reset_iterators(layer);
23 m_buffer(
std::move(buffer))
25 reset_iterators(layer);
29 m_buffer(other.m_buffer)
31 rebuild_iterators(other);
34CohesivePacket& CohesivePacket::operator=(
const CohesivePacket& other)
36 m_buffer = other.m_buffer;
37 rebuild_iterators(other);
43 return get(layer_index(layer));
48 return get(layer_index(layer));
53 const unsigned layer_idx = layer_index(layer);
54 assert(get(layer_idx).
size() >= bytes);
55 m_iterators[layer_idx] = m_iterators[layer_idx - 1] + bytes;
60 if (
size(from, max_osi_layer()) > bytes) {
61 const auto from_idx = layer_index(from) - 1;
62 const auto max_idx = layer_index(max_osi_layer());
63 m_iterators[max_idx] = m_iterators[from_idx] + bytes;
64 assert(&m_iterators.back() == &m_iterators[max_idx]);
65 assert(m_iterators.back() >= m_iterators.front());
66 for (
auto idx = from_idx; idx < max_idx; ++idx) {
67 if (m_iterators[idx] > m_iterators[max_idx]) {
68 m_iterators[idx] = m_iterators[max_idx];
72 assert(
size(from, max_osi_layer()) <= bytes);
77 return std::distance(m_iterators.front(), m_iterators.back());
82 return get(layer_index(single_layer)).size();
87 auto begin = m_iterators[layer_index(from) - 1];
88 auto end = m_iterators[layer_index(to)];
89 auto dist = std::distance(begin, end);
90 return dist < 0 ? 0 : dist;
93void CohesivePacket::reset_iterators(OsiLayer ins_layer)
95 unsigned layer_idx = 0;
97 const unsigned ins_layer_idx = layer_index(ins_layer);
98 for (
unsigned i = 0; i < ins_layer_idx; ++i) {
99 m_iterators[layer_idx++] = m_buffer.begin();
102 const unsigned max_layer_idx = layer_index(max_osi_layer());
103 for (
unsigned i = ins_layer_idx; i <= max_layer_idx; ++i) {
104 m_iterators[layer_idx++] = m_buffer.end();
107 assert(m_iterators.size() == layer_idx);
110void CohesivePacket::rebuild_iterators(
const CohesivePacket& other)
112 assert(m_buffer.size() == other.m_buffer.size());
113 m_iterators.front() = m_buffer.begin();
114 auto next = m_iterators.front();
115 for (
unsigned i = 1; i < m_iterators.size(); ++i) {
116 next += other.m_iterators[i] - other.m_iterators[i - 1];
117 m_iterators[i] = next;
121auto CohesivePacket::get(
unsigned layer_idx) -> buffer_range
123 assert(layer_idx > 0);
124 assert(layer_idx < m_iterators.size());
125 return buffer_range(m_iterators[layer_idx - 1], m_iterators[layer_idx]);
128auto CohesivePacket::get(
unsigned layer_idx)
const -> buffer_const_range
130 assert(layer_idx > 0);
131 assert(layer_idx < m_iterators.size());
132 return buffer_const_range(m_iterators[layer_idx - 1], m_iterators[layer_idx]);
buffer_const_range operator[](OsiLayer layer) const
void set_boundary(OsiLayer, unsigned bytes)
CohesivePacket(const ByteBuffer &buffer, OsiLayer layer)
void trim(OsiLayer from, unsigned bytes)