miniz_oxide/
lib.rs

1//! A pure rust replacement for the [miniz](https://github.com/richgel999/miniz)
2//! DEFLATE/zlib encoder/decoder.
3//! Used a rust back-end for the
4//! [flate2](https://github.com/alexcrichton/flate2-rs) crate.
5//!
6#![cfg_attr(
7    feature = "with-alloc",
8    doc = r##"
9# Usage
10## Simple compression/decompression:
11``` rust
12
13use miniz_oxide::inflate::decompress_to_vec;
14use miniz_oxide::deflate::compress_to_vec;
15
16fn roundtrip(data: &[u8]) {
17    let compressed = compress_to_vec(data, 6);
18    let decompressed = decompress_to_vec(compressed.as_slice()).expect("Failed to decompress!");
19#   let _ = decompressed;
20}
21
22# roundtrip(b"Test_data test data lalalal blabla");
23"##
24)]
25#![forbid(unsafe_code)]
26#![cfg_attr(all(not(feature = "std"), not(feature = "serde")), no_std)]
27
28#[cfg(feature = "with-alloc")]
29extern crate alloc;
30
31#[cfg(feature = "with-alloc")]
32pub mod deflate;
33pub mod inflate;
34#[cfg(feature = "serde")]
35pub mod serde;
36mod shared;
37
38pub use crate::shared::update_adler32 as mz_adler32_oxide;
39pub use crate::shared::{MZ_ADLER32_INIT, MZ_DEFAULT_WINDOW_BITS};
40
41/// A list of flush types.
42///
43/// See <http://www.bolet.org/~pornin/deflate-flush.html> for more in-depth info.
44#[repr(i32)]
45#[derive(Copy, Clone, PartialEq, Eq)]
46#[cfg_attr(not(feature = "rustc-dep-of-std"), derive(Hash, Debug))]
47pub enum MZFlush {
48    /// Don't force any flushing.
49    /// Used when more input data is expected.
50    None = 0,
51    /// Zlib partial flush.
52    /// Currently treated as [`Sync`].
53    Partial = 1,
54    /// Finish compressing the currently buffered data, and output an empty raw block.
55    /// Has no use in decompression.
56    Sync = 2,
57    /// Same as [`Sync`], but resets the compression dictionary so that further compressed
58    /// data does not depend on data compressed before the flush.
59    ///
60    /// Has no use in decompression, and is an error to supply in that case.
61    Full = 3,
62    /// Attempt to flush the remaining data and end the stream.
63    Finish = 4,
64    /// Not implemented.
65    Block = 5,
66}
67
68impl MZFlush {
69    /// Create an MZFlush value from an integer value.
70    ///
71    /// Returns `MZError::Param` on invalid values.
72    pub fn new(flush: i32) -> Result<Self, MZError> {
73        match flush {
74            0 => Ok(MZFlush::None),
75            1 | 2 => Ok(MZFlush::Sync),
76            3 => Ok(MZFlush::Full),
77            4 => Ok(MZFlush::Finish),
78            _ => Err(MZError::Param),
79        }
80    }
81}
82
83/// A list of miniz successful status codes.
84///
85/// These are emitted as the [`Ok`] side of a [`MZResult`] in the [`StreamResult`] returned from
86/// [`deflate::stream::deflate()`] or [`inflate::stream::inflate()`].
87#[repr(i32)]
88#[derive(Copy, Clone, PartialEq, Eq)]
89#[cfg_attr(not(feature = "rustc-dep-of-std"), derive(Hash, Debug))]
90pub enum MZStatus {
91    /// Operation succeeded.
92    ///
93    /// Some data was decompressed or compressed; see the byte counters in the [`StreamResult`] for
94    /// details.
95    Ok = 0,
96
97    /// Operation succeeded and end of deflate stream was found.
98    ///
99    /// X-ref [`TINFLStatus::Done`][inflate::TINFLStatus::Done] or
100    /// [`TDEFLStatus::Done`][deflate::core::TDEFLStatus::Done] for `inflate` or `deflate`
101    /// respectively.
102    StreamEnd = 1,
103
104    /// Unused
105    NeedDict = 2,
106}
107
108/// A list of miniz failed status codes.
109///
110/// These are emitted as the [`Err`] side of a [`MZResult`] in the [`StreamResult`] returned from
111/// [`deflate::stream::deflate()`] or [`inflate::stream::inflate()`].
112#[repr(i32)]
113#[cfg_attr(not(feature = "rustc-dep-of-std"), derive(Hash, Debug))]
114#[derive(Copy, Clone, PartialEq, Eq)]
115pub enum MZError {
116    /// Unused
117    ErrNo = -1,
118
119    /// General stream error.
120    ///
121    /// See [`inflate::stream::inflate()`] docs for details of how it can occur there.
122    ///
123    /// See [`deflate::stream::deflate()`] docs for how it can in principle occur there, though it's
124    /// believed impossible in practice.
125    Stream = -2,
126
127    /// Error in inflation; see [`inflate::stream::inflate()`] for details.
128    ///
129    /// Not returned from [`deflate::stream::deflate()`].
130    Data = -3,
131
132    /// Unused
133    Mem = -4,
134
135    /// Buffer-related error.
136    ///
137    /// See the docs of [`deflate::stream::deflate()`] or [`inflate::stream::inflate()`] for details
138    /// of when it would trigger in the one you're using.
139    Buf = -5,
140
141    /// Unused
142    Version = -6,
143
144    /// Bad parameters.
145    ///
146    /// This can be returned from [`deflate::stream::deflate()`] in the case of bad parameters.  See
147    /// [`TDEFLStatus::BadParam`][deflate::core::TDEFLStatus::BadParam].
148    Param = -10_000,
149}
150
151/// How compressed data is wrapped.
152#[derive(Copy, Clone, PartialEq, Eq)]
153#[cfg_attr(not(feature = "rustc-dep-of-std"), derive(Hash, Debug))]
154#[non_exhaustive]
155pub enum DataFormat {
156    /// Wrapped using the [zlib](http://www.zlib.org/rfc-zlib.html) format.
157    Zlib,
158    /// Zlib wrapped but ignore and don't compute the adler32 checksum.
159    /// Currently only used for inflate, behaves the same as Zlib for compression.
160    ZLibIgnoreChecksum,
161    /// Raw DEFLATE.
162    Raw,
163}
164
165#[cfg(not(feature = "rustc-dep-of-std"))]
166impl DataFormat {
167    pub fn from_window_bits(window_bits: i32) -> DataFormat {
168        if window_bits > 0 {
169            DataFormat::Zlib
170        } else {
171            DataFormat::Raw
172        }
173    }
174
175    pub fn to_window_bits(self) -> i32 {
176        match self {
177            DataFormat::Zlib | DataFormat::ZLibIgnoreChecksum => shared::MZ_DEFAULT_WINDOW_BITS,
178            DataFormat::Raw => -shared::MZ_DEFAULT_WINDOW_BITS,
179        }
180    }
181}
182
183/// `Result` alias for all miniz status codes both successful and failed.
184pub type MZResult = Result<MZStatus, MZError>;
185
186/// A structure containing the result of a call to the inflate or deflate streaming functions.
187#[cfg(not(feature = "rustc-dep-of-std"))]
188#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
189pub struct StreamResult {
190    /// The number of bytes consumed from the input slice.
191    pub bytes_consumed: usize,
192    /// The number of bytes written to the output slice.
193    pub bytes_written: usize,
194    /// The return status of the call.
195    pub status: MZResult,
196}
197
198#[cfg(not(feature = "rustc-dep-of-std"))]
199impl StreamResult {
200    #[inline]
201    pub const fn error(error: MZError) -> StreamResult {
202        StreamResult {
203            bytes_consumed: 0,
204            bytes_written: 0,
205            status: Err(error),
206        }
207    }
208}
209
210#[cfg(not(feature = "rustc-dep-of-std"))]
211impl core::convert::From<StreamResult> for MZResult {
212    fn from(res: StreamResult) -> Self {
213        res.status
214    }
215}
216
217#[cfg(not(feature = "rustc-dep-of-std"))]
218impl core::convert::From<&StreamResult> for MZResult {
219    fn from(res: &StreamResult) -> Self {
220        res.status
221    }
222}