lzlib 0.1.0

Lzip compression and decompression
Documentation
use std::io;

use crate::Param;

const BUF_SIZE: usize = 16384;

struct CodecWriter<C, W> {
    codec: C,
    writer: W,
    buf: Box<[u8; BUF_SIZE]>,
}
impl<C: super::Codec, W: io::Write> CodecWriter<C, W> {
    fn write_buf(&mut self) -> io::Result<()> {
        let rdr_len = self
            .codec
            .lzip_read(self.buf.as_mut_slice())
            .map_err(io::Error::other)?;
        self.writer.write_all(&self.buf[0..rdr_len])
    }
    fn into_inner(mut self) -> io::Result<W> {
        self.codec.lzip_finish();
        while !self.codec.lzip_finished() {
            self.write_buf()?;
        }
        Ok(self.writer)
    }
}
impl<C: super::Codec, W: io::Write> io::Write for CodecWriter<C, W> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        if buf.is_empty() {
            return Ok(0);
        }
        loop {
            match self.codec.lzip_write(buf) {
                Ok(0) => self.write_buf()?,
                Ok(n) => {
                    self.write_buf()?;
                    break Ok(n);
                }
                Err(e) => break Err(io::Error::other(e)),
            }
        }
    }
    fn flush(&mut self) -> io::Result<()> {
        self.write_buf()
    }
}

pub struct LzEncoder<W>(CodecWriter<super::Encoder, W>);
impl<W: io::Write> LzEncoder<W> {
    pub fn new(param: Param, writer: W) -> Result<Self, super::Error> {
        Ok(Self(CodecWriter {
            codec: super::Encoder::new(param)?,
            writer,
            buf: Box::new([0; BUF_SIZE]),
        }))
    }
    pub fn restart_member(&mut self, member_size: u64) -> io::Result<()> {
        while !self.0.codec.member_finished() {
            self.0.write_buf()?;
        }
        self.0
            .codec
            .restart_member(member_size)
            .map_err(io::Error::other)
    }
    pub fn into_inner(self) -> io::Result<W> {
        self.0.into_inner()
    }
}
impl<W: io::Write> io::Write for LzEncoder<W> {
    #[inline]
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.0.write(buf)
    }
    #[inline]
    fn flush(&mut self) -> io::Result<()> {
        self.0.flush()
    }
}

pub struct LzDecoder<W>(CodecWriter<super::Decoder, W>);
impl<W> LzDecoder<W> {
    pub fn new(writer: W) -> Result<Self, super::Error> {
        Ok(Self(CodecWriter {
            codec: super::Decoder::new()?,
            writer,
            buf: Box::new([0; BUF_SIZE]),
        }))
    }
}
impl<W: io::Write> LzDecoder<W> {
    pub fn into_inner(self) -> io::Result<W> {
        self.0.into_inner()
    }
}
impl<W: io::Write> io::Write for LzDecoder<W> {
    #[inline]
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.0.write(buf)
    }
    #[inline]
    fn flush(&mut self) -> io::Result<()> {
        self.0.flush()
    }
}