delimited_protobuf/
lib.rs1use protobuf::Message;
2use simple_error::SimpleError;
3
4pub fn read<MSG: Message>(reader: &mut dyn std::io::Read) -> Result<MSG, SimpleError> {
6 let size = read_u32(reader).map_err(SimpleError::from)?;
7 if size == 0_u32 {
8 return Err(SimpleError::new("empty message"));
9 }
10 let mut buf = vec![0_u8; size as usize];
11 reader.read_exact(&mut buf).unwrap();
12
13 MSG::parse_from_bytes(&buf).map_err(SimpleError::from)
14}
15
16pub fn write<MSG: Message>(msg: &MSG, writer: &mut dyn std::io::Write) -> protobuf::Result<()> {
18 msg.write_length_delimited_to_writer(writer)
19}
20
21fn read_u32(reader: &mut dyn std::io::Read) -> Result<u32, SimpleError> {
23 let mut buf = [0_u8; 1];
24 let mut num_bits_read = 0;
25 let mut val: u32 = 0;
26 let mut is_last: bool;
27 let mut byte: u32;
28
29 loop {
30 reader.read_exact(&mut buf).map_err(SimpleError::from)?;
31 byte = buf[0] as u32;
32
33 is_last = byte >> 7 == 0;
34 byte &= 0b0111_1111;
35
36 byte = match byte.checked_shl(num_bits_read) {
37 None => {
38 return Err(SimpleError::new("too many bytes for u32"));
39 }
40 Some(v) => v,
41 };
42 val |= byte;
43 num_bits_read += 7;
44 if is_last {
45 break;
47 }
48 }
49
50 Ok(val)
51}