substrate_data/wire/io/
framing.rs1use std::io::{self, Read, Write};
4
5use crate::Schema;
6
7pub type Len = u32;
9pub const MAX_FRAME: usize = 256 << 20;
11
12pub fn write_frame<T: Schema>(w: &mut impl Write, message: &T) -> io::Result<()> {
18 write_frame_bytes(w, &crate::to_bytes(message))
19}
20
21pub fn write_frame_bytes(w: &mut impl Write, bytes: &[u8]) -> io::Result<()> {
27 let len = Len::try_from(bytes.len())
28 .ok()
29 .filter(|_| bytes.len() <= MAX_FRAME)
30 .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidInput, "frame too long"))?;
31 let mut frame = Vec::with_capacity(size_of::<Len>() + bytes.len());
33 frame.extend_from_slice(&len.to_le_bytes());
34 frame.extend_from_slice(bytes);
35 w.write_all(&frame)?;
36 w.flush()
37}
38
39pub fn read_frame_bytes(r: &mut impl Read) -> io::Result<Option<Vec<u8>>> {
45 let mut len = [0; size_of::<Len>()];
46 match r.read_exact(&mut len) {
47 Err(e) if e.kind() == io::ErrorKind::UnexpectedEof => return Ok(None),
48 other => other?,
49 }
50 let len = Len::from_le_bytes(len) as usize;
51 if len > MAX_FRAME {
52 return Err(io::Error::new(io::ErrorKind::InvalidData, "frame too long"));
53 }
54 let mut bytes = vec![0; len];
55 r.read_exact(&mut bytes)?;
56 Ok(Some(bytes))
57}
58
59pub fn read_frame<T: Schema>(r: &mut impl Read) -> io::Result<Option<T>> {
65 let Some(bytes) = read_frame_bytes(r)? else {
66 return Ok(None);
67 };
68 crate::read_bytes(&bytes)
69 .map(Some)
70 .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, crate::Errors(e)))
71}