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}