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