Coverage Report

Created: 2025-07-23 07:29

/rust/registry/src/index.crates.io-6f17d22bba15001f/flate2-1.0.28/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(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
13.3k
fn format_from_bool(zlib_header: bool) -> DataFormat {
30
13.3k
    if zlib_header {
31
0
        DataFormat::Zlib
32
    } else {
33
13.3k
        DataFormat::Raw
34
    }
35
13.3k
}
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 InflateBackend for Inflate {
54
13.3k
    fn make(zlib_header: bool, _window_bits: u8) -> Self {
55
13.3k
        let format = format_from_bool(zlib_header);
56
13.3k
57
13.3k
        Inflate {
58
13.3k
            inner: InflateState::new_boxed(format),
59
13.3k
            total_in: 0,
60
13.3k
            total_out: 0,
61
13.3k
        }
62
13.3k
    }
63
64
194k
    fn decompress(
65
194k
        &mut self,
66
194k
        input: &[u8],
67
194k
        output: &mut [u8],
68
194k
        flush: FlushDecompress,
69
194k
    ) -> Result<Status, DecompressError> {
70
194k
        let flush = MZFlush::new(flush as i32).unwrap();
71
194k
72
194k
        let res = inflate::stream::inflate(&mut self.inner, input, output, flush);
73
194k
        self.total_in += res.bytes_consumed as u64;
74
194k
        self.total_out += res.bytes_written as u64;
75
194k
76
194k
        match res.status {
77
191k
            Ok(status) => match status {
78
183k
                MZStatus::Ok => Ok(Status::Ok),
79
7.65k
                MZStatus::StreamEnd => Ok(Status::StreamEnd),
80
                MZStatus::NeedDict => {
81
0
                    mem::decompress_need_dict(self.inner.decompressor().adler32().unwrap_or(0))
82
                }
83
            },
84
3.41k
            Err(status) => match status {
85
0
                MZError::Buf => Ok(Status::BufError),
86
3.41k
                _ => mem::decompress_failed(ErrorMessage),
87
            },
88
        }
89
194k
    }
90
91
0
    fn reset(&mut self, zlib_header: bool) {
92
0
        self.inner.reset(format_from_bool(zlib_header));
93
0
        self.total_in = 0;
94
0
        self.total_out = 0;
95
0
    }
96
}
97
98
impl Backend for Inflate {
99
    #[inline]
100
388k
    fn total_in(&self) -> u64 {
101
388k
        self.total_in
102
388k
    }
103
104
    #[inline]
105
388k
    fn total_out(&self) -> u64 {
106
388k
        self.total_out
107
388k
    }
108
}
109
110
pub struct Deflate {
111
    inner: Box<CompressorOxide>,
112
    total_in: u64,
113
    total_out: u64,
114
}
115
116
impl fmt::Debug for Deflate {
117
0
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
118
0
        write!(
119
0
            f,
120
0
            "miniz_oxide deflate internal state. total_in: {}, total_out: {}",
121
0
            self.total_in, self.total_out,
122
0
        )
123
0
    }
124
}
125
126
impl DeflateBackend for Deflate {
127
0
    fn make(level: Compression, zlib_header: bool, _window_bits: u8) -> Self {
128
0
        // Check in case the integer value changes at some point.
129
0
        debug_assert!(level.level() <= 10);
130
131
0
        let mut inner: Box<CompressorOxide> = Box::default();
132
0
        let format = format_from_bool(zlib_header);
133
0
        inner.set_format_and_level(format, level.level().try_into().unwrap_or(1));
134
0
135
0
        Deflate {
136
0
            inner,
137
0
            total_in: 0,
138
0
            total_out: 0,
139
0
        }
140
0
    }
141
142
0
    fn compress(
143
0
        &mut self,
144
0
        input: &[u8],
145
0
        output: &mut [u8],
146
0
        flush: FlushCompress,
147
0
    ) -> Result<Status, CompressError> {
148
0
        let flush = MZFlush::new(flush as i32).unwrap();
149
0
        let res = deflate::stream::deflate(&mut self.inner, input, output, flush);
150
0
        self.total_in += res.bytes_consumed as u64;
151
0
        self.total_out += res.bytes_written as u64;
152
0
153
0
        match res.status {
154
0
            Ok(status) => match status {
155
0
                MZStatus::Ok => Ok(Status::Ok),
156
0
                MZStatus::StreamEnd => Ok(Status::StreamEnd),
157
0
                MZStatus::NeedDict => mem::compress_failed(ErrorMessage),
158
            },
159
0
            Err(status) => match status {
160
0
                MZError::Buf => Ok(Status::BufError),
161
0
                _ => mem::compress_failed(ErrorMessage),
162
            },
163
        }
164
0
    }
165
166
0
    fn reset(&mut self) {
167
0
        self.total_in = 0;
168
0
        self.total_out = 0;
169
0
        self.inner.reset();
170
0
    }
171
}
172
173
impl Backend for Deflate {
174
    #[inline]
175
0
    fn total_in(&self) -> u64 {
176
0
        self.total_in
177
0
    }
178
179
    #[inline]
180
0
    fn total_out(&self) -> u64 {
181
0
        self.total_out
182
0
    }
183
}