pcap_file/
read_buffer.rs

1use std::io::{Error, ErrorKind, Read};
2
3use crate::PcapError;
4
5
6/// Internal structure that bufferize its input and allow to parse element from its buffer.
7#[derive(Debug)]
8pub(crate) struct ReadBuffer<R: Read> {
9    /// Reader from which we read the data from
10    reader: R,
11    /// Internal buffer
12    buffer: Vec<u8>,
13    /// Current start position of the buffer
14    pos: usize,
15    /// Current end position of the buffer
16    len: usize,
17}
18
19impl<R: Read> ReadBuffer<R> {
20    /// Creates a new ReadBuffer with capacity of 8_000_000
21    pub fn new(reader: R) -> Self {
22        Self::with_capacity(reader, 8_000_000)
23    }
24
25    /// Creates a new ReadBuffer with the given capacity
26    pub fn with_capacity(reader: R, capacity: usize) -> Self {
27        Self { reader, buffer: vec![0_u8; capacity], pos: 0, len: 0 }
28    }
29
30    /// Parse data from the internal buffer
31    ///
32    /// Safety
33    ///
34    /// The parser must NOT keep a reference to the buffer in input.
35    pub fn parse_with<'a, 'b: 'a, 'c: 'a, F, O>(&'c mut self, mut parser: F) -> Result<O, PcapError>
36    where
37        F: FnMut(&'a [u8]) -> Result<(&'a [u8], O), PcapError>,
38        F: 'b,
39        O: 'a,
40    {
41        loop {
42            let buf = &self.buffer[self.pos..self.len];
43
44            // Sound because 'b and 'c must outlive 'a so the buffer cannot be modified while someone has a ref on it
45            let buf: &'a [u8] = unsafe { std::mem::transmute(buf) };
46
47            match parser(buf) {
48                Ok((rem, value)) => {
49                    self.advance_with_slice(rem);
50                    return Ok(value);
51                },
52
53                Err(PcapError::IncompleteBuffer) => {
54                    // The parsed data len should never be more than the buffer capacity
55                    if buf.len() == self.buffer.len() {
56                        return Err(PcapError::IoError(Error::from(ErrorKind::UnexpectedEof)));
57                    }
58
59                    let nb_read = self.fill_buf().map_err(PcapError::IoError)?;
60                    if nb_read == 0 {
61                        return Err(PcapError::IoError(Error::from(ErrorKind::UnexpectedEof)));
62                    }
63                },
64
65                Err(e) => return Err(e),
66            }
67        }
68    }
69
70    /// Fill the inner buffer.
71    /// Copy the remaining data inside buffer at its start and the fill the end part with data from the reader.
72    fn fill_buf(&mut self) -> Result<usize, std::io::Error> {
73        // Copy the remaining data to the start of the buffer
74        let rem_len = unsafe {
75            let buf_ptr_mut = self.buffer.as_mut_ptr();
76            let rem_ptr_mut = buf_ptr_mut.add(self.pos);
77            std::ptr::copy(rem_ptr_mut, buf_ptr_mut, self.len - self.pos);
78            self.len - self.pos
79        };
80
81        let nb_read = self.reader.read(&mut self.buffer[rem_len..])?;
82
83        self.len = rem_len + nb_read;
84        self.pos = 0;
85
86        Ok(nb_read)
87    }
88
89    /// Advance the internal buffer position.
90    fn advance(&mut self, nb_bytes: usize) {
91        assert!(self.pos + nb_bytes <= self.len);
92        self.pos += nb_bytes;
93    }
94
95    /// Advance the internal buffer position.
96    fn advance_with_slice(&mut self, rem: &[u8]) {
97        // Compute the length between the buffer and the slice
98        let diff_len = (rem.as_ptr() as usize)
99            .checked_sub(self.buffer().as_ptr() as usize)
100            .expect("Rem is not a sub slice of self.buffer");
101
102        self.advance(diff_len)
103    }
104
105    /// Return the valid data of the internal buffer
106    pub fn buffer(&self) -> &[u8] {
107        &self.buffer[self.pos..self.len]
108    }
109
110    /// Return true there are some data that can be read
111    pub fn has_data_left(&mut self) -> Result<bool, std::io::Error> {
112        // The buffer can be empty and the reader can still have data
113        if self.buffer().is_empty() {
114            let nb_read = self.fill_buf()?;
115            if nb_read == 0 {
116                return Ok(false);
117            }
118        }
119
120        Ok(true)
121    }
122
123    /// Return the inner reader
124    pub fn into_inner(self) -> R {
125        self.reader
126    }
127
128    /// Return a reference over the inner reader
129    pub fn get_ref(&self) -> &R {
130        &self.reader
131    }
132}
133
134#[cfg(test)]
135mod test {
136    /*
137    // Shouldn't compile
138    #[test]
139    fn parse_with_safety() {
140        let a = &[0_u8; 10];
141        let b = &mut &a[..];
142
143        let input = vec![1_u8; 100];
144        let input_read = &mut &input[..];
145        let mut reader = super::ReadBuffer::new(input_read);
146
147        unsafe {
148            reader.parse_with(|buf| {
149                *b = buf;
150                Ok((buf, ()))
151            });
152        }
153
154        unsafe {
155            reader.has_data_left();
156        }
157
158        println!("{:?}", b);
159    }
160    */
161}