Coverage Report

Created: 2025-10-10 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/flate2-1.1.4/src/zio.rs
Line
Count
Source
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
608M
    fn total_in(&self) -> u64 {
39
608M
        self.total_in()
40
608M
    }
41
14.7k
    fn total_out(&self) -> u64 {
42
14.7k
        self.total_out()
43
14.7k
    }
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
304M
    fn run_vec(
53
304M
        &mut self,
54
304M
        input: &[u8],
55
304M
        output: &mut Vec<u8>,
56
304M
        flush: FlushCompress,
57
304M
    ) -> Result<Status, CompressError> {
58
304M
        self.compress_vec(input, output, flush)
59
304M
    }
60
}
61
62
impl Ops for Decompress {
63
    type Error = DecompressError;
64
    type Flush = FlushDecompress;
65
0
    fn total_in(&self) -> u64 {
66
0
        self.total_in()
67
0
    }
68
0
    fn total_out(&self) -> u64 {
69
0
        self.total_out()
70
0
    }
71
0
    fn run(
72
0
        &mut self,
73
0
        input: &[u8],
74
0
        output: &mut [u8],
75
0
        flush: FlushDecompress,
76
0
    ) -> Result<Status, DecompressError> {
77
0
        self.decompress(input, output, flush)
78
0
    }
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
304M
    fn none() -> Self {
97
304M
        FlushCompress::None
98
304M
    }
99
100
0
    fn sync() -> Self {
101
0
        FlushCompress::Sync
102
0
    }
103
104
7.37k
    fn finish() -> Self {
105
7.37k
        FlushCompress::Finish
106
7.37k
    }
107
}
108
109
impl Flush for FlushDecompress {
110
0
    fn none() -> Self {
111
0
        FlushDecompress::None
112
0
    }
113
114
0
    fn sync() -> Self {
115
0
        FlushDecompress::Sync
116
0
    }
117
118
0
    fn finish() -> Self {
119
0
        FlushDecompress::Finish
120
0
    }
121
}
122
123
0
pub fn read<R, D>(obj: &mut R, data: &mut D, dst: &mut [u8]) -> io::Result<usize>
124
0
where
125
0
    R: BufRead,
126
0
    D: Ops,
127
{
128
    loop {
129
        let (read, consumed, ret, eof);
130
        {
131
0
            let input = obj.fill_buf()?;
132
0
            eof = input.is_empty();
133
0
            let before_out = data.total_out();
134
0
            let before_in = data.total_in();
135
0
            let flush = if eof {
136
0
                D::Flush::finish()
137
            } else {
138
0
                D::Flush::none()
139
            };
140
0
            ret = data.run(input, dst, flush);
141
0
            read = (data.total_out() - before_out) as usize;
142
0
            consumed = (data.total_in() - before_in) as usize;
143
        }
144
0
        obj.consume(consumed);
145
146
0
        match ret {
147
            // If we haven't ready any data and we haven't hit EOF yet,
148
            // then we need to keep asking for more data because if we
149
            // return that 0 bytes of data have been read then it will
150
            // be interpreted as EOF.
151
0
            Ok(Status::Ok | Status::BufError) if read == 0 && !eof && !dst.is_empty() => continue,
152
0
            Ok(Status::Ok | Status::BufError | Status::StreamEnd) => return Ok(read),
153
154
            Err(..) => {
155
0
                return Err(io::Error::new(
156
0
                    io::ErrorKind::InvalidInput,
157
0
                    "corrupt deflate stream",
158
0
                ))
159
            }
160
        }
161
    }
162
0
}
163
164
impl<W: Write, D: Ops> Writer<W, D> {
165
3.62k
    pub fn new(w: W, d: D) -> Writer<W, D> {
166
3.62k
        Writer {
167
3.62k
            obj: Some(w),
168
3.62k
            data: d,
169
3.62k
            buf: Vec::with_capacity(32 * 1024),
170
3.62k
        }
171
3.62k
    }
<flate2::zio::Writer<alloc::vec::Vec<u8>, flate2::mem::Compress>>::new
Line
Count
Source
165
3.62k
    pub fn new(w: W, d: D) -> Writer<W, D> {
166
3.62k
        Writer {
167
3.62k
            obj: Some(w),
168
3.62k
            data: d,
169
3.62k
            buf: Vec::with_capacity(32 * 1024),
170
3.62k
        }
171
3.62k
    }
Unexecuted instantiation: <flate2::zio::Writer<_, _>>::new
172
173
3.62k
    pub fn finish(&mut self) -> io::Result<()> {
174
        loop {
175
7.37k
            self.dump()?;
176
177
7.37k
            let before = self.data.total_out();
178
7.37k
            self.data
179
7.37k
                .run_vec(&[], &mut self.buf, Flush::finish())
180
7.37k
                .map_err(Into::into)?;
181
7.37k
            if before == self.data.total_out() {
182
3.62k
                return Ok(());
183
3.74k
            }
184
        }
185
3.62k
    }
<flate2::zio::Writer<alloc::vec::Vec<u8>, flate2::mem::Compress>>::finish
Line
Count
Source
173
3.62k
    pub fn finish(&mut self) -> io::Result<()> {
174
        loop {
175
7.37k
            self.dump()?;
176
177
7.37k
            let before = self.data.total_out();
178
7.37k
            self.data
179
7.37k
                .run_vec(&[], &mut self.buf, Flush::finish())
180
7.37k
                .map_err(Into::into)?;
181
7.37k
            if before == self.data.total_out() {
182
3.62k
                return Ok(());
183
3.74k
            }
184
        }
185
3.62k
    }
Unexecuted instantiation: <flate2::zio::Writer<_, _>>::finish
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
3.62k
    pub fn take_inner(&mut self) -> W {
205
3.62k
        self.obj.take().unwrap()
206
3.62k
    }
<flate2::zio::Writer<alloc::vec::Vec<u8>, flate2::mem::Compress>>::take_inner
Line
Count
Source
204
3.62k
    pub fn take_inner(&mut self) -> W {
205
3.62k
        self.obj.take().unwrap()
206
3.62k
    }
Unexecuted instantiation: <flate2::zio::Writer<_, _>>::take_inner
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
304M
    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
304M
            self.dump()?;
222
223
304M
            let before_in = self.data.total_in();
224
304M
            let ret = self.data.run_vec(buf, &mut self.buf, D::Flush::none());
225
304M
            let written = (self.data.total_in() - before_in) as usize;
226
304M
            let is_stream_end = matches!(ret, Ok(Status::StreamEnd));
227
228
304M
            if !buf.is_empty() && written == 0 && ret.is_ok() && !is_stream_end {
229
0
                continue;
230
304M
            }
231
304M
            return match ret {
232
304M
                Ok(st) => match st {
233
304M
                    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
304M
    }
<flate2::zio::Writer<alloc::vec::Vec<u8>, flate2::mem::Compress>>::write_with_status
Line
Count
Source
213
304M
    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
304M
            self.dump()?;
222
223
304M
            let before_in = self.data.total_in();
224
304M
            let ret = self.data.run_vec(buf, &mut self.buf, D::Flush::none());
225
304M
            let written = (self.data.total_in() - before_in) as usize;
226
304M
            let is_stream_end = matches!(ret, Ok(Status::StreamEnd));
227
228
304M
            if !buf.is_empty() && written == 0 && ret.is_ok() && !is_stream_end {
229
0
                continue;
230
304M
            }
231
304M
            return match ret {
232
304M
                Ok(st) => match st {
233
304M
                    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
304M
    }
Unexecuted instantiation: <flate2::zio::Writer<_, _>>::write_with_status
242
243
304M
    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
304M
        while !self.buf.is_empty() {
247
13.2k
            let n = self.obj.as_mut().unwrap().write(&self.buf)?;
248
13.2k
            if n == 0 {
249
0
                return Err(io::ErrorKind::WriteZero.into());
250
13.2k
            }
251
13.2k
            self.buf.drain(..n);
252
        }
253
304M
        Ok(())
254
304M
    }
<flate2::zio::Writer<alloc::vec::Vec<u8>, flate2::mem::Compress>>::dump
Line
Count
Source
243
304M
    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
304M
        while !self.buf.is_empty() {
247
13.2k
            let n = self.obj.as_mut().unwrap().write(&self.buf)?;
248
13.2k
            if n == 0 {
249
0
                return Err(io::ErrorKind::WriteZero.into());
250
13.2k
            }
251
13.2k
            self.buf.drain(..n);
252
        }
253
304M
        Ok(())
254
304M
    }
Unexecuted instantiation: <flate2::zio::Writer<_, _>>::dump
255
}
256
257
impl<W: Write, D: Ops> Write for Writer<W, D> {
258
304M
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
259
304M
        self.write_with_status(buf).map(|res| res.0)
260
304M
    }
<flate2::zio::Writer<alloc::vec::Vec<u8>, flate2::mem::Compress> as std::io::Write>::write
Line
Count
Source
258
304M
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
259
304M
        self.write_with_status(buf).map(|res| res.0)
260
304M
    }
Unexecuted instantiation: <flate2::zio::Writer<_, _> as std::io::Write>::write
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
    }
285
}
286
287
impl<W: Write, D: Ops> Drop for Writer<W, D> {
288
3.62k
    fn drop(&mut self) {
289
3.62k
        if self.obj.is_some() {
290
0
            let _ = self.finish();
291
3.62k
        }
292
3.62k
    }
<flate2::zio::Writer<alloc::vec::Vec<u8>, flate2::mem::Compress> as core::ops::drop::Drop>::drop
Line
Count
Source
288
3.62k
    fn drop(&mut self) {
289
3.62k
        if self.obj.is_some() {
290
0
            let _ = self.finish();
291
3.62k
        }
292
3.62k
    }
Unexecuted instantiation: <flate2::zio::Writer<_, _> as core::ops::drop::Drop>::drop
293
}