send_it/reader.rs
1use std::io::Read;
2
3use crate::Segment;
4
5/// A reader that reads variable-length encoded data from a stream.
6/// Data is read in little-endian unless the big-endian feature is enabled.
7/// # Example
8/// ```
9/// use send_it::reader::VarReader;
10///
11/// // Create a sample stream, this is the output from the above test_writer test
12/// let stream: Vec<u8> = vec![21, 7, 0, 0, 0, 72, 101, 108, 108, 111, 44, 32, 6, 0, 0, 0, 87, 111, 114, 108, 100, 33];
13/// // turn the vector into a slice as Vec does not implement Read
14/// let mut fake_stream = stream.as_slice();
15///
16/// // create a new VarReader
17/// let mut reader = crate::reader::VarReader::new(&mut fake_stream);
18///
19/// let data = reader.read_data().unwrap();
20/// assert_eq!(data[0].to_string(), "Hello");
21/// assert_eq!(data[1].to_string(), "World");
22/// ```
23pub struct VarReader<'a, R: Read> {
24 reader: &'a mut R,
25}
26
27impl<'a, R: Read> VarReader<'a, R> {
28 /// Create a new VarReader
29 pub fn new(reader: &'a mut R) -> Self {
30 VarReader { reader }
31 }
32
33 fn read_varint(&mut self) -> std::io::Result<usize> {
34 let mut value = 0usize;
35 let mut shift = 0;
36 loop {
37 let mut buf = [0; 1];
38 self.reader.read_exact(&mut buf)?;
39 let byte = buf[0];
40 value |= ((byte & 0x7F) as usize) << shift;
41 shift += 7;
42 if byte & 0x80 == 0 {
43 break;
44 }
45 }
46 Ok(value)
47 }
48
49 #[cfg(not(feature = "big-endian"))]
50 fn read_u32(&mut self) -> std::io::Result<u32> {
51 let mut bytes = [0; 4];
52 self.reader.read_exact(&mut bytes)?;
53 Ok(u32::from_le_bytes(bytes))
54 }
55
56 #[cfg(feature = "big-endian")]
57 fn read_u32(&mut self) -> std::io::Result<u32> {
58 let mut bytes = [0; 4];
59 self.reader.read_exact(&mut bytes)?;
60 Ok(u32::from_be_bytes(bytes))
61 }
62
63 /// Reads data from the stream.
64 /// # Example
65 /// ```
66 /// use send_it::reader::VarReader;
67 ///
68 /// let stream: Vec<u8> = vec![21, 7, 0, 0, 0, 72, 101, 108, 108, 111, 44, 32, 6, 0, 0, 0, 87, 111, 114, 108, 100, 33];
69 /// // turn the vector into a slice as Vec does not implement Read
70 /// let mut fake_stream = stream.as_slice();
71 ///
72 /// // create a new VarReader
73 /// let mut reader = crate::reader::VarReader::new(&mut fake_stream);
74 ///
75 /// let data = reader.read_data().unwrap();
76 /// assert_eq!(data[0].to_string(), "Hello");
77 /// assert_eq!(data[1].to_string(), "World");
78 /// ```
79 pub fn read_data(&mut self) -> std::io::Result<Vec<Segment>> {
80 let total_size = self.read_varint()?;
81 let mut data = Vec::new();
82
83 while data.iter().map(|segment: &Segment| segment.len() + 4).sum::<usize>() < total_size {
84 let segment_size = self.read_u32()? as usize;
85 let mut segment_data = vec![0u8; segment_size];
86 self.reader.read_exact(&mut segment_data)?;
87 data.push(Segment::from(segment_data));
88 }
89
90 Ok(data)
91 }
92}