Skip to content

Commit

Permalink
Avoid Take/Cursor in favor of manual impl
Browse files Browse the repository at this point in the history
This is a bit clearer to me at least as it wasn't entirely clear from
before how data was being read and extended simultaneously.
  • Loading branch information
alexcrichton committed Mar 13, 2019
1 parent 433f50c commit 68f285a
Showing 1 changed file with 20 additions and 9 deletions.
29 changes: 20 additions & 9 deletions src/gz/bufread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,27 +313,38 @@ enum GzState {
End
}

/// A small adapter which reads data originally from `buf` and then reads all
/// further data from `reader`. This will also buffer all data read from
/// `reader` into `buf` for reuse on a further call.
struct Buffer<'a, T> {
buf: io::Take<io::Cursor<&'a mut Vec<u8>>>,
buf: &'a mut Vec<u8>,
buf_cur: usize,
buf_max: usize,
reader: &'a mut T
}

impl<'a, T> Buffer<'a, T> {
fn new(buf: &'a mut Vec<u8>, reader: &'a mut T) -> Buffer<'a, T> {
let len = buf.len();
Buffer { buf: io::Cursor::new(buf).take(len as _), reader }
Buffer {
reader,
buf_cur: 0,
buf_max: buf.len(),
buf,
}
}
}

impl<'a, T: Read> Read for Buffer<'a, T> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let mut len = self.buf.read(buf)?;
if buf.len() > len {
let len2 = self.reader.read(&mut buf[len..])?;
self.buf.get_mut().get_mut().extend_from_slice(&buf[len..][..len2]);
len += len2;
if self.buf_cur == self.buf_max {
let len = self.reader.read(buf)?;
self.buf.extend_from_slice(&buf[..len]);
Ok(len)
} else {
let len = (&self.buf[self.buf_cur..self.buf_max]).read(buf)?;
self.buf_cur += len;
Ok(len)
}
Ok(len)
}
}

Expand Down

0 comments on commit 68f285a

Please sign in to comment.