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