Vanetza
 
Loading...
Searching...
No Matches
cohesive_packet.cpp
1#include "cohesive_packet.hpp"
2#include <cassert>
3#include <iterator>
4
5namespace vanetza
6{
7
8constexpr unsigned layer_index(OsiLayer layer)
9{
10 return static_cast<unsigned>(layer);
11}
12
13static_assert(layer_index(min_osi_layer()) == 1, "Lowest OSI layer index broken");
14
15
16CohesivePacket::CohesivePacket(const ByteBuffer& buffer, OsiLayer layer) :
17 m_buffer(buffer)
18{
19 reset_iterators(layer);
20}
21
22CohesivePacket::CohesivePacket(ByteBuffer&& buffer, OsiLayer layer) :
23 m_buffer(std::move(buffer))
24{
25 reset_iterators(layer);
26}
27
28CohesivePacket::CohesivePacket(const CohesivePacket& other) :
29 m_buffer(other.m_buffer)
30{
31 rebuild_iterators(other);
32}
33
34CohesivePacket& CohesivePacket::operator=(const CohesivePacket& other)
35{
36 m_buffer = other.m_buffer;
37 rebuild_iterators(other);
38 return *this;
39}
40
41auto CohesivePacket::operator[](OsiLayer layer) const -> buffer_const_range
42{
43 return get(layer_index(layer));
44}
45
46auto CohesivePacket::operator[](OsiLayer layer) -> buffer_range
47{
48 return get(layer_index(layer));
49}
50
51void CohesivePacket::set_boundary(OsiLayer layer, unsigned bytes)
52{
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;
56}
57
58void CohesivePacket::trim(OsiLayer from, unsigned bytes)
59{
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];
69 }
70 }
71 }
72 assert(size(from, max_osi_layer()) <= bytes);
73}
74
75std::size_t CohesivePacket::size() const
76{
77 return std::distance(m_iterators.front(), m_iterators.back());
78}
79
80std::size_t CohesivePacket::size(OsiLayer single_layer) const
81{
82 return get(layer_index(single_layer)).size();
83}
84
85std::size_t CohesivePacket::size(OsiLayer from, OsiLayer to) const
86{
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;
91}
92
93void CohesivePacket::reset_iterators(OsiLayer ins_layer)
94{
95 unsigned layer_idx = 0;
96
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();
100 }
101
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();
105 }
106
107 assert(m_iterators.size() == layer_idx);
108}
109
110void CohesivePacket::rebuild_iterators(const CohesivePacket& other)
111{
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;
118 }
119}
120
121auto CohesivePacket::get(unsigned layer_idx) -> buffer_range
122{
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]);
126}
127
128auto CohesivePacket::get(unsigned layer_idx) const -> buffer_const_range
129{
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]);
133}
134
135} // namespace vanetza
136
buffer_const_range operator[](OsiLayer layer) const
std::size_t size() const
void set_boundary(OsiLayer, unsigned bytes)
CohesivePacket(const ByteBuffer &buffer, OsiLayer layer)
void trim(OsiLayer from, unsigned bytes)
STL namespace.