flate2/ffi/
rust.rs
1use std::convert::TryInto;
4use std::fmt;
5
6use miniz_oxide::deflate::core::CompressorOxide;
7use miniz_oxide::inflate::stream::InflateState;
8pub use miniz_oxide::*;
9
10pub const MZ_NO_FLUSH: isize = MZFlush::None as isize;
11pub const MZ_PARTIAL_FLUSH: isize = MZFlush::Partial as isize;
12pub const MZ_SYNC_FLUSH: isize = MZFlush::Sync as isize;
13pub const MZ_FULL_FLUSH: isize = MZFlush::Full as isize;
14pub const MZ_FINISH: isize = MZFlush::Finish as isize;
15
16use super::*;
17use crate::mem;
18
19fn format_from_bool(zlib_header: bool) -> DataFormat {
20 if zlib_header {
21 DataFormat::Zlib
22 } else {
23 DataFormat::Raw
24 }
25}
26
27pub struct Inflate {
28 inner: Box<InflateState>,
29 total_in: u64,
30 total_out: u64,
31}
32
33impl fmt::Debug for Inflate {
34 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
35 write!(
36 f,
37 "miniz_oxide inflate internal state. total_in: {}, total_out: {}",
38 self.total_in, self.total_out,
39 )
40 }
41}
42
43impl InflateBackend for Inflate {
44 fn make(zlib_header: bool, window_bits: u8) -> Self {
45 assert!(
46 window_bits > 8 && window_bits < 16,
47 "window_bits must be within 9 ..= 15"
48 );
49
50 let format = format_from_bool(zlib_header);
51
52 Inflate {
53 inner: InflateState::new_boxed(format),
54 total_in: 0,
55 total_out: 0,
56 }
57 }
58
59 fn decompress(
60 &mut self,
61 input: &[u8],
62 output: &mut [u8],
63 flush: FlushDecompress,
64 ) -> Result<Status, DecompressError> {
65 let flush = MZFlush::new(flush as i32).unwrap();
66
67 let res = inflate::stream::inflate(&mut self.inner, input, output, flush);
68 self.total_in += res.bytes_consumed as u64;
69 self.total_out += res.bytes_written as u64;
70
71 match res.status {
72 Ok(status) => match status {
73 MZStatus::Ok => Ok(Status::Ok),
74 MZStatus::StreamEnd => Ok(Status::StreamEnd),
75 MZStatus::NeedDict => {
76 mem::decompress_need_dict(self.inner.decompressor().adler32().unwrap_or(0))
77 }
78 },
79 Err(status) => match status {
80 MZError::Buf => Ok(Status::BufError),
81 _ => mem::decompress_failed(),
82 },
83 }
84 }
85
86 fn reset(&mut self, zlib_header: bool) {
87 self.inner.reset(format_from_bool(zlib_header));
88 self.total_in = 0;
89 self.total_out = 0;
90 }
91}
92
93impl Backend for Inflate {
94 #[inline]
95 fn total_in(&self) -> u64 {
96 self.total_in
97 }
98
99 #[inline]
100 fn total_out(&self) -> u64 {
101 self.total_out
102 }
103}
104
105pub struct Deflate {
106 inner: Box<CompressorOxide>,
107 total_in: u64,
108 total_out: u64,
109}
110
111impl fmt::Debug for Deflate {
112 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
113 write!(
114 f,
115 "miniz_oxide deflate internal state. total_in: {}, total_out: {}",
116 self.total_in, self.total_out,
117 )
118 }
119}
120
121impl DeflateBackend for Deflate {
122 fn make(level: Compression, zlib_header: bool, window_bits: u8) -> Self {
123 assert!(
124 window_bits > 8 && window_bits < 16,
125 "window_bits must be within 9 ..= 15"
126 );
127
128 debug_assert!(level.level() <= 10);
130
131 let mut inner: Box<CompressorOxide> = Box::default();
132 let format = format_from_bool(zlib_header);
133 inner.set_format_and_level(format, level.level().try_into().unwrap_or(1));
134
135 Deflate {
136 inner,
137 total_in: 0,
138 total_out: 0,
139 }
140 }
141
142 fn compress(
143 &mut self,
144 input: &[u8],
145 output: &mut [u8],
146 flush: FlushCompress,
147 ) -> Result<Status, CompressError> {
148 let flush = MZFlush::new(flush as i32).unwrap();
149 let res = deflate::stream::deflate(&mut self.inner, input, output, flush);
150 self.total_in += res.bytes_consumed as u64;
151 self.total_out += res.bytes_written as u64;
152
153 match res.status {
154 Ok(status) => match status {
155 MZStatus::Ok => Ok(Status::Ok),
156 MZStatus::StreamEnd => Ok(Status::StreamEnd),
157 MZStatus::NeedDict => Err(CompressError(())),
158 },
159 Err(status) => match status {
160 MZError::Buf => Ok(Status::BufError),
161 _ => Err(CompressError(())),
162 },
163 }
164 }
165
166 fn reset(&mut self) {
167 self.total_in = 0;
168 self.total_out = 0;
169 self.inner.reset();
170 }
171}
172
173impl Backend for Deflate {
174 #[inline]
175 fn total_in(&self) -> u64 {
176 self.total_in
177 }
178
179 #[inline]
180 fn total_out(&self) -> u64 {
181 self.total_out
182 }
183}