1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use std::io::Read;

use crate::Segment;

/// A reader that reads variable-length encoded data from a stream.
/// Data is read in little-endian unless the big-endian feature is enabled.
/// # Example
/// ```
/// use send_it::reader::VarReader;
///
/// // Create a sample stream, this is the output from the above test_writer test
/// 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];
/// // turn the vector into a slice as Vec does not implement Read
/// let mut fake_stream = stream.as_slice();
///
/// // create a new VarReader
/// let mut reader = crate::reader::VarReader::new(&mut fake_stream);
///
/// let data = reader.read_data().unwrap();
/// assert_eq!(data[0].to_string(), "Hello");
/// assert_eq!(data[1].to_string(), "World");
/// ```
pub struct VarReader<'a, R: Read> {
    reader: &'a mut R,
}

impl<'a, R: Read> VarReader<'a, R> {
    /// Create a new VarReader
    pub fn new(reader: &'a mut R) -> Self {
        VarReader { reader }
    }

    fn read_varint(&mut self) -> std::io::Result<usize> {
        let mut value = 0usize;
        let mut shift = 0;
        loop {
            let mut buf = [0; 1];
            self.reader.read_exact(&mut buf)?;
            let byte = buf[0];
            value |= ((byte & 0x7F) as usize) << shift;
            shift += 7;
            if byte & 0x80 == 0 {
                break;
            }
        }
        Ok(value)
    }

    #[cfg(not(feature = "big-endian"))]
    fn read_u32(&mut self) -> std::io::Result<u32> {
        let mut bytes = [0; 4];
        self.reader.read_exact(&mut bytes)?;
        Ok(u32::from_le_bytes(bytes))
    }

    #[cfg(feature = "big-endian")]
    fn read_u32(&mut self) -> std::io::Result<u32> {
        let mut bytes = [0; 4];
        self.reader.read_exact(&mut bytes)?;
        Ok(u32::from_be_bytes(bytes))
    }

    /// Reads data from the stream.
    /// # Example
    /// ```
    /// use send_it::reader::VarReader;
    ///
    /// 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];
    /// // turn the vector into a slice as Vec does not implement Read
    /// let mut fake_stream = stream.as_slice();
    ///
    /// // create a new VarReader
    /// let mut reader = crate::reader::VarReader::new(&mut fake_stream);
    ///
    /// let data = reader.read_data().unwrap();
    /// assert_eq!(data[0].to_string(), "Hello");
    /// assert_eq!(data[1].to_string(), "World");
    /// ```
    pub fn read_data(&mut self) -> std::io::Result<Vec<Segment>> {
        let total_size = self.read_varint()?;
        let mut data = Vec::new();

        while data.iter().map(|segment: &Segment| segment.len() + 4).sum::<usize>() < total_size {
            let segment_size = self.read_u32()? as usize;
            let mut segment_data = vec![0u8; segment_size];
            self.reader.read_exact(&mut segment_data)?;
            data.push(Segment::from(segment_data));
        }

        Ok(data)
    }
}