use libflate::non_blocking::deflate;
use std::{cmp, io};
pub trait Decoder<R>: io::Read
where
R: io::Read,
{
fn into_inner(self: Box<Self>) -> R;
fn as_inner_mut(&mut self) -> &mut R;
}
impl<R> Decoder<R> for deflate::Decoder<R>
where
R: io::Read,
{
fn into_inner(self: Box<Self>) -> R {
deflate::Decoder::into_inner(*self)
}
fn as_inner_mut(&mut self) -> &mut R {
deflate::Decoder::as_inner_mut(self)
}
}
pub struct StoreDecoder<R>
where
R: io::Read,
{
inner: R,
}
impl<R> StoreDecoder<R>
where
R: io::Read,
{
pub fn new(inner: R) -> Self {
Self { inner }
}
}
impl<R> io::Read for StoreDecoder<R>
where
R: io::Read,
{
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
}
impl<R> Decoder<R> for StoreDecoder<R>
where
R: io::Read,
{
fn into_inner(self: Box<Self>) -> R {
self.inner
}
fn as_inner_mut(&mut self) -> &mut R {
&mut self.inner
}
}
pub struct LimitedReader {
remaining: u64,
inner: circular::Buffer,
}
impl LimitedReader {
pub fn new(inner: circular::Buffer, remaining: u64) -> Self {
Self { inner, remaining }
}
pub fn into_inner(self) -> circular::Buffer {
self.inner
}
pub fn as_inner_mut(&mut self) -> &mut circular::Buffer {
&mut self.inner
}
}
impl io::Read for LimitedReader {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
if self.inner.available_space() == 0 {
self.inner.shift();
}
let len = cmp::min(buf.len() as u64, self.remaining) as usize;
let res = self.inner.read(&mut buf[..len]);
if let Ok(n) = res {
self.remaining -= n as u64;
}
res
}
}
pub struct EOFNormalizer<R>
where
R: io::Read,
{
inner: R,
}
impl<R> EOFNormalizer<R>
where
R: io::Read,
{
pub fn new(inner: R) -> Self {
Self { inner }
}
}
impl<R> io::Read for EOFNormalizer<R>
where
R: io::Read,
{
#[inline]
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
#[cfg(windows)]
match self.inner.read(buf) {
Err(e) => match e.raw_os_error() {
Some(38) => Ok(0),
_ => Err(e),
},
x => x,
}
#[cfg(not(windows))]
self.inner.read(buf)
}
}