quic_reverse_control/
framing.rs1use crate::ControlError;
29use bytes::{Buf, BufMut, BytesMut};
30
31pub const MAX_FRAME_SIZE: usize = 65536;
35
36const LENGTH_PREFIX_SIZE: usize = 4;
38
39#[derive(Debug, Default)]
44pub struct FrameReader {
45 buffer: BytesMut,
47}
48
49impl FrameReader {
50 #[must_use]
52 pub fn new() -> Self {
53 Self {
54 buffer: BytesMut::new(),
55 }
56 }
57
58 #[must_use]
60 pub fn with_capacity(capacity: usize) -> Self {
61 Self {
62 buffer: BytesMut::with_capacity(capacity),
63 }
64 }
65
66 pub fn extend(&mut self, data: &[u8]) {
68 self.buffer.extend_from_slice(data);
69 }
70
71 pub fn read_frame(&mut self) -> Result<Option<Vec<u8>>, ControlError> {
81 if self.buffer.len() < LENGTH_PREFIX_SIZE {
83 return Ok(None);
84 }
85
86 let length = u32::from_be_bytes([
88 self.buffer[0],
89 self.buffer[1],
90 self.buffer[2],
91 self.buffer[3],
92 ]) as usize;
93
94 if length > MAX_FRAME_SIZE {
96 return Err(ControlError::FrameTooLarge { size: length });
97 }
98
99 let total_length = LENGTH_PREFIX_SIZE + length;
101 if self.buffer.len() < total_length {
102 return Ok(None);
103 }
104
105 self.buffer.advance(LENGTH_PREFIX_SIZE);
107
108 let payload = self.buffer.split_to(length).to_vec();
110
111 Ok(Some(payload))
112 }
113
114 #[must_use]
116 pub fn buffered_len(&self) -> usize {
117 self.buffer.len()
118 }
119
120 #[must_use]
122 pub fn is_empty(&self) -> bool {
123 self.buffer.is_empty()
124 }
125
126 pub fn clear(&mut self) {
128 self.buffer.clear();
129 }
130}
131
132#[derive(Debug, Default)]
134pub struct FrameWriter {
135 buffer: BytesMut,
137}
138
139impl FrameWriter {
140 #[must_use]
142 pub fn new() -> Self {
143 Self {
144 buffer: BytesMut::new(),
145 }
146 }
147
148 #[must_use]
150 pub fn with_capacity(capacity: usize) -> Self {
151 Self {
152 buffer: BytesMut::with_capacity(capacity),
153 }
154 }
155
156 pub fn write_frame(&mut self, payload: &[u8]) -> Result<(), ControlError> {
162 if payload.len() > MAX_FRAME_SIZE {
163 return Err(ControlError::FrameTooLarge {
164 size: payload.len(),
165 });
166 }
167
168 self.buffer.reserve(LENGTH_PREFIX_SIZE + payload.len());
170
171 #[allow(clippy::cast_possible_truncation)]
173 self.buffer.put_u32(payload.len() as u32);
174
175 self.buffer.extend_from_slice(payload);
177
178 Ok(())
179 }
180
181 pub fn take_bytes(&mut self) -> Vec<u8> {
185 self.buffer.split().to_vec()
186 }
187
188 #[must_use]
190 pub fn as_bytes(&self) -> &[u8] {
191 &self.buffer
192 }
193
194 #[must_use]
196 pub fn len(&self) -> usize {
197 self.buffer.len()
198 }
199
200 #[must_use]
202 pub fn is_empty(&self) -> bool {
203 self.buffer.is_empty()
204 }
205
206 pub fn clear(&mut self) {
208 self.buffer.clear();
209 }
210}
211
212pub fn encode_frame(payload: &[u8]) -> Result<Vec<u8>, ControlError> {
220 let mut writer = FrameWriter::with_capacity(LENGTH_PREFIX_SIZE + payload.len());
221 writer.write_frame(payload)?;
222 Ok(writer.take_bytes())
223}
224
225pub fn decode_frame(data: &[u8]) -> Result<Vec<u8>, ControlError> {
234 if data.len() < LENGTH_PREFIX_SIZE {
235 return Err(ControlError::UnexpectedEof {
236 expected: LENGTH_PREFIX_SIZE,
237 actual: data.len(),
238 });
239 }
240
241 let length = u32::from_be_bytes([data[0], data[1], data[2], data[3]]) as usize;
242
243 if length > MAX_FRAME_SIZE {
244 return Err(ControlError::FrameTooLarge { size: length });
245 }
246
247 let total_length = LENGTH_PREFIX_SIZE + length;
248 if data.len() < total_length {
249 return Err(ControlError::UnexpectedEof {
250 expected: total_length,
251 actual: data.len(),
252 });
253 }
254
255 Ok(data[LENGTH_PREFIX_SIZE..total_length].to_vec())
256}
257
258#[cfg(test)]
259mod tests {
260 use super::*;
261
262 #[test]
263 fn frame_round_trip() {
264 let payload = b"hello, world!";
265 let encoded = encode_frame(payload).expect("encode should succeed");
266 let decoded = decode_frame(&encoded).expect("decode should succeed");
267 assert_eq!(decoded, payload);
268 }
269
270 #[test]
271 fn frame_reader_complete() {
272 let mut reader = FrameReader::new();
273 let payload = b"test payload";
274 let frame = encode_frame(payload).expect("encode should succeed");
275
276 reader.extend(&frame);
277 let result = reader.read_frame().expect("read should succeed");
278 assert_eq!(result, Some(payload.to_vec()));
279 assert!(reader.is_empty());
280 }
281
282 #[test]
283 fn frame_reader_incremental() {
284 let mut reader = FrameReader::new();
285 let payload = b"incremental test";
286 let frame = encode_frame(payload).expect("encode should succeed");
287
288 for (i, &byte) in frame.iter().enumerate() {
290 reader.extend(&[byte]);
291
292 if i < frame.len() - 1 {
293 let result = reader.read_frame().expect("read should succeed");
295 assert!(result.is_none(), "expected None at byte {i}");
296 }
297 }
298
299 let result = reader.read_frame().expect("read should succeed");
301 assert_eq!(result, Some(payload.to_vec()));
302 }
303
304 #[test]
305 fn frame_reader_multiple_frames() {
306 let mut reader = FrameReader::new();
307 let payload1 = b"first";
308 let payload2 = b"second";
309
310 let frame1 = encode_frame(payload1).expect("encode should succeed");
311 let frame2 = encode_frame(payload2).expect("encode should succeed");
312
313 reader.extend(&frame1);
315 reader.extend(&frame2);
316
317 let result1 = reader.read_frame().expect("read should succeed");
318 assert_eq!(result1, Some(payload1.to_vec()));
319
320 let result2 = reader.read_frame().expect("read should succeed");
321 assert_eq!(result2, Some(payload2.to_vec()));
322
323 assert!(reader.is_empty());
324 }
325
326 #[test]
327 fn frame_too_large_on_encode() {
328 let payload = vec![0u8; MAX_FRAME_SIZE + 1];
329 let result = encode_frame(&payload);
330 assert!(matches!(result, Err(ControlError::FrameTooLarge { .. })));
331 }
332
333 #[test]
334 fn frame_too_large_on_decode() {
335 let mut frame = Vec::new();
337 let bad_length = (MAX_FRAME_SIZE + 1) as u32;
338 frame.extend_from_slice(&bad_length.to_be_bytes());
339 frame.extend_from_slice(&[0u8; 100]); let mut reader = FrameReader::new();
342 reader.extend(&frame);
343 let result = reader.read_frame();
344 assert!(matches!(result, Err(ControlError::FrameTooLarge { .. })));
345 }
346
347 #[test]
348 fn decode_incomplete_length() {
349 let result = decode_frame(&[0, 0, 0]); assert!(matches!(result, Err(ControlError::UnexpectedEof { .. })));
351 }
352
353 #[test]
354 fn decode_incomplete_payload() {
355 let mut frame = Vec::new();
356 frame.extend_from_slice(&10u32.to_be_bytes()); frame.extend_from_slice(&[1, 2, 3, 4, 5]); let result = decode_frame(&frame);
360 assert!(matches!(result, Err(ControlError::UnexpectedEof { .. })));
361 }
362
363 #[test]
364 fn empty_frame() {
365 let encoded = encode_frame(&[]).expect("encode should succeed");
366 assert_eq!(encoded.len(), 4); let decoded = decode_frame(&encoded).expect("decode should succeed");
369 assert!(decoded.is_empty());
370 }
371
372 #[test]
373 fn frame_writer_multiple_frames() {
374 let mut writer = FrameWriter::new();
375 writer.write_frame(b"one").expect("write should succeed");
376 writer.write_frame(b"two").expect("write should succeed");
377
378 let bytes = writer.take_bytes();
379
380 let mut reader = FrameReader::new();
382 reader.extend(&bytes);
383
384 assert_eq!(
385 reader.read_frame().expect("read should succeed"),
386 Some(b"one".to_vec())
387 );
388 assert_eq!(
389 reader.read_frame().expect("read should succeed"),
390 Some(b"two".to_vec())
391 );
392 }
393}