1#include <vanetza/security/v2/length_coding.hpp>
14std::size_t count_leading_ones(uint8_t v)
16 std::size_t count = 0;
17 while ((v & 0x80) != 0) {
24std::size_t length_coding_size(std::uintmax_t length) {
26 while ((length & ~0x7f) != 0) {
34ByteBuffer encode_length(std::uintmax_t length)
36 static_assert(
sizeof(std::uintmax_t) <= 8,
"size of length type exceeds implementation capabilities");
37 std::list<uint8_t> length_info;
40 length_info.push_front(
static_cast<uint8_t
>(length));
44 unsigned prefix_length = length_info.size();
45 if (prefix_length == 0) {
47 length_info.push_back(0x00);
50 assert(prefix_length <= 8);
51 uint8_t prefix_mask = ~((1 << (8 - prefix_length)) - 1);
52 if ((length_info.front() & ~prefix_mask) != length_info.front()) {
54 length_info.push_front(prefix_mask);
58 length_info.front() |= (prefix_mask << 1);
61 length_info.insert(length_info.begin(), prefix_length / 8, 0xff);
64 return ByteBuffer(length_info.begin(), length_info.end());
67std::tuple<ByteBuffer::const_iterator, std::uintmax_t> decode_length(
const ByteBuffer& buffer)
69 if (!buffer.empty()) {
70 std::size_t additional_prefix = count_leading_ones(buffer.front());
72 if (additional_prefix >=
sizeof(std::uintmax_t)) {
74 return std::make_tuple(buffer.begin(), 0);
75 }
else if (buffer.size() > additional_prefix) {
76 uint8_t prefix_mask = (1 << (8 - additional_prefix)) - 1;
77 std::uintmax_t length = buffer.front() & prefix_mask;
78 for (std::size_t i = 1; i <= additional_prefix; ++i) {
83 auto start = buffer.begin();
84 std::advance(start, additional_prefix + 1);
85 return std::make_tuple(start, length);
89 return std::make_tuple(buffer.end(), 0);