| //! Implementation for `miniz_oxide` rust backend. | 
 |  | 
 | use std::convert::TryInto; | 
 | use std::fmt; | 
 |  | 
 | use miniz_oxide::deflate::core::CompressorOxide; | 
 | use miniz_oxide::inflate::stream::InflateState; | 
 | pub use miniz_oxide::*; | 
 |  | 
 | pub const MZ_NO_FLUSH: isize = MZFlush::None as isize; | 
 | pub const MZ_PARTIAL_FLUSH: isize = MZFlush::Partial as isize; | 
 | pub const MZ_SYNC_FLUSH: isize = MZFlush::Sync as isize; | 
 | pub const MZ_FULL_FLUSH: isize = MZFlush::Full as isize; | 
 | pub const MZ_FINISH: isize = MZFlush::Finish as isize; | 
 |  | 
 | use super::*; | 
 | use crate::mem; | 
 |  | 
 | // miniz_oxide doesn't provide any error messages (yet?) | 
 | #[derive(Default)] | 
 | pub struct ErrorMessage; | 
 |  | 
 | impl ErrorMessage { | 
 |     pub fn get(&self) -> Option<&str> { | 
 |         None | 
 |     } | 
 | } | 
 |  | 
 | fn format_from_bool(zlib_header: bool) -> DataFormat { | 
 |     if zlib_header { | 
 |         DataFormat::Zlib | 
 |     } else { | 
 |         DataFormat::Raw | 
 |     } | 
 | } | 
 |  | 
 | pub struct Inflate { | 
 |     inner: Box<InflateState>, | 
 |     total_in: u64, | 
 |     total_out: u64, | 
 | } | 
 |  | 
 | impl fmt::Debug for Inflate { | 
 |     fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { | 
 |         write!( | 
 |             f, | 
 |             "miniz_oxide inflate internal state. total_in: {}, total_out: {}", | 
 |             self.total_in, self.total_out, | 
 |         ) | 
 |     } | 
 | } | 
 |  | 
 | impl InflateBackend for Inflate { | 
 |     fn make(zlib_header: bool, _window_bits: u8) -> Self { | 
 |         let format = format_from_bool(zlib_header); | 
 |  | 
 |         Inflate { | 
 |             inner: InflateState::new_boxed(format), | 
 |             total_in: 0, | 
 |             total_out: 0, | 
 |         } | 
 |     } | 
 |  | 
 |     fn decompress( | 
 |         &mut self, | 
 |         input: &[u8], | 
 |         output: &mut [u8], | 
 |         flush: FlushDecompress, | 
 |     ) -> Result<Status, DecompressError> { | 
 |         let flush = MZFlush::new(flush as i32).unwrap(); | 
 |  | 
 |         let res = inflate::stream::inflate(&mut self.inner, input, output, flush); | 
 |         self.total_in += res.bytes_consumed as u64; | 
 |         self.total_out += res.bytes_written as u64; | 
 |  | 
 |         match res.status { | 
 |             Ok(status) => match status { | 
 |                 MZStatus::Ok => Ok(Status::Ok), | 
 |                 MZStatus::StreamEnd => Ok(Status::StreamEnd), | 
 |                 MZStatus::NeedDict => { | 
 |                     mem::decompress_need_dict(self.inner.decompressor().adler32().unwrap_or(0)) | 
 |                 } | 
 |             }, | 
 |             Err(status) => match status { | 
 |                 MZError::Buf => Ok(Status::BufError), | 
 |                 _ => mem::decompress_failed(ErrorMessage), | 
 |             }, | 
 |         } | 
 |     } | 
 |  | 
 |     fn reset(&mut self, zlib_header: bool) { | 
 |         self.inner.reset(format_from_bool(zlib_header)); | 
 |         self.total_in = 0; | 
 |         self.total_out = 0; | 
 |     } | 
 | } | 
 |  | 
 | impl Backend for Inflate { | 
 |     #[inline] | 
 |     fn total_in(&self) -> u64 { | 
 |         self.total_in | 
 |     } | 
 |  | 
 |     #[inline] | 
 |     fn total_out(&self) -> u64 { | 
 |         self.total_out | 
 |     } | 
 | } | 
 |  | 
 | pub struct Deflate { | 
 |     inner: Box<CompressorOxide>, | 
 |     total_in: u64, | 
 |     total_out: u64, | 
 | } | 
 |  | 
 | impl fmt::Debug for Deflate { | 
 |     fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { | 
 |         write!( | 
 |             f, | 
 |             "miniz_oxide deflate internal state. total_in: {}, total_out: {}", | 
 |             self.total_in, self.total_out, | 
 |         ) | 
 |     } | 
 | } | 
 |  | 
 | impl DeflateBackend for Deflate { | 
 |     fn make(level: Compression, zlib_header: bool, _window_bits: u8) -> Self { | 
 |         // Check in case the integer value changes at some point. | 
 |         debug_assert!(level.level() <= 10); | 
 |  | 
 |         let mut inner: Box<CompressorOxide> = Box::default(); | 
 |         let format = format_from_bool(zlib_header); | 
 |         inner.set_format_and_level(format, level.level().try_into().unwrap_or(1)); | 
 |  | 
 |         Deflate { | 
 |             inner, | 
 |             total_in: 0, | 
 |             total_out: 0, | 
 |         } | 
 |     } | 
 |  | 
 |     fn compress( | 
 |         &mut self, | 
 |         input: &[u8], | 
 |         output: &mut [u8], | 
 |         flush: FlushCompress, | 
 |     ) -> Result<Status, CompressError> { | 
 |         let flush = MZFlush::new(flush as i32).unwrap(); | 
 |         let res = deflate::stream::deflate(&mut self.inner, input, output, flush); | 
 |         self.total_in += res.bytes_consumed as u64; | 
 |         self.total_out += res.bytes_written as u64; | 
 |  | 
 |         match res.status { | 
 |             Ok(status) => match status { | 
 |                 MZStatus::Ok => Ok(Status::Ok), | 
 |                 MZStatus::StreamEnd => Ok(Status::StreamEnd), | 
 |                 MZStatus::NeedDict => mem::compress_failed(ErrorMessage), | 
 |             }, | 
 |             Err(status) => match status { | 
 |                 MZError::Buf => Ok(Status::BufError), | 
 |                 _ => mem::compress_failed(ErrorMessage), | 
 |             }, | 
 |         } | 
 |     } | 
 |  | 
 |     fn reset(&mut self) { | 
 |         self.total_in = 0; | 
 |         self.total_out = 0; | 
 |         self.inner.reset(); | 
 |     } | 
 | } | 
 |  | 
 | impl Backend for Deflate { | 
 |     #[inline] | 
 |     fn total_in(&self) -> u64 { | 
 |         self.total_in | 
 |     } | 
 |  | 
 |     #[inline] | 
 |     fn total_out(&self) -> u64 { | 
 |         self.total_out | 
 |     } | 
 | } |