Skip to content

Commit d34a7b8

Browse files
committed
initial design
1 parent 8ad8fd7 commit d34a7b8

File tree

6 files changed

+190
-29
lines changed

6 files changed

+190
-29
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ libz-sys = { version = "1.1.20", optional = true, default-features = false }
2323
libz-ng-sys = { version = "1.1.16", optional = true }
2424
# this matches the default features, but we don't want to depend on the default features staying the same
2525
libz-rs-sys = { version = "0.5.1", optional = true, default-features = false, features = ["std", "rust-allocator"] }
26+
zlib-rs = { git = "https://github.com/trifectatechfoundation/zlib-rs.git", rev = "84b875fabc615890743a4432f0c75c92b104f064", optional = true, default-features = false, features = ["std", "rust-allocator"] }
2627
cloudflare-zlib-sys = { version = "0.3.6", optional = true }
2728
miniz_oxide = { version = "0.8.5", optional = true, default-features = false, features = ["with-alloc", "simd"] }
2829
crc32fast = "1.2.0"
@@ -43,7 +44,7 @@ zlib = ["any_zlib", "libz-sys"]
4344
zlib-default = ["any_zlib", "libz-sys/default"]
4445
zlib-ng-compat = ["zlib", "libz-sys/zlib-ng"]
4546
zlib-ng = ["any_zlib", "libz-ng-sys"]
46-
zlib-rs = ["any_zlib", "libz-rs-sys"]
47+
zlib-rs = ["any_impl", "dep:zlib-rs", "dep:libz-rs-sys"]
4748
cloudflare_zlib = ["any_zlib", "cloudflare-zlib-sys"]
4849
rust_backend = ["miniz_oxide", "any_impl"]
4950
miniz-sys = ["rust_backend"] # For backwards compatibility

src/ffi/c.rs

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use super::*;
99
use crate::mem;
1010

1111
#[derive(Clone, Default)]
12-
pub struct ErrorMessage(Option<&'static str>);
12+
pub struct ErrorMessage(pub(crate) Option<&'static str>);
1313

1414
impl ErrorMessage {
1515
pub fn get(&self) -> Option<&str> {
@@ -55,34 +55,27 @@ impl Default for StreamWrapper {
5555
// zlib-ng
5656
feature = "zlib-ng",
5757
// libz-sys
58-
all(not(feature = "cloudflare_zlib"), not(feature = "zlib-ng"), not(feature = "zlib-rs"))
58+
all(not(feature = "cloudflare_zlib"), not(feature = "zlib-ng"))
5959
))]
6060
zalloc: allocator::zalloc,
6161
#[cfg(any(
6262
// zlib-ng
6363
feature = "zlib-ng",
6464
// libz-sys
65-
all(not(feature = "cloudflare_zlib"), not(feature = "zlib-ng"), not(feature = "zlib-rs"))
65+
all(not(feature = "cloudflare_zlib"), not(feature = "zlib-ng"))
6666
))]
6767
zfree: allocator::zfree,
6868

6969
#[cfg(
7070
// cloudflare-zlib
71-
all(feature = "cloudflare_zlib", not(feature = "zlib-rs"), not(feature = "zlib-ng")),
71+
all(feature = "cloudflare_zlib", not(feature = "zlib-ng")),
7272
)]
7373
zalloc: Some(allocator::zalloc),
7474
#[cfg(
7575
// cloudflare-zlib
76-
all(feature = "cloudflare_zlib", not(feature = "zlib-rs"), not(feature = "zlib-ng")),
76+
all(feature = "cloudflare_zlib", not(feature = "zlib-ng")),
7777
)]
7878
zfree: Some(allocator::zfree),
79-
80-
// for zlib-rs, it is most efficient to have it provide the allocator.
81-
// The libz-rs-sys dependency is configured to use the rust system allocator
82-
#[cfg(all(feature = "zlib-rs", not(feature = "zlib-ng")))]
83-
zalloc: None,
84-
#[cfg(all(feature = "zlib-rs", not(feature = "zlib-ng")))]
85-
zfree: None,
8679
})),
8780
}
8881
}
@@ -102,9 +95,9 @@ impl Drop for StreamWrapper {
10295
// zlib-ng
10396
feature = "zlib-ng",
10497
// cloudflare-zlib
105-
all(feature = "cloudflare_zlib", not(feature = "zlib-rs"), not(feature = "zlib-ng")),
98+
all(feature = "cloudflare_zlib", not(feature = "zlib-ng")),
10699
// libz-sys
107-
all(not(feature = "cloudflare_zlib"), not(feature = "zlib-ng"), not(feature = "zlib-rs")),
100+
all(not(feature = "cloudflare_zlib"), not(feature = "zlib-ng")),
108101
))]
109102
mod allocator {
110103
use super::*;
@@ -462,18 +455,15 @@ mod c_backend {
462455
#[cfg(feature = "zlib-ng")]
463456
use libz_ng_sys as libz;
464457

465-
#[cfg(all(feature = "zlib-rs", not(feature = "zlib-ng")))]
466-
use libz_rs_sys as libz;
467-
468458
#[cfg(
469459
// cloudflare-zlib
470-
all(feature = "cloudflare_zlib", not(feature = "zlib-rs"), not(feature = "zlib-ng")),
460+
all(feature = "cloudflare_zlib", not(feature = "zlib-ng")),
471461
)]
472462
use cloudflare_zlib_sys as libz;
473463

474464
#[cfg(
475465
// libz-sys
476-
all(not(feature = "cloudflare_zlib"), not(feature = "zlib-ng"), not(feature = "zlib-rs")),
466+
all(not(feature = "cloudflare_zlib"), not(feature = "zlib-ng")),
477467
)]
478468
use libz_sys as libz;
479469

src/ffi/rust.rs renamed to src/ffi/miniz_oxide.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
use std::convert::TryInto;
44
use std::fmt;
55

6-
use miniz_oxide::deflate::core::CompressorOxide;
7-
use miniz_oxide::inflate::stream::InflateState;
8-
pub use miniz_oxide::*;
6+
use ::miniz_oxide::deflate::core::CompressorOxide;
7+
use ::miniz_oxide::inflate::stream::InflateState;
8+
pub use ::miniz_oxide::*;
99

1010
pub const MZ_NO_FLUSH: isize = MZFlush::None as isize;
1111
pub const MZ_PARTIAL_FLUSH: isize = MZFlush::Partial as isize;
@@ -146,7 +146,7 @@ impl From<FlushCompress> for MZFlush {
146146
impl DeflateBackend for Deflate {
147147
fn make(level: Compression, zlib_header: bool, _window_bits: u8) -> Self {
148148
// Check in case the integer value changes at some point.
149-
debug_assert!(level.level() <= 10);
149+
debug_assert!(level.level() <= 9);
150150

151151
let mut inner: Box<CompressorOxide> = Box::default();
152152
let format = format_from_bool(zlib_header);

src/ffi/mod.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,15 @@ mod c;
6565
#[cfg(feature = "any_zlib")]
6666
pub use self::c::*;
6767

68+
#[cfg(all(not(feature = "any_zlib"), feature = "zlib-rs"))]
69+
mod zlib_rs;
70+
#[cfg(all(not(feature = "any_zlib"), feature = "zlib-rs"))]
71+
pub use self::zlib_rs::*;
72+
6873
#[cfg(all(not(feature = "any_zlib"), feature = "miniz_oxide"))]
69-
mod rust;
74+
mod miniz_oxide;
7075
#[cfg(all(not(feature = "any_zlib"), feature = "miniz_oxide"))]
71-
pub use self::rust::*;
76+
pub use self::miniz_oxide::*;
7277

7378
impl std::fmt::Debug for ErrorMessage {
7479
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {

src/ffi/zlib_rs.rs

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
//! Implementation for `miniz_oxide` rust backend.
2+
3+
use std::fmt;
4+
5+
use ::zlib_rs::{Compress, Decompress, DeflateFlush, InflateFlush};
6+
7+
pub const MZ_NO_FLUSH: isize = DeflateFlush::NoFlush as isize;
8+
pub const MZ_PARTIAL_FLUSH: isize = DeflateFlush::PartialFlush as isize;
9+
pub const MZ_SYNC_FLUSH: isize = DeflateFlush::SyncFlush as isize;
10+
pub const MZ_FULL_FLUSH: isize = DeflateFlush::FullFlush as isize;
11+
pub const MZ_FINISH: isize = DeflateFlush::Finish as isize;
12+
13+
pub const MZ_DEFAULT_WINDOW_BITS: core::ffi::c_int = 15;
14+
15+
use super::*;
16+
17+
impl From<::zlib_rs::Status> for crate::mem::Status {
18+
fn from(value: ::zlib_rs::Status) -> Self {
19+
match value {
20+
::zlib_rs::Status::Ok => crate::mem::Status::Ok,
21+
::zlib_rs::Status::BufError => crate::mem::Status::BufError,
22+
::zlib_rs::Status::StreamEnd => crate::mem::Status::StreamEnd,
23+
}
24+
}
25+
}
26+
27+
#[derive(Clone, Default)]
28+
pub struct ErrorMessage(Option<&'static str>);
29+
30+
impl ErrorMessage {
31+
pub fn get(&self) -> Option<&str> {
32+
self.0
33+
}
34+
}
35+
36+
pub struct Inflate {
37+
pub(crate) inner: Decompress,
38+
}
39+
40+
impl fmt::Debug for Inflate {
41+
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
42+
write!(
43+
f,
44+
"miniz_oxide inflate internal state. total_in: {}, total_out: {}",
45+
self.inner.total_in(),
46+
self.inner.total_out(),
47+
)
48+
}
49+
}
50+
51+
impl From<FlushDecompress> for DeflateFlush {
52+
fn from(value: FlushDecompress) -> Self {
53+
match value {
54+
FlushDecompress::None => Self::NoFlush,
55+
FlushDecompress::Sync => Self::SyncFlush,
56+
FlushDecompress::Finish => Self::Finish,
57+
}
58+
}
59+
}
60+
61+
impl InflateBackend for Inflate {
62+
fn make(zlib_header: bool, window_bits: u8) -> Self {
63+
Inflate {
64+
inner: Decompress::new(zlib_header, window_bits),
65+
}
66+
}
67+
68+
fn decompress(
69+
&mut self,
70+
input: &[u8],
71+
output: &mut [u8],
72+
flush: FlushDecompress,
73+
) -> Result<Status, DecompressError> {
74+
let flush = match flush {
75+
FlushDecompress::None => InflateFlush::NoFlush,
76+
FlushDecompress::Sync => InflateFlush::SyncFlush,
77+
FlushDecompress::Finish => InflateFlush::Finish,
78+
};
79+
80+
match self.inner.decompress(input, output, flush) {
81+
Ok(status) => Ok(status.into()),
82+
Err(::zlib_rs::DecompressError::NeedDict { dict_id }) => {
83+
crate::mem::decompress_need_dict(dict_id)
84+
}
85+
Err(e) => crate::mem::decompress_failed(ErrorMessage(Some(e.as_str()))),
86+
}
87+
}
88+
89+
fn reset(&mut self, zlib_header: bool) {
90+
self.inner.reset(zlib_header);
91+
}
92+
}
93+
94+
impl Backend for Inflate {
95+
#[inline]
96+
fn total_in(&self) -> u64 {
97+
self.inner.total_in()
98+
}
99+
100+
#[inline]
101+
fn total_out(&self) -> u64 {
102+
self.inner.total_out()
103+
}
104+
}
105+
106+
pub struct Deflate {
107+
pub(crate) inner: Compress,
108+
}
109+
110+
impl fmt::Debug for Deflate {
111+
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
112+
write!(
113+
f,
114+
"zlib_rs deflate internal state. total_in: {}, total_out: {}",
115+
self.inner.total_in(),
116+
self.inner.total_out(),
117+
)
118+
}
119+
}
120+
121+
impl DeflateBackend for Deflate {
122+
fn make(level: Compression, zlib_header: bool, window_bits: u8) -> Self {
123+
// Check in case the integer value changes at some point.
124+
debug_assert!(level.level() <= 9);
125+
126+
Deflate {
127+
inner: Compress::new(level.level() as i32, zlib_header, window_bits),
128+
}
129+
}
130+
131+
fn compress(
132+
&mut self,
133+
input: &[u8],
134+
output: &mut [u8],
135+
flush: FlushCompress,
136+
) -> Result<Status, CompressError> {
137+
let flush = match flush {
138+
FlushCompress::None => DeflateFlush::NoFlush,
139+
FlushCompress::Partial => DeflateFlush::PartialFlush,
140+
FlushCompress::Sync => DeflateFlush::SyncFlush,
141+
FlushCompress::Full => DeflateFlush::FullFlush,
142+
FlushCompress::Finish => DeflateFlush::Finish,
143+
};
144+
145+
match self.inner.compress(input, output, flush) {
146+
Ok(status) => Ok(status.into()),
147+
Err(e) => crate::mem::compress_failed(ErrorMessage(Some(e.as_str()))),
148+
}
149+
}
150+
151+
fn reset(&mut self) {
152+
self.inner.reset();
153+
}
154+
}
155+
156+
impl Backend for Deflate {
157+
#[inline]
158+
fn total_in(&self) -> u64 {
159+
self.inner.total_in()
160+
}
161+
162+
#[inline]
163+
fn total_out(&self) -> u64 {
164+
self.inner.total_out()
165+
}
166+
}

src/mem.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -662,9 +662,8 @@ mod tests {
662662

663663
let mut d = Decompress::new(false);
664664
// decompressed whole deflate stream
665-
assert!(d
666-
.decompress_vec(&data[10..], &mut decoded, FlushDecompress::Finish)
667-
.is_ok());
665+
d.decompress_vec(&data[10..], &mut decoded, FlushDecompress::Finish)
666+
.unwrap();
668667

669668
// decompress data that has nothing to do with the deflate stream (this
670669
// used to panic)

0 commit comments

Comments
 (0)