LibQuicR
Loading...
Searching...
No Matches
uintvar.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) 2024 Cisco Systems
2// SPDX-License-Identifier: BSD-2-Clause
3
4#pragma once
5
6#include "span.h"
7
8#include <cstdint>
9#include <cstring>
10#include <vector>
11
12namespace quicr {
13 namespace {
14#if __cplusplus >= 202002L
15 constexpr bool kIsBigEndian = std::endian::native == std::endian::big;
16#else
17 constexpr bool kIsBigEndian = static_cast<const std::uint8_t&>(0x0001) == 0x00;
18#endif
19
20 constexpr std::uint16_t SwapBytes(const std::uint16_t value)
21 {
22 if constexpr (kIsBigEndian)
23 return value;
24
25 return ((value >> 8) & 0x00FF) | ((value << 8) & 0xFF00);
26 }
27
28 constexpr std::uint32_t SwapBytes(const std::uint32_t value)
29 {
30 if constexpr (kIsBigEndian)
31 return value;
32
33 return ((value >> 24) & 0x000000FF) | ((value >> 8) & 0x0000FF00) | ((value << 8) & 0x00FF0000) |
34 ((value << 24) & 0xFF000000);
35 }
36
37 constexpr std::uint64_t SwapBytes(const std::uint64_t value)
38 {
39 if constexpr (kIsBigEndian)
40 return value;
41
42 return ((value >> 56) & 0x00000000000000FF) | ((value >> 40) & 0x000000000000FF00) |
43 ((value >> 24) & 0x0000000000FF0000) | ((value >> 8) & 0x00000000FF000000) |
44 ((value << 8) & 0x000000FF00000000) | ((value << 24) & 0x0000FF0000000000) |
45 ((value << 40) & 0x00FF000000000000) | ((value << 56) & 0xFF00000000000000);
46 }
47 }
48
49 class UintVar
50 {
51 public:
52 constexpr UintVar(uint64_t value)
53 : be_value_{ SwapBytes(value) }
54 {
55 constexpr uint64_t kLen1 = (static_cast<uint64_t>(-1) << (64 - 6) >> (64 - 6));
56 constexpr uint64_t kLen2 = (static_cast<uint64_t>(-1) << (64 - 14) >> (64 - 14));
57 constexpr uint64_t kLen4 = (static_cast<uint64_t>(-1) << (64 - 30) >> (64 - 30));
58
59 if (static_cast<uint8_t>(be_value_) & 0xC0u) { // Check if invalid
60 throw std::invalid_argument("Value greater than uintvar maximum");
61 }
62
63 if (value > kLen4) { // 62 bit encoding (8 bytes)
64 be_value_ |= 0xC0ull;
65 } else if (value > kLen2) { // 30 bit encoding (4 bytes)
66 be_value_ >>= 32;
67 be_value_ |= 0x80ull;
68 } else if (value > kLen1) { // 14 bit encoding (2 bytes)
69 be_value_ >>= 48;
70 be_value_ |= 0x40ull;
71 } else {
72 be_value_ >>= 56;
73 }
74 }
75
76 UintVar(Span<const uint8_t> bytes)
77 : be_value_{ 0 }
78 {
79 if (bytes.empty() || bytes.size() < Size(bytes[0])) {
80 throw std::invalid_argument("Invalid bytes for uintvar");
81 }
82
83 std::memcpy(&be_value_, bytes.data(), Size(bytes[0]));
84 }
85
86 explicit constexpr operator uint64_t() const noexcept
87 {
88 return SwapBytes((be_value_ & SwapBytes(uint64_t(~(~0x3Full << 56)))) << (sizeof(uint64_t) - Size()) * 8);
89 }
90
91 static constexpr std::size_t Size(uint8_t msb_bytes) noexcept
92 {
93 if ((msb_bytes & 0xC0) == 0xC0) {
94 return sizeof(uint64_t);
95 } else if ((msb_bytes & 0x80) == 0x80) {
96 return sizeof(uint32_t);
97 } else if ((msb_bytes & 0x40) == 0x40) {
98 return sizeof(uint16_t);
99 }
100
101 return sizeof(uint8_t);
102 }
103
104 constexpr std::size_t Size() const noexcept { return UintVar::Size(static_cast<uint8_t>(be_value_)); }
105
106 // NOLINTBEGIN(readability-identifier-naming)
107 auto data() const noexcept { return reinterpret_cast<const uint8_t*>(&be_value_); }
108 constexpr std::size_t size() const noexcept { return Size(); }
109 auto begin() const noexcept { return data(); }
110 auto end() const noexcept { return data() + Size(); }
111 // NOLINTEND(readability-identifier-naming)
112
113 private:
114 uint64_t be_value_;
115 };
116}
Definition uintvar.h:50
constexpr std::size_t Size() const noexcept
Definition uintvar.h:104
UintVar(Span< const uint8_t > bytes)
Definition uintvar.h:76
auto begin() const noexcept
Definition uintvar.h:109
static constexpr std::size_t Size(uint8_t msb_bytes) noexcept
Definition uintvar.h:91
constexpr std::size_t size() const noexcept
Definition uintvar.h:108
auto end() const noexcept
Definition uintvar.h:110
constexpr UintVar(uint64_t value)
Definition uintvar.h:52
auto data() const noexcept
Definition uintvar.h:107
Definition transport.h:26