//! A pure rust replacement for the [miniz](https://github.com/richgel999/miniz) //! DEFLATE/zlib encoder/decoder. //! The plan for this crate is to be used as a back-end for the //! [flate2](https://github.com/alexcrichton/flate2-rs) crate and eventually remove the //! need to depend on a C library. //! //! # Usage //! ## Simple compression/decompression: //! ``` rust //! //! use miniz_oxide::inflate::decompress_to_vec; //! use miniz_oxide::deflate::compress_to_vec; //! //! fn roundtrip(data: &[u8]) { //! let compressed = compress_to_vec(data, 6); //! let decompressed = decompress_to_vec(compressed.as_slice()).expect("Failed to decompress!"); //! # let _ = decompressed; //! } //! //! # roundtrip(b"Test_data test data lalalal blabla"); //! //! ``` #![forbid(unsafe_code)] #![no_std] extern crate alloc; pub mod deflate; pub mod inflate; mod shared; pub use crate::shared::update_adler32 as mz_adler32_oxide; pub use crate::shared::{MZ_ADLER32_INIT, MZ_DEFAULT_WINDOW_BITS}; /// A list of flush types. /// /// See for more in-depth info. #[repr(i32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum MZFlush { /// Don't force any flushing. /// Used when more input data is expected. None = 0, /// Zlib partial flush. /// Currently treated as [`Sync`]. Partial = 1, /// Finish compressing the currently buffered data, and output an empty raw block. /// Has no use in decompression. Sync = 2, /// Same as [`Sync`], but resets the compression dictionary so that further compressed /// data does not depend on data compressed before the flush. /// /// Has no use in decompression, and is an error to supply in that case. Full = 3, /// Attempt to flush the remaining data and end the stream. Finish = 4, /// Not implemented. Block = 5, } impl MZFlush { /// Create an MZFlush value from an integer value. /// /// Returns `MZError::Param` on invalid values. pub fn new(flush: i32) -> Result { match flush { 0 => Ok(MZFlush::None), 1 | 2 => Ok(MZFlush::Sync), 3 => Ok(MZFlush::Full), 4 => Ok(MZFlush::Finish), _ => Err(MZError::Param), } } } /// A list of miniz successful status codes. /// /// These are emitted as the [`Ok`] side of a [`MZResult`] in the [`StreamResult`] returned from /// [`deflate::stream::deflate()`] or [`inflate::stream::inflate()`]. #[repr(i32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum MZStatus { /// Operation succeeded. /// /// Some data was decompressed or compressed; see the byte counters in the [`StreamResult`] for /// details. Ok = 0, /// Operation succeeded and end of deflate stream was found. /// /// X-ref [`TINFLStatus::Done`][inflate::TINFLStatus::Done] or /// [`TDEFLStatus::Done`][deflate::core::TDEFLStatus::Done] for `inflate` or `deflate` /// respectively. StreamEnd = 1, /// Unused NeedDict = 2, } /// A list of miniz failed status codes. /// /// These are emitted as the [`Err`] side of a [`MZResult`] in the [`StreamResult`] returned from /// [`deflate::stream::deflate()`] or [`inflate::stream::inflate()`]. #[repr(i32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum MZError { /// Unused ErrNo = -1, /// General stream error. /// /// See [`inflate::stream::inflate()`] docs for details of how it can occur there. /// /// See [`deflate::stream::deflate()`] docs for how it can in principle occur there, though it's /// believed impossible in practice. Stream = -2, /// Error in inflation; see [`inflate::stream::inflate()`] for details. /// /// Not returned from [`deflate::stream::deflate()`]. Data = -3, /// Unused Mem = -4, /// Buffer-related error. /// /// See the docs of [`deflate::stream::deflate()`] or [`inflate::stream::inflate()`] for details /// of when it would trigger in the one you're using. Buf = -5, /// Unused Version = -6, /// Bad parameters. /// /// This can be returned from [`deflate::stream::deflate()`] in the case of bad parameters. See /// [`TDEFLStatus::BadParam`][deflate::core::TDEFLStatus::BadParam]. Param = -10_000, } /// How compressed data is wrapped. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[non_exhaustive] pub enum DataFormat { /// Wrapped using the [zlib](http://www.zlib.org/rfc-zlib.html) format. Zlib, /// Zlib wrapped but ignore and don't compute the adler32 checksum. /// Currently only used for inflate, behaves the same as Zlib for compression. ZLibIgnoreChecksum, /// Raw DEFLATE. Raw, } impl DataFormat { pub(crate) fn from_window_bits(window_bits: i32) -> DataFormat { if window_bits > 0 { DataFormat::Zlib } else { DataFormat::Raw } } pub(crate) fn to_window_bits(self) -> i32 { match self { DataFormat::Zlib | DataFormat::ZLibIgnoreChecksum => shared::MZ_DEFAULT_WINDOW_BITS, DataFormat::Raw => -shared::MZ_DEFAULT_WINDOW_BITS, } } } /// `Result` alias for all miniz status codes both successful and failed. pub type MZResult = Result; /// A structure containg the result of a call to the inflate or deflate streaming functions. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct StreamResult { /// The number of bytes consumed from the input slice. pub bytes_consumed: usize, /// The number of bytes written to the output slice. pub bytes_written: usize, /// The return status of the call. pub status: MZResult, } impl StreamResult { #[inline] pub(crate) const fn error(error: MZError) -> StreamResult { StreamResult { bytes_consumed: 0, bytes_written: 0, status: Err(error), } } } impl core::convert::From for MZResult { fn from(res: StreamResult) -> Self { res.status } } impl core::convert::From<&StreamResult> for MZResult { fn from(res: &StreamResult) -> Self { res.status } }