Skip to main content

indigo_term/
reader.rs

1use crate::{event::Event, parser};
2use std::io::{self, Read};
3use tinyvec::ArrayVec;
4use winnow::{Parser, Partial, error::ErrMode};
5
6#[derive(Default)]
7pub struct Reader {
8    buffer: ArrayVec<[u8; 1024]>,
9}
10
11impl Reader {
12    #[must_use]
13    pub fn new() -> Self {
14        Self::default()
15    }
16
17    /// Read the next event from the input source. Blocks until a complete event is available.
18    pub fn read_event(&mut self, input: &mut impl Read) -> io::Result<Event> {
19        loop {
20            self.skip_garbage();
21
22            if !self.buffer.is_empty() {
23                let input_slice = Partial::new(self.buffer.as_slice());
24                match parser::event.parse_peek(input_slice) {
25                    Ok((remaining, event)) => {
26                        let consumed = self.buffer.len() - remaining.len();
27                        self.buffer.drain(..consumed);
28                        return Ok(event);
29                    }
30                    Err(ErrMode::Incomplete(_)) => {
31                        // Need more bytes, fall through to fill_buffer below
32                    }
33                    Err(_) => {
34                        // Malformed sequence, skip the leading 0x1b and retry
35                        self.buffer.drain(..1);
36                        continue;
37                    }
38                }
39            }
40
41            self.fill_buffer(input)?;
42        }
43    }
44
45    /// Read bytes from the input source into the internal buffer. Blocks until at least one byte is
46    /// available.
47    fn fill_buffer(&mut self, input: &mut impl Read) -> io::Result<()> {
48        let remaining_capacity = self.buffer.capacity() - self.buffer.len();
49        if remaining_capacity == 0 {
50            return Err(io::Error::other("reader buffer full"));
51        }
52        let mut tmp = [0u8; 256];
53        let max_read = remaining_capacity.min(tmp.len());
54        let bytes_read = input.read(&mut tmp[..max_read])?;
55        if bytes_read == 0 {
56            return Err(io::Error::new(io::ErrorKind::UnexpectedEof, "input closed"));
57        }
58        self.buffer.extend_from_slice(&tmp[..bytes_read]);
59        Ok(())
60    }
61
62    /// Skip any non-ESC bytes at the front of the buffer. These are garbage bytes that don't start
63    /// any recognized sequence.
64    fn skip_garbage(&mut self) {
65        let garbage_count = self
66            .buffer
67            .iter()
68            .position(|&byte| byte == /* ESC */ 0x1B)
69            .unwrap_or(self.buffer.len());
70        if garbage_count > 0 {
71            self.buffer.drain(..garbage_count);
72        }
73    }
74}