diff --git a/src/decode/lzbuffer.rs b/src/decode/lzbuffer.rs index 258e587..fecd593 100644 --- a/src/decode/lzbuffer.rs +++ b/src/decode/lzbuffer.rs @@ -1,7 +1,10 @@ use crate::error; use std::io; -pub trait LZBuffer { +pub trait LZBuffer +where + W: io::Write, +{ fn len(&self) -> usize; // Retrieve the last byte or return a default fn last_or(&self, lit: u8) -> u8; @@ -11,30 +14,34 @@ pub trait LZBuffer { fn append_literal(&mut self, lit: u8) -> error::Result<()>; // Fetch an LZ sequence (length, distance) from inside the buffer fn append_lz(&mut self, len: usize, dist: usize) -> error::Result<()>; + // Get a reference to the output sink + fn get_output(&self) -> &W; + // Get a mutable reference to the output sink + fn get_output_mut(&mut self) -> &mut W; // Flush the buffer to the output - fn finish(self) -> io::Result<()>; + fn finish(self) -> io::Result; } // An accumulating buffer for LZ sequences -pub struct LZAccumBuffer<'a, W> +pub struct LZAccumBuffer where - W: 'a + io::Write, + W: io::Write, { - stream: &'a mut W, // Output sink - buf: Vec, // Buffer - memlimit: usize, // Buffer memory limit - len: usize, // Total number of bytes sent through the buffer + stream: W, // Output sink + buf: Vec, // Buffer + memlimit: usize, // Buffer memory limit + len: usize, // Total number of bytes sent through the buffer } -impl<'a, W> LZAccumBuffer<'a, W> +impl LZAccumBuffer where W: io::Write, { - pub fn from_stream(stream: &'a mut W) -> Self { + pub fn from_stream(stream: W) -> Self { Self::from_stream_with_memlimit(stream, std::usize::MAX) } - pub fn from_stream_with_memlimit(stream: &'a mut W, memlimit: usize) -> Self { + pub fn from_stream_with_memlimit(stream: W, memlimit: usize) -> Self { Self { stream, buf: Vec::new(), @@ -58,7 +65,7 @@ where } } -impl<'a, W> LZBuffer for LZAccumBuffer<'a, W> +impl LZBuffer for LZAccumBuffer where W: io::Write, { @@ -126,32 +133,42 @@ where Ok(()) } + // Get a reference to the output sink + fn get_output(&self) -> &W { + &self.stream + } + + // Get a mutable reference to the output sink + fn get_output_mut(&mut self) -> &mut W { + &mut self.stream + } + // Flush the buffer to the output - fn finish(self) -> io::Result<()> { + fn finish(mut self) -> io::Result { self.stream.write_all(self.buf.as_slice())?; self.stream.flush()?; - Ok(()) + Ok(self.stream) } } // A circular buffer for LZ sequences -pub struct LZCircularBuffer<'a, W> +pub struct LZCircularBuffer where - W: 'a + io::Write, + W: io::Write, { - stream: &'a mut W, // Output sink - buf: Vec, // Circular buffer - dict_size: usize, // Length of the buffer - memlimit: usize, // Buffer memory limit - cursor: usize, // Current position - len: usize, // Total number of bytes sent through the buffer + stream: W, // Output sink + buf: Vec, // Circular buffer + dict_size: usize, // Length of the buffer + memlimit: usize, // Buffer memory limit + cursor: usize, // Current position + len: usize, // Total number of bytes sent through the buffer } -impl<'a, W> LZCircularBuffer<'a, W> +impl LZCircularBuffer where W: io::Write, { - pub fn from_stream_with_memlimit(stream: &'a mut W, dict_size: usize, memlimit: usize) -> Self { + pub fn from_stream_with_memlimit(stream: W, dict_size: usize, memlimit: usize) -> Self { lzma_info!("Dict size in LZ buffer: {}", dict_size); Self { stream, @@ -185,7 +202,7 @@ where } } -impl<'a, W> LZBuffer for LZCircularBuffer<'a, W> +impl LZBuffer for LZCircularBuffer where W: io::Write, { @@ -264,12 +281,22 @@ where Ok(()) } + // Get a reference to the output sink + fn get_output(&self) -> &W { + &self.stream + } + + // Get a mutable reference to the output sink + fn get_output_mut(&mut self) -> &mut W { + &mut self.stream + } + // Flush the buffer to the output - fn finish(self) -> io::Result<()> { + fn finish(mut self) -> io::Result { if self.cursor > 0 { self.stream.write_all(&self.buf[0..self.cursor])?; self.stream.flush()?; } - Ok(()) + Ok(self.stream) } } diff --git a/src/decode/lzma.rs b/src/decode/lzma.rs index 8890b1e..fbe164b 100644 --- a/src/decode/lzma.rs +++ b/src/decode/lzma.rs @@ -3,6 +3,7 @@ use crate::decode::rangecoder; use crate::error; use byteorder::{LittleEndian, ReadBytesExt}; use std::io; +use std::marker::PhantomData; use crate::decompress::Options; use crate::decompress::UnpackedSize; @@ -97,10 +98,12 @@ impl LZMAParams { } } -pub struct DecoderState +pub struct DecoderState where - LZB: lzbuffer::LZBuffer, + W: io::Write, + LZB: lzbuffer::LZBuffer, { + _phantom: PhantomData, pub output: LZB, // most lc significant bits of previous byte are part of the literal context pub lc: u32, // 0..8 @@ -125,17 +128,18 @@ where } // Initialize decoder with accumulating buffer -pub fn new_accum<'a, W>( - output: lzbuffer::LZAccumBuffer<'a, W>, +pub fn new_accum( + output: lzbuffer::LZAccumBuffer, lc: u32, lp: u32, pb: u32, unpacked_size: Option, -) -> DecoderState> +) -> DecoderState> where W: io::Write, { DecoderState { + _phantom: PhantomData, output, lc, lp, @@ -159,10 +163,10 @@ where } // Initialize decoder with circular buffer -pub fn new_circular<'a, W>( - output: &'a mut W, +pub fn new_circular( + output: W, params: LZMAParams, -) -> error::Result>> +) -> error::Result>> where W: io::Write, { @@ -170,16 +174,17 @@ where } // Initialize decoder with circular buffer -pub fn new_circular_with_memlimit<'a, W>( - output: &'a mut W, +pub fn new_circular_with_memlimit( + output: W, params: LZMAParams, memlimit: usize, -) -> error::Result>> +) -> error::Result>> where W: io::Write, { // Decoder let decoder = DecoderState { + _phantom: PhantomData, output: lzbuffer::LZCircularBuffer::from_stream_with_memlimit( output, params.dict_size as usize, @@ -208,9 +213,10 @@ where Ok(decoder) } -impl DecoderState +impl DecoderState where - LZB: lzbuffer::LZBuffer, + W: io::Write, + LZB: lzbuffer::LZBuffer, { pub fn reset_state(&mut self, lc: u32, lp: u32, pb: u32) { self.lc = lc; diff --git a/src/decode/lzma2.rs b/src/decode/lzma2.rs index a50b9fd..725c93b 100644 --- a/src/decode/lzma2.rs +++ b/src/decode/lzma2.rs @@ -43,8 +43,8 @@ where Ok(()) } -fn parse_lzma<'a, R, W>( - decoder: &mut lzma::DecoderState>, +fn parse_lzma( + decoder: &mut lzma::DecoderState>, input: &mut R, status: u8, ) -> error::Result<()> @@ -165,8 +165,8 @@ where decoder.process(&mut rangecoder) } -fn parse_uncompressed<'a, R, W>( - decoder: &mut lzma::DecoderState>, +fn parse_uncompressed( + decoder: &mut lzma::DecoderState>, input: &mut R, reset_dict: bool, ) -> error::Result<()>