Coverage Report

Created: 2025-06-04 06:23

/rust/registry/src/index.crates.io-6f17d22bba15001f/flate2-1.1.1/src/zio.rs
Line
Count
Source (jump to first uncovered line)
1
use std::io;
2
use std::io::prelude::*;
3
use std::mem;
4
5
use crate::{
6
    Compress, CompressError, Decompress, DecompressError, FlushCompress, FlushDecompress, Status,
7
};
8
9
#[derive(Debug)]
10
pub struct Writer<W: Write, D: Ops> {
11
    obj: Option<W>,
12
    pub data: D,
13
    buf: Vec<u8>,
14
}
15
16
pub trait Ops {
17
    type Error: Into<io::Error>;
18
    type Flush: Flush;
19
    fn total_in(&self) -> u64;
20
    fn total_out(&self) -> u64;
21
    fn run(
22
        &mut self,
23
        input: &[u8],
24
        output: &mut [u8],
25
        flush: Self::Flush,
26
    ) -> Result<Status, Self::Error>;
27
    fn run_vec(
28
        &mut self,
29
        input: &[u8],
30
        output: &mut Vec<u8>,
31
        flush: Self::Flush,
32
    ) -> Result<Status, Self::Error>;
33
}
34
35
impl Ops for Compress {
36
    type Error = CompressError;
37
    type Flush = FlushCompress;
38
38.9k
    fn total_in(&self) -> u64 {
39
38.9k
        self.total_in()
40
38.9k
    }
41
77.9k
    fn total_out(&self) -> u64 {
42
77.9k
        self.total_out()
43
77.9k
    }
44
0
    fn run(
45
0
        &mut self,
46
0
        input: &[u8],
47
0
        output: &mut [u8],
48
0
        flush: FlushCompress,
49
0
    ) -> Result<Status, CompressError> {
50
0
        self.compress(input, output, flush)
51
0
    }
52
58.4k
    fn run_vec(
53
58.4k
        &mut self,
54
58.4k
        input: &[u8],
55
58.4k
        output: &mut Vec<u8>,
56
58.4k
        flush: FlushCompress,
57
58.4k
    ) -> Result<Status, CompressError> {
58
58.4k
        self.compress_vec(input, output, flush)
59
58.4k
    }
60
}
61
62
impl Ops for Decompress {
63
    type Error = DecompressError;
64
    type Flush = FlushDecompress;
65
436k
    fn total_in(&self) -> u64 {
66
436k
        self.total_in()
67
436k
    }
68
436k
    fn total_out(&self) -> u64 {
69
436k
        self.total_out()
70
436k
    }
71
218k
    fn run(
72
218k
        &mut self,
73
218k
        input: &[u8],
74
218k
        output: &mut [u8],
75
218k
        flush: FlushDecompress,
76
218k
    ) -> Result<Status, DecompressError> {
77
218k
        self.decompress(input, output, flush)
78
218k
    }
79
0
    fn run_vec(
80
0
        &mut self,
81
0
        input: &[u8],
82
0
        output: &mut Vec<u8>,
83
0
        flush: FlushDecompress,
84
0
    ) -> Result<Status, DecompressError> {
85
0
        self.decompress_vec(input, output, flush)
86
0
    }
87
}
88
89
pub trait Flush {
90
    fn none() -> Self;
91
    fn sync() -> Self;
92
    fn finish() -> Self;
93
}
94
95
impl Flush for FlushCompress {
96
19.4k
    fn none() -> Self {
97
19.4k
        FlushCompress::None
98
19.4k
    }
99
100
0
    fn sync() -> Self {
101
0
        FlushCompress::Sync
102
0
    }
103
104
38.9k
    fn finish() -> Self {
105
38.9k
        FlushCompress::Finish
106
38.9k
    }
107
}
108
109
impl Flush for FlushDecompress {
110
143k
    fn none() -> Self {
111
143k
        FlushDecompress::None
112
143k
    }
113
114
0
    fn sync() -> Self {
115
0
        FlushDecompress::Sync
116
0
    }
117
118
74.3k
    fn finish() -> Self {
119
74.3k
        FlushDecompress::Finish
120
74.3k
    }
121
}
122
123
215k
pub fn read<R, D>(obj: &mut R, data: &mut D, dst: &mut [u8]) -> io::Result<usize>
124
215k
where
125
215k
    R: BufRead,
126
215k
    D: Ops,
127
215k
{
128
    loop {
129
        let (read, consumed, ret, eof);
130
        {
131
218k
            let input = obj.fill_buf()?;
132
218k
            eof = input.is_empty();
133
218k
            let before_out = data.total_out();
134
218k
            let before_in = data.total_in();
135
218k
            let flush = if eof {
136
74.3k
                D::Flush::finish()
137
            } else {
138
143k
                D::Flush::none()
139
            };
140
218k
            ret = data.run(input, dst, flush);
141
218k
            read = (data.total_out() - before_out) as usize;
142
218k
            consumed = (data.total_in() - before_in) as usize;
143
218k
        }
144
218k
        obj.consume(consumed);
145
146
103k
        match ret {
147
103k
            // If we haven't ready any data and we haven't hit EOF yet,
148
103k
            // then we need to keep asking for more data because if we
149
103k
            // return that 0 bytes of data have been read then it will
150
103k
            // be interpreted as EOF.
151
103k
            Ok(Status::Ok | Status::BufError) if read == 0 && !eof && !dst.is_empty() => continue,
152
173k
            Ok(Status::Ok | Status::BufError | Status::StreamEnd) => return Ok(read),
153
154
            Err(..) => {
155
42.4k
                return Err(io::Error::new(
156
42.4k
                    io::ErrorKind::InvalidInput,
157
42.4k
                    "corrupt deflate stream",
158
42.4k
                ))
159
            }
160
        }
161
    }
162
215k
}
flate2::zio::read::<flate2::bufreader::BufReader<zip::read::CryptoReader>, flate2::mem::Decompress>
Line
Count
Source
123
215k
pub fn read<R, D>(obj: &mut R, data: &mut D, dst: &mut [u8]) -> io::Result<usize>
124
215k
where
125
215k
    R: BufRead,
126
215k
    D: Ops,
127
215k
{
128
    loop {
129
        let (read, consumed, ret, eof);
130
        {
131
218k
            let input = obj.fill_buf()?;
132
218k
            eof = input.is_empty();
133
218k
            let before_out = data.total_out();
134
218k
            let before_in = data.total_in();
135
218k
            let flush = if eof {
136
74.3k
                D::Flush::finish()
137
            } else {
138
143k
                D::Flush::none()
139
            };
140
218k
            ret = data.run(input, dst, flush);
141
218k
            read = (data.total_out() - before_out) as usize;
142
218k
            consumed = (data.total_in() - before_in) as usize;
143
218k
        }
144
218k
        obj.consume(consumed);
145
146
103k
        match ret {
147
103k
            // If we haven't ready any data and we haven't hit EOF yet,
148
103k
            // then we need to keep asking for more data because if we
149
103k
            // return that 0 bytes of data have been read then it will
150
103k
            // be interpreted as EOF.
151
103k
            Ok(Status::Ok | Status::BufError) if read == 0 && !eof && !dst.is_empty() => continue,
152
173k
            Ok(Status::Ok | Status::BufError | Status::StreamEnd) => return Ok(read),
153
154
            Err(..) => {
155
42.4k
                return Err(io::Error::new(
156
42.4k
                    io::ErrorKind::InvalidInput,
157
42.4k
                    "corrupt deflate stream",
158
42.4k
                ))
159
            }
160
        }
161
    }
162
215k
}
Unexecuted instantiation: flate2::zio::read::<_, _>
163
164
impl<W: Write, D: Ops> Writer<W, D> {
165
19.4k
    pub fn new(w: W, d: D) -> Writer<W, D> {
166
19.4k
        Writer {
167
19.4k
            obj: Some(w),
168
19.4k
            data: d,
169
19.4k
            buf: Vec::with_capacity(32 * 1024),
170
19.4k
        }
171
19.4k
    }
Unexecuted instantiation: <flate2::zio::Writer<_, _>>::new
<flate2::zio::Writer<zip::write::MaybeEncrypted<std::io::cursor::Cursor<&mut [u8]>>, flate2::mem::Compress>>::new
Line
Count
Source
165
19.4k
    pub fn new(w: W, d: D) -> Writer<W, D> {
166
19.4k
        Writer {
167
19.4k
            obj: Some(w),
168
19.4k
            data: d,
169
19.4k
            buf: Vec::with_capacity(32 * 1024),
170
19.4k
        }
171
19.4k
    }
172
173
19.4k
    pub fn finish(&mut self) -> io::Result<()> {
174
        loop {
175
38.9k
            self.dump()?;
176
177
38.9k
            let before = self.data.total_out();
178
38.9k
            self.data
179
38.9k
                .run_vec(&[], &mut self.buf, Flush::finish())
180
38.9k
                .map_err(Into::into)?;
181
38.9k
            if before == self.data.total_out() {
182
19.4k
                return Ok(());
183
19.4k
            }
184
        }
185
19.4k
    }
Unexecuted instantiation: <flate2::zio::Writer<_, _>>::finish
<flate2::zio::Writer<zip::write::MaybeEncrypted<std::io::cursor::Cursor<&mut [u8]>>, flate2::mem::Compress>>::finish
Line
Count
Source
173
19.4k
    pub fn finish(&mut self) -> io::Result<()> {
174
        loop {
175
38.9k
            self.dump()?;
176
177
38.9k
            let before = self.data.total_out();
178
38.9k
            self.data
179
38.9k
                .run_vec(&[], &mut self.buf, Flush::finish())
180
38.9k
                .map_err(Into::into)?;
181
38.9k
            if before == self.data.total_out() {
182
19.4k
                return Ok(());
183
19.4k
            }
184
        }
185
19.4k
    }
186
187
0
    pub fn replace(&mut self, w: W) -> W {
188
0
        self.buf.truncate(0);
189
0
        mem::replace(self.get_mut(), w)
190
0
    }
191
192
0
    pub fn get_ref(&self) -> &W {
193
0
        self.obj.as_ref().unwrap()
194
0
    }
195
196
0
    pub fn get_mut(&mut self) -> &mut W {
197
0
        self.obj.as_mut().unwrap()
198
0
    }
199
200
    // Note that this should only be called if the outer object is just about
201
    // to be consumed!
202
    //
203
    // (e.g. an implementation of `into_inner`)
204
19.4k
    pub fn take_inner(&mut self) -> W {
205
19.4k
        self.obj.take().unwrap()
206
19.4k
    }
Unexecuted instantiation: <flate2::zio::Writer<_, _>>::take_inner
<flate2::zio::Writer<zip::write::MaybeEncrypted<std::io::cursor::Cursor<&mut [u8]>>, flate2::mem::Compress>>::take_inner
Line
Count
Source
204
19.4k
    pub fn take_inner(&mut self) -> W {
205
19.4k
        self.obj.take().unwrap()
206
19.4k
    }
207
208
0
    pub fn is_present(&self) -> bool {
209
0
        self.obj.is_some()
210
0
    }
211
212
    // Returns total written bytes and status of underlying codec
213
19.4k
    pub(crate) fn write_with_status(&mut self, buf: &[u8]) -> io::Result<(usize, Status)> {
214
        // miniz isn't guaranteed to actually write any of the buffer provided,
215
        // it may be in a flushing mode where it's just giving us data before
216
        // we're actually giving it any data. We don't want to spuriously return
217
        // `Ok(0)` when possible as it will cause calls to write_all() to fail.
218
        // As a result we execute this in a loop to ensure that we try our
219
        // darndest to write the data.
220
        loop {
221
19.4k
            self.dump()?;
222
223
19.4k
            let before_in = self.data.total_in();
224
19.4k
            let ret = self.data.run_vec(buf, &mut self.buf, D::Flush::none());
225
19.4k
            let written = (self.data.total_in() - before_in) as usize;
226
19.4k
            let is_stream_end = matches!(ret, Ok(Status::StreamEnd));
227
228
19.4k
            if !buf.is_empty() && written == 0 && ret.is_ok() && !is_stream_end {
229
0
                continue;
230
19.4k
            }
231
19.4k
            return match ret {
232
19.4k
                Ok(st) => match st {
233
19.4k
                    Status::Ok | Status::BufError | Status::StreamEnd => Ok((written, st)),
234
                },
235
0
                Err(..) => Err(io::Error::new(
236
0
                    io::ErrorKind::InvalidInput,
237
0
                    "corrupt deflate stream",
238
0
                )),
239
            };
240
        }
241
19.4k
    }
Unexecuted instantiation: <flate2::zio::Writer<_, _>>::write_with_status
<flate2::zio::Writer<zip::write::MaybeEncrypted<std::io::cursor::Cursor<&mut [u8]>>, flate2::mem::Compress>>::write_with_status
Line
Count
Source
213
19.4k
    pub(crate) fn write_with_status(&mut self, buf: &[u8]) -> io::Result<(usize, Status)> {
214
        // miniz isn't guaranteed to actually write any of the buffer provided,
215
        // it may be in a flushing mode where it's just giving us data before
216
        // we're actually giving it any data. We don't want to spuriously return
217
        // `Ok(0)` when possible as it will cause calls to write_all() to fail.
218
        // As a result we execute this in a loop to ensure that we try our
219
        // darndest to write the data.
220
        loop {
221
19.4k
            self.dump()?;
222
223
19.4k
            let before_in = self.data.total_in();
224
19.4k
            let ret = self.data.run_vec(buf, &mut self.buf, D::Flush::none());
225
19.4k
            let written = (self.data.total_in() - before_in) as usize;
226
19.4k
            let is_stream_end = matches!(ret, Ok(Status::StreamEnd));
227
228
19.4k
            if !buf.is_empty() && written == 0 && ret.is_ok() && !is_stream_end {
229
0
                continue;
230
19.4k
            }
231
19.4k
            return match ret {
232
19.4k
                Ok(st) => match st {
233
19.4k
                    Status::Ok | Status::BufError | Status::StreamEnd => Ok((written, st)),
234
                },
235
0
                Err(..) => Err(io::Error::new(
236
0
                    io::ErrorKind::InvalidInput,
237
0
                    "corrupt deflate stream",
238
0
                )),
239
            };
240
        }
241
19.4k
    }
242
243
58.4k
    fn dump(&mut self) -> io::Result<()> {
244
        // TODO: should manage this buffer not with `drain` but probably more of
245
        // a deque-like strategy.
246
77.9k
        while !self.buf.is_empty() {
247
19.5k
            let n = self.obj.as_mut().unwrap().write(&self.buf)?;
248
19.5k
            if n == 0 {
249
10
                return Err(io::ErrorKind::WriteZero.into());
250
19.5k
            }
251
19.5k
            self.buf.drain(..n);
252
        }
253
58.4k
        Ok(())
254
58.4k
    }
Unexecuted instantiation: <flate2::zio::Writer<_, _>>::dump
<flate2::zio::Writer<zip::write::MaybeEncrypted<std::io::cursor::Cursor<&mut [u8]>>, flate2::mem::Compress>>::dump
Line
Count
Source
243
58.4k
    fn dump(&mut self) -> io::Result<()> {
244
        // TODO: should manage this buffer not with `drain` but probably more of
245
        // a deque-like strategy.
246
77.9k
        while !self.buf.is_empty() {
247
19.5k
            let n = self.obj.as_mut().unwrap().write(&self.buf)?;
248
19.5k
            if n == 0 {
249
10
                return Err(io::ErrorKind::WriteZero.into());
250
19.5k
            }
251
19.5k
            self.buf.drain(..n);
252
        }
253
58.4k
        Ok(())
254
58.4k
    }
255
}
256
257
impl<W: Write, D: Ops> Write for Writer<W, D> {
258
19.4k
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
259
19.4k
        self.write_with_status(buf).map(|res| res.0)
Unexecuted instantiation: <flate2::zio::Writer<_, _> as std::io::Write>::write::{closure#0}
<flate2::zio::Writer<zip::write::MaybeEncrypted<std::io::cursor::Cursor<&mut [u8]>>, flate2::mem::Compress> as std::io::Write>::write::{closure#0}
Line
Count
Source
259
19.4k
        self.write_with_status(buf).map(|res| res.0)
260
19.4k
    }
Unexecuted instantiation: <flate2::zio::Writer<_, _> as std::io::Write>::write
<flate2::zio::Writer<zip::write::MaybeEncrypted<std::io::cursor::Cursor<&mut [u8]>>, flate2::mem::Compress> as std::io::Write>::write
Line
Count
Source
258
19.4k
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
259
19.4k
        self.write_with_status(buf).map(|res| res.0)
260
19.4k
    }
261
262
0
    fn flush(&mut self) -> io::Result<()> {
263
0
        self.data
264
0
            .run_vec(&[], &mut self.buf, Flush::sync())
265
0
            .map_err(Into::into)?;
266
267
        // Unfortunately miniz doesn't actually tell us when we're done with
268
        // pulling out all the data from the internal stream. To remedy this we
269
        // have to continually ask the stream for more memory until it doesn't
270
        // give us a chunk of memory the same size as our own internal buffer,
271
        // at which point we assume it's reached the end.
272
        loop {
273
0
            self.dump()?;
274
0
            let before = self.data.total_out();
275
0
            self.data
276
0
                .run_vec(&[], &mut self.buf, Flush::none())
277
0
                .map_err(Into::into)?;
278
0
            if before == self.data.total_out() {
279
0
                break;
280
0
            }
281
        }
282
283
0
        self.obj.as_mut().unwrap().flush()
284
0
    }
Unexecuted instantiation: <flate2::zio::Writer<_, _> as std::io::Write>::flush
Unexecuted instantiation: <flate2::zio::Writer<zip::write::MaybeEncrypted<std::io::cursor::Cursor<&mut [u8]>>, flate2::mem::Compress> as std::io::Write>::flush
285
}
286
287
impl<W: Write, D: Ops> Drop for Writer<W, D> {
288
19.4k
    fn drop(&mut self) {
289
19.4k
        if self.obj.is_some() {
290
5
            let _ = self.finish();
291
19.4k
        }
292
19.4k
    }
Unexecuted instantiation: <flate2::zio::Writer<_, _> as core::ops::drop::Drop>::drop
<flate2::zio::Writer<zip::write::MaybeEncrypted<std::io::cursor::Cursor<&mut [u8]>>, flate2::mem::Compress> as core::ops::drop::Drop>::drop
Line
Count
Source
288
19.4k
    fn drop(&mut self) {
289
19.4k
        if self.obj.is_some() {
290
5
            let _ = self.finish();
291
19.4k
        }
292
19.4k
    }
293
}