Network System 0.1.1
High-performance modular networking library for scalable client-server applications
Loading...
Searching...
No Matches
kcenon::network::protocols::quic::varint Class Reference

QUIC variable-length integer encoding/decoding (RFC 9000 Section 16) More...

#include <varint.h>

Collaboration diagram for kcenon::network::protocols::quic::varint:
Collaboration graph

Static Public Member Functions

static auto encode (uint64_t value) -> std::vector< uint8_t >
 Encode a value to variable-length format.
 
static auto encode_with_length (uint64_t value, size_t min_length) -> Result< std::vector< uint8_t > >
 Encode with minimum length requirement.
 
static auto decode (std::span< const uint8_t > data) -> Result< std::pair< uint64_t, size_t > >
 Decode variable-length integer from buffer.
 
static constexpr auto encoded_length (uint64_t value) noexcept -> size_t
 Get the number of bytes needed to encode a value.
 
static constexpr auto length_from_prefix (uint8_t first_byte) noexcept -> size_t
 Get encoded length from the first byte's prefix.
 
static constexpr auto is_valid (uint64_t value) noexcept -> bool
 Check if a value can be encoded as a varint.
 

Static Public Attributes

static constexpr uint64_t max_1byte = 63
 Maximum value for each encoded length.
 
static constexpr uint64_t max_2byte = 16383
 
static constexpr uint64_t max_4byte = 1073741823
 
static constexpr uint64_t max_8byte = varint_max
 

Static Private Attributes

static constexpr uint8_t prefix_1byte = 0x00
 
static constexpr uint8_t prefix_2byte = 0x40
 
static constexpr uint8_t prefix_4byte = 0x80
 
static constexpr uint8_t prefix_8byte = 0xC0
 
static constexpr uint8_t prefix_mask = 0xC0
 
static constexpr uint8_t value_mask = 0x3F
 

Detailed Description

QUIC variable-length integer encoding/decoding (RFC 9000 Section 16)

QUIC uses a variable-length integer encoding with 2-bit length prefix:

2-Bit Value Length Usable Bits Range
0b00 1 byte 6 0-63
0b01 2 bytes 14 0-16383
0b10 4 bytes 30 0-1073741823
0b11 8 bytes 62 0-4611686018427387903

The two most significant bits of the first byte indicate the length.

Definition at line 38 of file varint.h.

Member Function Documentation

◆ decode()

auto kcenon::network::protocols::quic::varint::decode ( std::span< const uint8_t > data) -> Result<std::pair<uint64_t, size_t>>
staticnodiscard

Decode variable-length integer from buffer.

Parameters
dataInput buffer
Returns
Result containing (decoded_value, bytes_consumed) or error

Definition at line 146 of file varint.cpp.

148{
149 if (data.empty())
150 {
153 "Empty buffer",
154 "quic::varint",
155 "Cannot decode from empty buffer"
156 );
157 }
158
159 const uint8_t first_byte = data[0];
160 const size_t length = length_from_prefix(first_byte);
161
162 if (data.size() < length)
163 {
166 "Insufficient data",
167 "quic::varint",
168 "Buffer too small for encoded length"
169 );
170 }
171
172 uint64_t value = first_byte & value_mask;
173
174 for (size_t i = 1; i < length; ++i)
175 {
176 value = (value << 8) | data[i];
177 }
178
179 return ok(std::make_pair(value, length));
180}
static constexpr auto length_from_prefix(uint8_t first_byte) noexcept -> size_t
Get encoded length from the first byte's prefix.
Definition varint.h:94
static constexpr uint8_t value_mask
Definition varint.h:123
@ error
Black hole detected, reset to base.
VoidResult ok()

References kcenon::network::protocols::quic::error, kcenon::network::error_codes::common_errors::invalid_argument, and kcenon::network::ok().

Referenced by kcenon::network::protocols::quic::transport_parameters::decode(), kcenon::network::protocols::quic::frame_parser::parse(), kcenon::network::protocols::quic::frame_parser::parse_ack(), kcenon::network::protocols::quic::frame_parser::parse_connection_close(), kcenon::network::protocols::quic::frame_parser::parse_crypto(), kcenon::network::protocols::quic::frame_parser::parse_data_blocked(), kcenon::network::protocols::quic::packet_parser::parse_long_header(), kcenon::network::protocols::quic::frame_parser::parse_max_data(), kcenon::network::protocols::quic::frame_parser::parse_max_stream_data(), kcenon::network::protocols::quic::frame_parser::parse_max_streams(), kcenon::network::protocols::quic::frame_parser::parse_new_connection_id(), kcenon::network::protocols::quic::frame_parser::parse_new_token(), kcenon::network::protocols::quic::frame_parser::parse_reset_stream(), kcenon::network::protocols::quic::frame_parser::parse_retire_connection_id(), kcenon::network::protocols::quic::frame_parser::parse_stop_sending(), kcenon::network::protocols::quic::frame_parser::parse_stream(), kcenon::network::protocols::quic::frame_parser::parse_stream_data_blocked(), kcenon::network::protocols::quic::frame_parser::parse_streams_blocked(), and kcenon::network::protocols::quic::frame_parser::peek_type().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ encode()

auto kcenon::network::protocols::quic::varint::encode ( uint64_t value) -> std::vector<uint8_t>
staticnodiscard

Encode a value to variable-length format.

Parameters
valueValue to encode (must be <= varint_max)
Returns
Encoded byte vector
Note
Values exceeding varint_max will be clamped

Definition at line 10 of file varint.cpp.

11{
12 if (value <= max_1byte)
13 {
14 // 6-bit: prefix 0b00
15 return {static_cast<uint8_t>(value)};
16 }
17
18 if (value <= max_2byte)
19 {
20 // 14-bit: prefix 0b01
21 return {
22 static_cast<uint8_t>(prefix_2byte | ((value >> 8) & value_mask)),
23 static_cast<uint8_t>(value & 0xFF)
24 };
25 }
26
27 if (value <= max_4byte)
28 {
29 // 30-bit: prefix 0b10
30 return {
31 static_cast<uint8_t>(prefix_4byte | ((value >> 24) & value_mask)),
32 static_cast<uint8_t>((value >> 16) & 0xFF),
33 static_cast<uint8_t>((value >> 8) & 0xFF),
34 static_cast<uint8_t>(value & 0xFF)
35 };
36 }
37
38 // 62-bit: prefix 0b11
39 // Clamp to max if exceeding varint_max
40 if (value > varint_max)
41 {
42 value = varint_max;
43 }
44
45 return {
46 static_cast<uint8_t>(prefix_8byte | ((value >> 56) & value_mask)),
47 static_cast<uint8_t>((value >> 48) & 0xFF),
48 static_cast<uint8_t>((value >> 40) & 0xFF),
49 static_cast<uint8_t>((value >> 32) & 0xFF),
50 static_cast<uint8_t>((value >> 24) & 0xFF),
51 static_cast<uint8_t>((value >> 16) & 0xFF),
52 static_cast<uint8_t>((value >> 8) & 0xFF),
53 static_cast<uint8_t>(value & 0xFF)
54 };
55}
static constexpr uint64_t max_4byte
Definition varint.h:114
static constexpr uint8_t prefix_4byte
Definition varint.h:120
static constexpr uint8_t prefix_2byte
Definition varint.h:119
static constexpr uint64_t max_2byte
Definition varint.h:113
static constexpr uint8_t prefix_8byte
Definition varint.h:121
static constexpr uint64_t max_1byte
Maximum value for each encoded length.
Definition varint.h:112
constexpr uint64_t varint_max
Maximum value that can be encoded in QUIC variable-length integer.
Definition varint.h:21

References kcenon::network::protocols::quic::varint_max.

Referenced by kcenon::network::protocols::quic::frame_builder::append_varint(), and kcenon::network::protocols::quic::packet_builder::build_initial().

Here is the caller graph for this function:

◆ encode_with_length()

auto kcenon::network::protocols::quic::varint::encode_with_length ( uint64_t value,
size_t min_length ) -> Result<std::vector<uint8_t>>
staticnodiscard

Encode with minimum length requirement.

Parameters
valueValue to encode
min_lengthMinimum encoded length (1, 2, 4, or 8)
Returns
Result containing encoded bytes or error if value doesn't fit or min_length is invalid

Definition at line 57 of file varint.cpp.

59{
60 // Validate min_length
61 if (min_length != 1 && min_length != 2 && min_length != 4 && min_length != 8)
62 {
65 "Invalid minimum length",
66 "quic::varint",
67 "min_length must be 1, 2, 4, or 8"
68 );
69 }
70
71 // Check if value fits in the requested length
72 uint64_t max_for_length = 0;
73 switch (min_length)
74 {
75 case 1: max_for_length = max_1byte; break;
76 case 2: max_for_length = max_2byte; break;
77 case 4: max_for_length = max_4byte; break;
78 case 8: max_for_length = max_8byte; break;
79 default: break;
80 }
81
82 // Find the actual minimum length needed
83 size_t actual_length = encoded_length(value);
84
85 // Use the larger of the two
86 size_t use_length = (min_length > actual_length) ? min_length : actual_length;
87
88 // If the requested min_length is smaller than needed, the value won't fit
89 // But we use the larger length, so this is fine
90
91 // Check if value exceeds maximum encodable
92 if (value > varint_max)
93 {
96 "Value exceeds maximum",
97 "quic::varint",
98 "Value exceeds 2^62 - 1"
99 );
100 }
101
102 // Encode with the determined length
103 std::vector<uint8_t> result;
104 switch (use_length)
105 {
106 case 1:
107 result = {static_cast<uint8_t>(value)};
108 break;
109
110 case 2:
111 result = {
112 static_cast<uint8_t>(prefix_2byte | ((value >> 8) & value_mask)),
113 static_cast<uint8_t>(value & 0xFF)
114 };
115 break;
116
117 case 4:
118 result = {
119 static_cast<uint8_t>(prefix_4byte | ((value >> 24) & value_mask)),
120 static_cast<uint8_t>((value >> 16) & 0xFF),
121 static_cast<uint8_t>((value >> 8) & 0xFF),
122 static_cast<uint8_t>(value & 0xFF)
123 };
124 break;
125
126 case 8:
127 result = {
128 static_cast<uint8_t>(prefix_8byte | ((value >> 56) & value_mask)),
129 static_cast<uint8_t>((value >> 48) & 0xFF),
130 static_cast<uint8_t>((value >> 40) & 0xFF),
131 static_cast<uint8_t>((value >> 32) & 0xFF),
132 static_cast<uint8_t>((value >> 24) & 0xFF),
133 static_cast<uint8_t>((value >> 16) & 0xFF),
134 static_cast<uint8_t>((value >> 8) & 0xFF),
135 static_cast<uint8_t>(value & 0xFF)
136 };
137 break;
138
139 default:
140 break;
141 }
142
143 return ok(std::move(result));
144}
static constexpr auto encoded_length(uint64_t value) noexcept -> size_t
Get the number of bytes needed to encode a value.
Definition varint.h:72
static constexpr uint64_t max_8byte
Definition varint.h:115

References kcenon::network::protocols::quic::error, kcenon::network::error_codes::common_errors::invalid_argument, kcenon::network::ok(), and kcenon::network::protocols::quic::varint_max.

Here is the call graph for this function:

◆ encoded_length()

static constexpr auto kcenon::network::protocols::quic::varint::encoded_length ( uint64_t value) -> size_t
inlinestaticnodiscardconstexprnoexcept

Get the number of bytes needed to encode a value.

Parameters
valueValue to check
Returns
Encoded length in bytes (1, 2, 4, or 8)

Definition at line 72 of file varint.h.

73 {
74 if (value <= 63)
75 {
76 return 1;
77 }
78 if (value <= 16383)
79 {
80 return 2;
81 }
82 if (value <= 1073741823)
83 {
84 return 4;
85 }
86 return 8;
87 }

◆ is_valid()

static constexpr auto kcenon::network::protocols::quic::varint::is_valid ( uint64_t value) -> bool
inlinestaticnodiscardconstexprnoexcept

Check if a value can be encoded as a varint.

Parameters
valueValue to check
Returns
true if value <= varint_max

Definition at line 104 of file varint.h.

105 {
106 return value <= varint_max;
107 }

References kcenon::network::protocols::quic::varint_max.

◆ length_from_prefix()

static constexpr auto kcenon::network::protocols::quic::varint::length_from_prefix ( uint8_t first_byte) -> size_t
inlinestaticnodiscardconstexprnoexcept

Get encoded length from the first byte's prefix.

Parameters
first_byteFirst byte of encoded varint
Returns
Encoded length in bytes (1, 2, 4, or 8)

Definition at line 94 of file varint.h.

95 {
96 return size_t{1} << (first_byte >> 6);
97 }

Member Data Documentation

◆ max_1byte

uint64_t kcenon::network::protocols::quic::varint::max_1byte = 63
staticconstexpr

Maximum value for each encoded length.

Definition at line 112 of file varint.h.

◆ max_2byte

uint64_t kcenon::network::protocols::quic::varint::max_2byte = 16383
staticconstexpr

Definition at line 113 of file varint.h.

◆ max_4byte

uint64_t kcenon::network::protocols::quic::varint::max_4byte = 1073741823
staticconstexpr

Definition at line 114 of file varint.h.

◆ max_8byte

uint64_t kcenon::network::protocols::quic::varint::max_8byte = varint_max
staticconstexpr

Definition at line 115 of file varint.h.

◆ prefix_1byte

uint8_t kcenon::network::protocols::quic::varint::prefix_1byte = 0x00
staticconstexprprivate

Definition at line 118 of file varint.h.

◆ prefix_2byte

uint8_t kcenon::network::protocols::quic::varint::prefix_2byte = 0x40
staticconstexprprivate

Definition at line 119 of file varint.h.

◆ prefix_4byte

uint8_t kcenon::network::protocols::quic::varint::prefix_4byte = 0x80
staticconstexprprivate

Definition at line 120 of file varint.h.

◆ prefix_8byte

uint8_t kcenon::network::protocols::quic::varint::prefix_8byte = 0xC0
staticconstexprprivate

Definition at line 121 of file varint.h.

◆ prefix_mask

uint8_t kcenon::network::protocols::quic::varint::prefix_mask = 0xC0
staticconstexprprivate

Definition at line 122 of file varint.h.

◆ value_mask

uint8_t kcenon::network::protocols::quic::varint::value_mask = 0x3F
staticconstexprprivate

Definition at line 123 of file varint.h.


The documentation for this class was generated from the following files: