use std::io::{self, BufRead, Read};
use std::vec::Vec;
use super::stream::Decoder;
use crate::Format;
const BUF_LEN: usize = 256 * 1024;
const FIRST_VEC_LEN: usize = 16 * 1024;
pub struct Reader<R> {
inner: R,
decoder: std::boxed::Box<Decoder>,
buf: Vec<u8>,
pending: core::ops::Range<usize>,
full: bool,
done: bool,
}
impl<R: core::fmt::Debug> core::fmt::Debug for Reader<R> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Reader")
.field("inner", &self.inner)
.field("decoder", &self.decoder)
.finish_non_exhaustive()
}
}
impl<R: BufRead> Reader<R> {
pub fn new(format: Format, inner: R) -> Self {
Reader {
inner,
decoder: std::boxed::Box::new(Decoder::new(format)),
buf: Vec::new(),
pending: 0..0,
full: false,
done: false,
}
}
pub fn decoder(&self) -> &Decoder {
&self.decoder
}
pub fn get_ref(&self) -> &R {
&self.inner
}
pub fn get_mut(&mut self) -> &mut R {
&mut self.inner
}
pub fn into_inner(self) -> R {
self.inner
}
fn fill(&mut self) -> io::Result<()> {
if self.buf.is_empty() {
self.buf = std::vec![0; BUF_LEN];
}
while self.pending.is_empty() && !self.done {
if self.full {
self.decoder.make_room(&mut self.buf);
}
let input = self.inner.fill_buf()?;
let eof = input.is_empty();
let p = self.decoder.decompress(input, &mut self.buf, eof)?;
let (consumed, len) = (p.consumed, p.output.len());
(self.done, self.full) = (p.done, p.full);
self.inner.consume(consumed);
let end = self.decoder.core.pos();
self.pending = end - len..end;
}
Ok(())
}
fn decode_to_end(&mut self, out: &mut Vec<u8>) -> io::Result<usize> {
let base = out.len();
let mut len = 0;
out.resize(base + FIRST_VEC_LEN, 0);
loop {
let input = self.inner.fill_buf()?;
let eof = input.is_empty();
match self.decoder.decompress(input, &mut out[base..], eof) {
Ok(p) => {
let (consumed, done, full) = (p.consumed, p.done, p.full);
len += p.output.len();
self.inner.consume(consumed);
if done {
self.done = true;
out.truncate(base + len);
return Ok(len);
}
if full {
out.resize(base + 2 * len, 0);
}
}
Err(e) => {
out.truncate(base + len);
return Err(e.into());
}
}
}
}
}
impl<R: BufRead> Read for Reader<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
if buf.is_empty() {
return Ok(0);
}
self.fill()?;
let n = self.pending.len().min(buf.len());
buf[..n].copy_from_slice(&self.buf[self.pending.start..self.pending.start + n]);
self.pending.start += n;
Ok(n)
}
fn read_to_end(&mut self, out: &mut Vec<u8>) -> io::Result<usize> {
if !self.done && self.decoder.total_out() == 0 && self.decoder.core.pos() == 0 {
return self.decode_to_end(out);
}
let start = out.len();
loop {
self.fill()?;
if self.pending.is_empty() {
return Ok(out.len() - start);
}
out.extend_from_slice(&self.buf[self.pending.clone()]);
self.pending.start = self.pending.end;
}
}
fn read_to_string(&mut self, out: &mut std::string::String) -> io::Result<usize> {
let mut bytes = Vec::new();
let n = self.read_to_end(&mut bytes)?;
let s = core::str::from_utf8(&bytes)
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
out.push_str(s);
Ok(n)
}
}