ProtoCore v0.0.2
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
quic_varint.cpp
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file pc_quic_varint.cpp
6 * @brief QUIC variable-length integer coding - implementation. See pc_quic_varint.h.
7 */
8
10
11#if PC_ENABLE_HTTP3
12
13size_t pc_quic_varint_len(uint64_t value)
14{
15 if (value <= 0x3F)
16 {
17 return 1;
18 }
19 if (value <= 0x3FFF)
20 {
21 return 2;
22 }
23 if (value <= 0x3FFFFFFF)
24 {
25 return 4;
26 }
27 if (value <= QUIC_VARINT_MAX)
28 {
29 return 8;
30 }
31 return 0;
32}
33
34size_t pc_quic_varint_encode(uint8_t *out, size_t cap, uint64_t value)
35{
36 size_t n = pc_quic_varint_len(value);
37 if (n == 0 || cap < n)
38 {
39 return 0;
40 }
41 // The 2-bit length prefix (log2 n) sits in the top bits of the first byte.
42 static const uint8_t prefix[9] = {0, 0x00, 0x40, 0, 0x80, 0, 0, 0, 0xC0};
43 for (size_t i = 0; i < n; i++)
44 {
45 out[n - 1 - i] = (uint8_t)(value >> (8 * i));
46 }
47 out[0] |= prefix[n];
48 return n;
49}
50
51bool pc_quic_varint_decode(const uint8_t *in, size_t len, uint64_t *value, size_t *consumed)
52{
53 if (len < 1)
54 {
55 return false;
56 }
57 size_t n = (size_t)1 << (in[0] >> 6); // 1, 2, 4, or 8
58 if (len < n)
59 {
60 return false;
61 }
62 uint64_t v = (uint64_t)(in[0] & 0x3F);
63 for (size_t i = 1; i < n; i++)
64 {
65 v = (v << 8) | in[i];
66 }
67 *value = v;
68 *consumed = n;
69 return true;
70}
71
72#endif // PC_ENABLE_HTTP3