Coverage Report

Created: 2025-07-18 08:00

/rust/registry/src/index.crates.io-6f17d22bba15001f/flate2-1.1.2/src/ffi/rust.rs
Line
Count
Source (jump to first uncovered line)
1
//! Implementation for `miniz_oxide` rust backend.
2
3
use std::convert::TryInto;
4
use std::fmt;
5
6
use miniz_oxide::deflate::core::CompressorOxide;
7
use miniz_oxide::inflate::stream::InflateState;
8
pub use miniz_oxide::*;
9
10
pub const MZ_NO_FLUSH: isize = MZFlush::None as isize;
11
pub const MZ_PARTIAL_FLUSH: isize = MZFlush::Partial as isize;
12
pub const MZ_SYNC_FLUSH: isize = MZFlush::Sync as isize;
13
pub const MZ_FULL_FLUSH: isize = MZFlush::Full as isize;
14
pub const MZ_FINISH: isize = MZFlush::Finish as isize;
15
16
use super::*;
17
use crate::mem;
18
19
// miniz_oxide doesn't provide any error messages (yet?)
20
#[derive(Clone, Default)]
21
pub struct ErrorMessage;
22
23
impl ErrorMessage {
24
0
    pub fn get(&self) -> Option<&str> {
25
0
        None
26
0
    }
27
}
28
29
0
fn format_from_bool(zlib_header: bool) -> DataFormat {
30
0
    if zlib_header {
31
0
        DataFormat::Zlib
32
    } else {
33
0
        DataFormat::Raw
34
    }
35
0
}
36
37
pub struct Inflate {
38
    inner: Box<InflateState>,
39
    total_in: u64,
40
    total_out: u64,
41
}
42
43
impl fmt::Debug for Inflate {
44
0
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
45
0
        write!(
46
0
            f,
47
0
            "miniz_oxide inflate internal state. total_in: {}, total_out: {}",
48
0
            self.total_in, self.total_out,
49
0
        )
50
0
    }
51
}
52
53
impl From<FlushDecompress> for MZFlush {
54
0
    fn from(value: FlushDecompress) -> Self {
55
0
        match value {
56
0
            FlushDecompress::None => Self::None,
57
0
            FlushDecompress::Sync => Self::Sync,
58
0
            FlushDecompress::Finish => Self::Finish,
59
        }
60
0
    }
61
}
62
63
impl InflateBackend for Inflate {
64
0
    fn make(zlib_header: bool, _window_bits: u8) -> Self {
65
0
        let format = format_from_bool(zlib_header);
66
0
67
0
        Inflate {
68
0
            inner: InflateState::new_boxed(format),
69
0
            total_in: 0,
70
0
            total_out: 0,
71
0
        }
72
0
    }
73
74
0
    fn decompress(
75
0
        &mut self,
76
0
        input: &[u8],
77
0
        output: &mut [u8],
78
0
        flush: FlushDecompress,
79
0
    ) -> Result<Status, DecompressError> {
80
0
        let mz_flush = flush.into();
81
0
        let res = inflate::stream::inflate(&mut self.inner, input, output, mz_flush);
82
0
        self.total_in += res.bytes_consumed as u64;
83
0
        self.total_out += res.bytes_written as u64;
84
0
85
0
        match res.status {
86
0
            Ok(status) => match status {
87
0
                MZStatus::Ok => Ok(Status::Ok),
88
0
                MZStatus::StreamEnd => Ok(Status::StreamEnd),
89
                MZStatus::NeedDict => {
90
0
                    mem::decompress_need_dict(self.inner.decompressor().adler32().unwrap_or(0))
91
                }
92
            },
93
0
            Err(status) => match status {
94
0
                MZError::Buf => Ok(Status::BufError),
95
0
                _ => mem::decompress_failed(ErrorMessage),
96
            },
97
        }
98
0
    }
99
100
0
    fn reset(&mut self, zlib_header: bool) {
101
0
        self.inner.reset(format_from_bool(zlib_header));
102
0
        self.total_in = 0;
103
0
        self.total_out = 0;
104
0
    }
105
}
106
107
impl Backend for Inflate {
108
    #[inline]
109
0
    fn total_in(&self) -> u64 {
110
0
        self.total_in
111
0
    }
112
113
    #[inline]
114
0
    fn total_out(&self) -> u64 {
115
0
        self.total_out
116
0
    }
117
}
118
119
pub struct Deflate {
120
    inner: Box<CompressorOxide>,
121
    total_in: u64,
122
    total_out: u64,
123
}
124
125
impl fmt::Debug for Deflate {
126
0
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
127
0
        write!(
128
0
            f,
129
0
            "miniz_oxide deflate internal state. total_in: {}, total_out: {}",
130
0
            self.total_in, self.total_out,
131
0
        )
132
0
    }
133
}
134
135
impl From<FlushCompress> for MZFlush {
136
0
    fn from(value: FlushCompress) -> Self {
137
0
        match value {
138
0
            FlushCompress::None => Self::None,
139
0
            FlushCompress::Partial | FlushCompress::Sync => Self::Sync,
140
0
            FlushCompress::Full => Self::Full,
141
0
            FlushCompress::Finish => Self::Finish,
142
        }
143
0
    }
144
}
145
146
impl DeflateBackend for Deflate {
147
0
    fn make(level: Compression, zlib_header: bool, _window_bits: u8) -> Self {
148
0
        // Check in case the integer value changes at some point.
149
0
        debug_assert!(level.level() <= 10);
150
151
0
        let mut inner: Box<CompressorOxide> = Box::default();
152
0
        let format = format_from_bool(zlib_header);
153
0
        inner.set_format_and_level(format, level.level().try_into().unwrap_or(1));
154
0
155
0
        Deflate {
156
0
            inner,
157
0
            total_in: 0,
158
0
            total_out: 0,
159
0
        }
160
0
    }
161
162
0
    fn compress(
163
0
        &mut self,
164
0
        input: &[u8],
165
0
        output: &mut [u8],
166
0
        flush: FlushCompress,
167
0
    ) -> Result<Status, CompressError> {
168
0
        let mz_flush = flush.into();
169
0
        let res = deflate::stream::deflate(&mut self.inner, input, output, mz_flush);
170
0
        self.total_in += res.bytes_consumed as u64;
171
0
        self.total_out += res.bytes_written as u64;
172
0
173
0
        match res.status {
174
0
            Ok(status) => match status {
175
0
                MZStatus::Ok => Ok(Status::Ok),
176
0
                MZStatus::StreamEnd => Ok(Status::StreamEnd),
177
0
                MZStatus::NeedDict => mem::compress_failed(ErrorMessage),
178
            },
179
0
            Err(status) => match status {
180
0
                MZError::Buf => Ok(Status::BufError),
181
0
                _ => mem::compress_failed(ErrorMessage),
182
            },
183
        }
184
0
    }
185
186
0
    fn reset(&mut self) {
187
0
        self.total_in = 0;
188
0
        self.total_out = 0;
189
0
        self.inner.reset();
190
0
    }
191
}
192
193
impl Backend for Deflate {
194
    #[inline]
195
0
    fn total_in(&self) -> u64 {
196
0
        self.total_in
197
0
    }
198
199
    #[inline]
200
0
    fn total_out(&self) -> u64 {
201
0
        self.total_out
202
0
    }
203
}