stackforge_core/layer/quic/
varint.rs1pub const VARINT_MAX: u64 = (1u64 << 62) - 1;
11
12#[must_use]
17pub fn decode(buf: &[u8]) -> Option<(u64, usize)> {
18 if buf.is_empty() {
19 return None;
20 }
21 let prefix = (buf[0] & 0xC0) >> 6;
22 match prefix {
23 0 => {
24 Some((u64::from(buf[0] & 0x3F), 1))
26 },
27 1 => {
28 if buf.len() < 2 {
30 return None;
31 }
32 let value = u64::from(u16::from_be_bytes([buf[0] & 0x3F, buf[1]]));
33 Some((value, 2))
34 },
35 2 => {
36 if buf.len() < 4 {
38 return None;
39 }
40 let value = u64::from(u32::from_be_bytes([buf[0] & 0x3F, buf[1], buf[2], buf[3]]));
41 Some((value, 4))
42 },
43 3 => {
44 if buf.len() < 8 {
46 return None;
47 }
48 let value = u64::from_be_bytes([
49 buf[0] & 0x3F,
50 buf[1],
51 buf[2],
52 buf[3],
53 buf[4],
54 buf[5],
55 buf[6],
56 buf[7],
57 ]);
58 Some((value, 8))
59 },
60 _ => unreachable!("prefix is always 0..=3"),
61 }
62}
63
64#[must_use]
70pub fn encode(value: u64) -> Vec<u8> {
71 assert!(
72 value <= VARINT_MAX,
73 "QUIC varint value {value} exceeds maximum {VARINT_MAX}"
74 );
75 if value < 64 {
76 vec![value as u8]
78 } else if value < 16_384 {
79 let encoded = (value as u16) | 0x4000;
81 encoded.to_be_bytes().to_vec()
82 } else if value < 1_073_741_824 {
83 let encoded = (value as u32) | 0x8000_0000;
85 encoded.to_be_bytes().to_vec()
86 } else {
87 let encoded = value | 0xC000_0000_0000_0000;
89 encoded.to_be_bytes().to_vec()
90 }
91}
92
93#[must_use]
101pub fn encoded_len(value: u64) -> usize {
102 assert!(
103 value <= VARINT_MAX,
104 "QUIC varint value {value} exceeds maximum {VARINT_MAX}"
105 );
106 if value < 64 {
107 1
108 } else if value < 16_384 {
109 2
110 } else if value < 1_073_741_824 {
111 4
112 } else {
113 8
114 }
115}
116
117#[cfg(test)]
118mod tests {
119 use super::*;
120
121 #[test]
122 fn test_decode_1byte() {
123 let buf = [0x25u8]; let (val, len) = decode(&buf).unwrap();
125 assert_eq!(val, 37);
126 assert_eq!(len, 1);
127 }
128
129 #[test]
130 fn test_decode_2bytes() {
131 let buf = [0x40u8, 0x01u8];
134 let (val, len) = decode(&buf).unwrap();
135 assert_eq!(val, 1);
136 assert_eq!(len, 2);
137 }
138
139 #[test]
140 fn test_decode_4bytes() {
141 let encoded = (494_878_333u32 | 0x8000_0000u32).to_be_bytes();
143 let (val, len) = decode(&encoded).unwrap();
144 assert_eq!(val, 494_878_333);
145 assert_eq!(len, 4);
146 }
147
148 #[test]
149 fn test_decode_8bytes() {
150 let v: u64 = 151_288_809_941_952_652;
151 let encoded = (v | 0xC000_0000_0000_0000).to_be_bytes();
152 let (val, len) = decode(&encoded).unwrap();
153 assert_eq!(val, v);
154 assert_eq!(len, 8);
155 }
156
157 #[test]
158 fn test_encode_decode_roundtrip() {
159 for &v in &[
160 0u64,
161 1,
162 63,
163 64,
164 16383,
165 16384,
166 1_073_741_823,
167 1_073_741_824,
168 VARINT_MAX,
169 ] {
170 let encoded = encode(v);
171 let (decoded, _) = decode(&encoded).unwrap();
172 assert_eq!(decoded, v, "roundtrip failed for {}", v);
173 }
174 }
175
176 #[test]
177 fn test_encoded_len() {
178 assert_eq!(encoded_len(0), 1);
179 assert_eq!(encoded_len(63), 1);
180 assert_eq!(encoded_len(64), 2);
181 assert_eq!(encoded_len(16383), 2);
182 assert_eq!(encoded_len(16384), 4);
183 assert_eq!(encoded_len(1_073_741_823), 4);
184 assert_eq!(encoded_len(1_073_741_824), 8);
185 assert_eq!(encoded_len(VARINT_MAX), 8);
186 }
187
188 #[test]
189 fn test_decode_empty() {
190 assert!(decode(&[]).is_none());
191 }
192
193 #[test]
194 fn test_decode_too_short() {
195 assert!(decode(&[0x40]).is_none());
197 assert!(decode(&[0x80, 0x01]).is_none());
199 assert!(decode(&[0xC0, 0x01, 0x02, 0x03]).is_none());
201 }
202}