Coverage Report

Created: 2024-06-24 06:10

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