pim_protocol/
length_delimited.rs1use bytes::{Buf, BufMut, BytesMut};
2
3use pim_core::PimError;
4
5pub struct LengthDelimitedCodec;
10
11const MAX_FRAME_SIZE: u32 = 1_048_576;
13
14impl LengthDelimitedCodec {
15 pub fn encode(payload: &[u8], buf: &mut BytesMut) {
17 buf.put_u32(payload.len() as u32);
18 buf.put_slice(payload);
19 }
20
21 pub fn decode(buf: &mut BytesMut) -> Result<Option<BytesMut>, PimError> {
28 if buf.len() < 4 {
29 return Ok(None);
30 }
31
32 let length = (&buf[0..4]).get_u32();
33
34 if length > MAX_FRAME_SIZE {
35 return Err(PimError::Protocol(format!(
36 "frame too large: {length} bytes, max {MAX_FRAME_SIZE}"
37 )));
38 }
39
40 let total = 4 + length as usize;
41 if buf.len() < total {
42 return Ok(None); }
44
45 buf.advance(4); let payload = buf.split_to(length as usize);
47 Ok(Some(payload))
48 }
49}
50
51#[cfg(test)]
52mod tests;