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 "utilities.h"
7
8#include <bit>
9#include <cstdint>
10#include <cstring>
11#include <span>
12#include <stdexcept>
13#include <vector>
14
15namespace quicr {
16 class UintVar
17 {
18 public:
19 constexpr UintVar(uint64_t value)
20 : be_value_{ std::bit_cast<std::array<std::uint8_t, sizeof(std::uint64_t)>>(SwapBytes(value)) }
21 {
22 constexpr uint64_t k14bitLength = (static_cast<uint64_t>(-1) << (64 - 6) >> (64 - 6));
23 constexpr uint64_t k30bitLength = (static_cast<uint64_t>(-1) << (64 - 14) >> (64 - 14));
24 constexpr uint64_t k62bitLength = (static_cast<uint64_t>(-1) << (64 - 30) >> (64 - 30));
25
26 if (be_value_.front() & 0xC0u) { // Check if invalid
27 throw std::invalid_argument("Value greater than uintvar maximum");
28 }
29
30 std::uint64_t be_v = std::bit_cast<std::uint64_t>(be_value_);
31 if (value > k62bitLength) { // 62 bit encoding (8 bytes)
32 be_v |= 0xC0ull;
33 } else if (value > k30bitLength) { // 30 bit encoding (4 bytes)
34 be_v >>= 32;
35 be_v |= 0x80ull;
36 } else if (value > k14bitLength) { // 14 bit encoding (2 bytes)
37 be_v >>= 48;
38 be_v |= 0x40ull;
39 } else {
40 be_v >>= 56;
41 }
42
43 be_value_ = std::bit_cast<std::array<std::uint8_t, sizeof(std::uint64_t)>>(be_v);
44 }
45
46 constexpr UintVar(std::span<const std::uint8_t> bytes)
47 : be_value_{ 0 }
48 {
49 if (bytes.empty() || bytes.size() < Size(bytes.front())) {
50 throw std::invalid_argument("Invalid bytes for uintvar");
51 }
52
53 const std::size_t size = Size(bytes.front());
54 if (std::is_constant_evaluated()) {
55 for (std::size_t i = 0; i < size; ++i) {
56 be_value_[i] = bytes.data()[i];
57 }
58 } else {
59 std::memcpy(&be_value_, bytes.data(), size);
60 }
61 }
62
63 constexpr UintVar(const UintVar&) noexcept = default;
64 constexpr UintVar(UintVar&&) noexcept = default;
65 constexpr UintVar& operator=(const UintVar&) noexcept = default;
66 constexpr UintVar& operator=(UintVar&&) noexcept = default;
67
68 constexpr UintVar& operator=(std::uint64_t value)
69 {
70 UintVar t(value);
71 this->be_value_ = t.be_value_;
72 return *this;
73 }
74
75 constexpr std::uint64_t Get() const noexcept
76 {
77 return SwapBytes((std::bit_cast<std::uint64_t>(be_value_) & SwapBytes(uint64_t(~(~0x3Full << 56))))
78 << (sizeof(uint64_t) - Size()) * 8);
79 }
80
81 static constexpr std::size_t Size(uint8_t msb_bytes) noexcept
82 {
83 if ((msb_bytes & 0xC0) == 0xC0) {
84 return sizeof(uint64_t);
85 } else if ((msb_bytes & 0x80) == 0x80) {
86 return sizeof(uint32_t);
87 } else if ((msb_bytes & 0x40) == 0x40) {
88 return sizeof(uint16_t);
89 }
90
91 return sizeof(uint8_t);
92 }
93
94 constexpr std::size_t Size() const noexcept { return UintVar::Size(be_value_.front()); }
95
96 // NOLINTBEGIN(readability-identifier-naming)
97 constexpr const std::uint8_t* data() const noexcept { return be_value_.data(); }
98 constexpr std::size_t size() const noexcept { return Size(); }
99 constexpr auto begin() const noexcept { return data(); }
100 constexpr auto end() const noexcept { return data() + Size(); }
101 // NOLINTEND(readability-identifier-naming)
102
103 explicit constexpr operator uint64_t() const noexcept { return Get(); }
104
105 constexpr auto operator<=>(const UintVar&) const noexcept = default;
106
107 private:
108 std::array<std::uint8_t, sizeof(std::uint64_t)> be_value_;
109 };
110}
constexpr auto end() const noexcept
Definition uintvar.h:100
constexpr UintVar(std::span< const std::uint8_t > bytes)
Definition uintvar.h:46
constexpr UintVar(const UintVar &) noexcept=default
constexpr auto operator<=>(const UintVar &) const noexcept=default
constexpr UintVar(UintVar &&) noexcept=default
constexpr std::uint64_t Get() const noexcept
Definition uintvar.h:75
constexpr std::size_t Size() const noexcept
Definition uintvar.h:94
static constexpr std::size_t Size(uint8_t msb_bytes) noexcept
Definition uintvar.h:81
constexpr std::size_t size() const noexcept
Definition uintvar.h:98
constexpr auto begin() const noexcept
Definition uintvar.h:99
constexpr const std::uint8_t * data() const noexcept
Definition uintvar.h:97
constexpr UintVar(uint64_t value)
Definition uintvar.h:19
Definition transport.h:28