#![doc = core::include_str!("../README.md")]
#![cfg_attr(not(any(test, feature = "rust-allocator")), no_std)]
#[cfg(any(feature = "rust-allocator", feature = "c-allocator"))]
extern crate alloc;
mod adler32;
pub mod allocate;
pub mod c_api;
mod cpu_features;
pub mod crc32;
pub mod deflate;
pub mod inflate;
pub mod read_buf;
pub use adler32::{adler32, adler32_combine};
pub use crc32::{crc32, crc32_combine};
#[macro_export]
macro_rules! trace {
($($arg:tt)*) => {
#[cfg(feature = "ZLIB_DEBUG")]
{
eprint!($($arg)*)
}
};
}
#[allow(unused)]
pub(crate) const ENOUGH: usize = ENOUGH_LENS + ENOUGH_DISTS;
pub(crate) const ENOUGH_LENS: usize = 1332;
pub(crate) const ENOUGH_DISTS: usize = 592;
pub(crate) const ADLER32_INITIAL_VALUE: usize = 1;
pub(crate) const CRC32_INITIAL_VALUE: u32 = 0;
pub const MIN_WBITS: i32 = 8; pub const MAX_WBITS: i32 = 15; pub(crate) const DEF_WBITS: i32 = MAX_WBITS;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum DeflateFlush {
#[default]
NoFlush = 0,
PartialFlush = 1,
SyncFlush = 2,
FullFlush = 3,
Finish = 4,
Block = 5,
}
impl TryFrom<i32> for DeflateFlush {
type Error = ();
fn try_from(value: i32) -> Result<Self, Self::Error> {
match value {
0 => Ok(Self::NoFlush),
1 => Ok(Self::PartialFlush),
2 => Ok(Self::SyncFlush),
3 => Ok(Self::FullFlush),
4 => Ok(Self::Finish),
5 => Ok(Self::Block),
_ => Err(()),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum InflateFlush {
#[default]
NoFlush = 0,
SyncFlush = 2,
Finish = 4,
Block = 5,
Trees = 6,
}
impl TryFrom<i32> for InflateFlush {
type Error = ();
fn try_from(value: i32) -> Result<Self, Self::Error> {
match value {
0 => Ok(Self::NoFlush),
2 => Ok(Self::SyncFlush),
4 => Ok(Self::Finish),
5 => Ok(Self::Block),
6 => Ok(Self::Trees),
_ => Err(()),
}
}
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
pub(crate) struct Code {
pub op: u8,
pub bits: u8,
pub val: u16,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[repr(i32)]
pub enum ReturnCode {
Ok = 0,
StreamEnd = 1,
NeedDict = 2,
ErrNo = -1,
StreamError = -2,
DataError = -3,
MemError = -4,
BufError = -5,
VersionError = -6,
}
impl From<i32> for ReturnCode {
fn from(value: i32) -> Self {
match Self::try_from_c_int(value) {
Some(value) => value,
None => panic!("invalid return code {value}"),
}
}
}
impl ReturnCode {
const fn error_message_str(self) -> &'static str {
match self {
ReturnCode::Ok => "\0",
ReturnCode::StreamEnd => "stream end\0",
ReturnCode::NeedDict => "need dictionary\0",
ReturnCode::ErrNo => "file error\0",
ReturnCode::StreamError => "stream error\0",
ReturnCode::DataError => "data error\0",
ReturnCode::MemError => "insufficient memory\0",
ReturnCode::BufError => "buffer error\0",
ReturnCode::VersionError => "incompatible version\0",
}
}
pub const fn error_message(self) -> *const core::ffi::c_char {
let msg = self.error_message_str();
msg.as_ptr().cast::<core::ffi::c_char>()
}
pub const fn try_from_c_int(err: core::ffi::c_int) -> Option<Self> {
match err {
0 => Some(Self::Ok),
1 => Some(Self::StreamEnd),
2 => Some(Self::NeedDict),
-1 => Some(Self::ErrNo),
-2 => Some(Self::StreamError),
-3 => Some(Self::DataError),
-4 => Some(Self::MemError),
-5 => Some(Self::BufError),
-6 => Some(Self::VersionError),
_ => None,
}
}
}