Unified · Split
| @@ -8,8 +8,10 @@ pub use sidebands::WithSidebands; · 7 unmodified lines | |||
| 8 | /// Read pack lines one after another, without consuming more than needed from the underlying | 8 | /// Read pack lines one after another, without consuming more than needed from the underlying |
| 9 | /// [`Read`][io::Read]. [`Flush`][PacketLine::Flush] lines cause the reader to stop producing lines forever, | 9 | /// [`Read`][io::Read]. [`Flush`][PacketLine::Flush] lines cause the reader to stop producing lines forever, |
| 10 | /// leaving [`Read`][io::Read] at the start of whatever comes next. | 10 | /// leaving [`Read`][io::Read] at the start of whatever comes next. |
| 11 | /// | ||
| 12 | /// This implementation tries hard not to allocate at all which leads to quite some added complexity and plenty of extra memory copies. | ||
| 11 | pub struct StreamingPeekReader<T> { | 13 | pub struct StreamingPeekReader<T> { |
| 12 | inner: T, | 14 | read: T, |
| 13 | peek_buf: Vec<u8>, | 15 | peek_buf: Vec<u8>, |
| 14 | fail_on_err_lines: bool, | 16 | fail_on_err_lines: bool, |
| 15 | buf: Vec<u8>, | 17 | buf: Vec<u8>, |
| @@ -25,7 +27,7 @@ where · 9 unmodified lines | |||
| 25 | /// Return a new instance from `read` which will stop decoding packet lines when receiving one of the given `delimiters`. | 27 | /// Return a new instance from `read` which will stop decoding packet lines when receiving one of the given `delimiters`. |
| 26 | pub fn new(read: T, delimiters: &'static [PacketLine<'static>]) -> Self { | 28 | pub fn new(read: T, delimiters: &'static [PacketLine<'static>]) -> Self { |
| 27 | StreamingPeekReader { | 29 | StreamingPeekReader { |
| 28 | inner: read, | 30 | read, |
| 29 | buf: vec![0; MAX_LINE_LEN], | 31 | buf: vec![0; MAX_LINE_LEN], |
| 30 | peek_buf: Vec::new(), | 32 | peek_buf: Vec::new(), |
| 31 | delimiters, | 33 | delimiters, |
| @@ -43,7 +45,7 @@ where · 11 unmodified lines | |||
| 43 | 45 | ||
| 44 | /// Replace the reader used with the given `read`, resetting all other iteration state as well. | 46 | /// Replace the reader used with the given `read`, resetting all other iteration state as well. |
| 45 | pub fn replace(&mut self, read: T) -> T { | 47 | pub fn replace(&mut self, read: T) -> T { |
| 46 | let prev = std::mem::replace(&mut self.inner, read); | 48 | let prev = std::mem::replace(&mut self.read, read); |
| 47 | self.reset(); | 49 | self.reset(); |
| 48 | self.fail_on_err_lines = false; | 50 | self.fail_on_err_lines = false; |
| 49 | prev | 51 | prev |
| @@ -106,7 +108,7 @@ where · 56 unmodified lines | |||
| 106 | } else if self.buf.len() != MAX_LINE_LEN { | 108 | } else if self.buf.len() != MAX_LINE_LEN { |
| 107 | self.buf.resize(MAX_LINE_LEN, 0); | 109 | self.buf.resize(MAX_LINE_LEN, 0); |
| 108 | } | 110 | } |
| 109 | match Self::read_line_inner(&mut self.inner, &mut self.buf) { | 111 | match Self::read_line_inner(&mut self.read, &mut self.buf) { |
| 110 | Ok(Ok(line)) => { | 112 | Ok(Ok(line)) => { |
| 111 | if self.delimiters.contains(&line) { | 113 | if self.delimiters.contains(&line) { |
| 112 | self.is_done = true; | 114 | self.is_done = true; |
| @@ -128,7 +130,11 @@ where · 15 unmodified lines | |||
| 128 | } | 130 | } |
| 129 | } | 131 | } |
| 130 | 132 | ||
| 131 | /// Modify the peek buffer, overwriting the byte at `position` with the given byte to `replace_with`. | 133 | /// Modify the peek buffer, overwriting the byte at `position` with the given byte to `replace_with` while truncating |
| 134 | /// it to contain only bytes until the newly replaced `position`. | ||
| 135 | /// | ||
| 136 | /// This is useful if you would want to remove 'special bytes' hidden behind, say a NULL byte to disappear and allow | ||
| 137 | /// standard line readers to read the next line as usual. | ||
| 132 | /// | 138 | /// |
| 133 | /// **Note** that `position` does not include the 4 bytes prefix (they are invisible outside the reader) | 139 | /// **Note** that `position` does not include the 4 bytes prefix (they are invisible outside the reader) |
| 134 | pub fn peek_buffer_replace_and_truncate(&mut self, position: usize, replace_with: u8) { | 140 | pub fn peek_buffer_replace_and_truncate(&mut self, position: usize, replace_with: u8) { |
| @@ -149,7 +155,7 @@ where · 14 unmodified lines | |||
| 149 | } | 155 | } |
| 150 | Some(if self.peek_buf.is_empty() { | 156 | Some(if self.peek_buf.is_empty() { |
| 151 | self.peek_buf.resize(MAX_LINE_LEN, 0); | 157 | self.peek_buf.resize(MAX_LINE_LEN, 0); |
| 152 | match Self::read_line_inner(&mut self.inner, &mut self.peek_buf) { | 158 | match Self::read_line_inner(&mut self.read, &mut self.peek_buf) { |
| 153 | Ok(Ok(line)) => { | 159 | Ok(Ok(line)) => { |
| 154 | if self.delimiters.contains(&line) { | 160 | if self.delimiters.contains(&line) { |
| 155 | self.is_done = true; | 161 | self.is_done = true; |