/rust/registry/src/index.crates.io-1949cf8c6b5b557f/bzip2-0.4.4/src/read.rs
Line | Count | Source |
1 | | //! Reader-based compression/decompression streams |
2 | | |
3 | | use std::io::prelude::*; |
4 | | use std::io::{self, BufReader}; |
5 | | |
6 | | #[cfg(feature = "tokio")] |
7 | | use futures::Poll; |
8 | | #[cfg(feature = "tokio")] |
9 | | use tokio_io::{AsyncRead, AsyncWrite}; |
10 | | |
11 | | use bufread; |
12 | | use Compression; |
13 | | |
14 | | /// A compression stream which wraps an uncompressed stream of data. Compressed |
15 | | /// data will be read from the stream. |
16 | | pub struct BzEncoder<R> { |
17 | | inner: bufread::BzEncoder<BufReader<R>>, |
18 | | } |
19 | | |
20 | | /// A decompression stream which wraps a compressed stream of data. Decompressed |
21 | | /// data will be read from the stream. |
22 | | pub struct BzDecoder<R> { |
23 | | inner: bufread::BzDecoder<BufReader<R>>, |
24 | | } |
25 | | |
26 | | impl<R: Read> BzEncoder<R> { |
27 | | /// Create a new compression stream which will compress at the given level |
28 | | /// to read compress output to the give output stream. |
29 | 0 | pub fn new(r: R, level: Compression) -> BzEncoder<R> { |
30 | 0 | BzEncoder { |
31 | 0 | inner: bufread::BzEncoder::new(BufReader::new(r), level), |
32 | 0 | } |
33 | 0 | } |
34 | | |
35 | | /// Acquires a reference to the underlying stream |
36 | 0 | pub fn get_ref(&self) -> &R { |
37 | 0 | self.inner.get_ref().get_ref() |
38 | 0 | } |
39 | | |
40 | | /// Acquires a mutable reference to the underlying stream |
41 | | /// |
42 | | /// Note that mutation of the stream may result in surprising results if |
43 | | /// this encoder is continued to be used. |
44 | 0 | pub fn get_mut(&mut self) -> &mut R { |
45 | 0 | self.inner.get_mut().get_mut() |
46 | 0 | } |
47 | | |
48 | | /// Unwrap the underlying writer, finishing the compression stream. |
49 | 0 | pub fn into_inner(self) -> R { |
50 | 0 | self.inner.into_inner().into_inner() |
51 | 0 | } |
52 | | |
53 | | /// Returns the number of bytes produced by the compressor |
54 | | /// (e.g. the number of bytes read from this stream) |
55 | | /// |
56 | | /// Note that, due to buffering, this only bears any relation to |
57 | | /// total_in() when the compressor chooses to flush its data |
58 | | /// (unfortunately, this won't happen in general |
59 | | /// at the end of the stream, because the compressor doesn't know |
60 | | /// if there's more data to come). At that point, |
61 | | /// `total_out() / total_in()` would be the compression ratio. |
62 | 0 | pub fn total_out(&self) -> u64 { |
63 | 0 | self.inner.total_out() |
64 | 0 | } |
65 | | |
66 | | /// Returns the number of bytes consumed by the compressor |
67 | | /// (e.g. the number of bytes read from the underlying stream) |
68 | 0 | pub fn total_in(&self) -> u64 { |
69 | 0 | self.inner.total_in() |
70 | 0 | } |
71 | | } |
72 | | |
73 | | impl<R: Read> Read for BzEncoder<R> { |
74 | 0 | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
75 | 0 | self.inner.read(buf) |
76 | 0 | } |
77 | | } |
78 | | |
79 | | #[cfg(feature = "tokio")] |
80 | | impl<R: AsyncRead> AsyncRead for BzEncoder<R> {} |
81 | | |
82 | | impl<W: Write + Read> Write for BzEncoder<W> { |
83 | 0 | fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
84 | 0 | self.get_mut().write(buf) |
85 | 0 | } |
86 | | |
87 | 0 | fn flush(&mut self) -> io::Result<()> { |
88 | 0 | self.get_mut().flush() |
89 | 0 | } |
90 | | } |
91 | | |
92 | | #[cfg(feature = "tokio")] |
93 | | impl<R: AsyncWrite + Read> AsyncWrite for BzEncoder<R> { |
94 | | fn shutdown(&mut self) -> Poll<(), io::Error> { |
95 | | self.get_mut().shutdown() |
96 | | } |
97 | | } |
98 | | |
99 | | impl<R: Read> BzDecoder<R> { |
100 | | /// Create a new decompression stream, which will read compressed |
101 | | /// data from the given input stream and decompress it. |
102 | 2.40k | pub fn new(r: R) -> BzDecoder<R> { |
103 | 2.40k | BzDecoder { |
104 | 2.40k | inner: bufread::BzDecoder::new(BufReader::new(r)), |
105 | 2.40k | } |
106 | 2.40k | } <bzip2::read::BzDecoder<zip::read::CryptoReader>>::new Line | Count | Source | 102 | 2.40k | pub fn new(r: R) -> BzDecoder<R> { | 103 | 2.40k | BzDecoder { | 104 | 2.40k | inner: bufread::BzDecoder::new(BufReader::new(r)), | 105 | 2.40k | } | 106 | 2.40k | } |
Unexecuted instantiation: <bzip2::read::BzDecoder<_>>::new |
107 | | |
108 | | /// Acquires a reference to the underlying stream |
109 | 0 | pub fn get_ref(&self) -> &R { |
110 | 0 | self.inner.get_ref().get_ref() |
111 | 0 | } |
112 | | |
113 | | /// Acquires a mutable reference to the underlying stream |
114 | | /// |
115 | | /// Note that mutation of the stream may result in surprising results if |
116 | | /// this encoder is continued to be used. |
117 | 0 | pub fn get_mut(&mut self) -> &mut R { |
118 | 0 | self.inner.get_mut().get_mut() |
119 | 0 | } |
120 | | |
121 | | /// Unwrap the underlying writer, finishing the compression stream. |
122 | 0 | pub fn into_inner(self) -> R { |
123 | 0 | self.inner.into_inner().into_inner() |
124 | 0 | } Unexecuted instantiation: <bzip2::read::BzDecoder<zip::read::CryptoReader>>::into_inner Unexecuted instantiation: <bzip2::read::BzDecoder<_>>::into_inner |
125 | | |
126 | | /// Returns the number of bytes produced by the decompressor |
127 | | /// (e.g. the number of bytes read from this stream) |
128 | | /// |
129 | | /// Note that, due to buffering, this only bears any relation to |
130 | | /// total_in() when the decompressor reaches a sync point |
131 | | /// (e.g. where the original compressed stream was flushed). |
132 | | /// At that point, `total_in() / total_out()` is the compression ratio. |
133 | 0 | pub fn total_out(&self) -> u64 { |
134 | 0 | self.inner.total_out() |
135 | 0 | } |
136 | | |
137 | | /// Returns the number of bytes consumed by the decompressor |
138 | | /// (e.g. the number of bytes read from the underlying stream) |
139 | 0 | pub fn total_in(&self) -> u64 { |
140 | 0 | self.inner.total_in() |
141 | 0 | } |
142 | | } |
143 | | |
144 | | impl<R: Read> Read for BzDecoder<R> { |
145 | 4.71k | fn read(&mut self, into: &mut [u8]) -> io::Result<usize> { |
146 | 4.71k | self.inner.read(into) |
147 | 4.71k | } <bzip2::read::BzDecoder<zip::read::CryptoReader> as std::io::Read>::read Line | Count | Source | 145 | 4.71k | fn read(&mut self, into: &mut [u8]) -> io::Result<usize> { | 146 | 4.71k | self.inner.read(into) | 147 | 4.71k | } |
Unexecuted instantiation: <bzip2::read::BzDecoder<_> as std::io::Read>::read |
148 | | } |
149 | | |
150 | | #[cfg(feature = "tokio")] |
151 | | impl<R: AsyncRead + Read> AsyncRead for BzDecoder<R> {} |
152 | | |
153 | | impl<W: Write + Read> Write for BzDecoder<W> { |
154 | 0 | fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
155 | 0 | self.get_mut().write(buf) |
156 | 0 | } |
157 | | |
158 | 0 | fn flush(&mut self) -> io::Result<()> { |
159 | 0 | self.get_mut().flush() |
160 | 0 | } |
161 | | } |
162 | | |
163 | | #[cfg(feature = "tokio")] |
164 | | impl<R: AsyncWrite + Read> AsyncWrite for BzDecoder<R> { |
165 | | fn shutdown(&mut self) -> Poll<(), io::Error> { |
166 | | self.get_mut().shutdown() |
167 | | } |
168 | | } |
169 | | |
170 | | /// A bzip2 streaming decoder that decodes all members of a multistream |
171 | | /// |
172 | | /// Wikipedia, particularly, uses bzip2 multistream for their dumps. |
173 | | pub struct MultiBzDecoder<R> { |
174 | | inner: bufread::MultiBzDecoder<BufReader<R>>, |
175 | | } |
176 | | |
177 | | impl<R: Read> MultiBzDecoder<R> { |
178 | | /// Creates a new decoder from the given reader, immediately parsing the |
179 | | /// (first) gzip header. If the gzip stream contains multiple members all will |
180 | | /// be decoded. |
181 | 0 | pub fn new(r: R) -> MultiBzDecoder<R> { |
182 | 0 | MultiBzDecoder { |
183 | 0 | inner: bufread::MultiBzDecoder::new(BufReader::new(r)), |
184 | 0 | } |
185 | 0 | } |
186 | | } |
187 | | |
188 | | impl<R> MultiBzDecoder<R> { |
189 | | /// Acquires a reference to the underlying reader. |
190 | 0 | pub fn get_ref(&self) -> &R { |
191 | 0 | self.inner.get_ref().get_ref() |
192 | 0 | } |
193 | | |
194 | | /// Acquires a mutable reference to the underlying stream. |
195 | | /// |
196 | | /// Note that mutation of the stream may result in surprising results if |
197 | | /// this encoder is continued to be used. |
198 | 0 | pub fn get_mut(&mut self) -> &mut R { |
199 | 0 | self.inner.get_mut().get_mut() |
200 | 0 | } |
201 | | |
202 | | /// Consumes this decoder, returning the underlying reader. |
203 | 0 | pub fn into_inner(self) -> R { |
204 | 0 | self.inner.into_inner().into_inner() |
205 | 0 | } |
206 | | } |
207 | | |
208 | | impl<R: Read> Read for MultiBzDecoder<R> { |
209 | 0 | fn read(&mut self, into: &mut [u8]) -> io::Result<usize> { |
210 | 0 | self.inner.read(into) |
211 | 0 | } |
212 | | } |
213 | | |
214 | | #[cfg(feature = "tokio")] |
215 | | impl<R: AsyncRead> AsyncRead for MultiBzDecoder<R> {} |
216 | | |
217 | | impl<R: Read + Write> Write for MultiBzDecoder<R> { |
218 | 0 | fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
219 | 0 | self.get_mut().write(buf) |
220 | 0 | } |
221 | | |
222 | 0 | fn flush(&mut self) -> io::Result<()> { |
223 | 0 | self.get_mut().flush() |
224 | 0 | } |
225 | | } |
226 | | |
227 | | #[cfg(feature = "tokio")] |
228 | | impl<R: AsyncWrite + AsyncRead> AsyncWrite for MultiBzDecoder<R> { |
229 | | fn shutdown(&mut self) -> Poll<(), io::Error> { |
230 | | self.get_mut().shutdown() |
231 | | } |
232 | | } |
233 | | |
234 | | #[cfg(test)] |
235 | | mod tests { |
236 | | use partial_io::{GenInterrupted, PartialRead, PartialWithErrors}; |
237 | | use rand::distributions::Standard; |
238 | | use rand::{thread_rng, Rng}; |
239 | | use read::{BzDecoder, BzEncoder, MultiBzDecoder}; |
240 | | use std::io::prelude::*; |
241 | | use Compression; |
242 | | |
243 | | #[test] |
244 | | fn smoke() { |
245 | | let m: &[u8] = &[1, 2, 3, 4, 5, 6, 7, 8]; |
246 | | let mut c = BzEncoder::new(m, Compression::default()); |
247 | | let mut data = vec![]; |
248 | | c.read_to_end(&mut data).unwrap(); |
249 | | let mut d = BzDecoder::new(&data[..]); |
250 | | let mut data2 = Vec::new(); |
251 | | d.read_to_end(&mut data2).unwrap(); |
252 | | assert_eq!(data2, m); |
253 | | } |
254 | | |
255 | | #[test] |
256 | | fn smoke2() { |
257 | | let m: &[u8] = &[1, 2, 3, 4, 5, 6, 7, 8]; |
258 | | let c = BzEncoder::new(m, Compression::default()); |
259 | | let mut d = BzDecoder::new(c); |
260 | | let mut data = vec![]; |
261 | | d.read_to_end(&mut data).unwrap(); |
262 | | assert_eq!(data, [1, 2, 3, 4, 5, 6, 7, 8]); |
263 | | } |
264 | | |
265 | | #[test] |
266 | | fn smoke3() { |
267 | | let m = vec![3u8; 128 * 1024 + 1]; |
268 | | let c = BzEncoder::new(&m[..], Compression::default()); |
269 | | let mut d = BzDecoder::new(c); |
270 | | let mut data = vec![]; |
271 | | d.read_to_end(&mut data).unwrap(); |
272 | | assert!(data == &m[..]); |
273 | | } |
274 | | |
275 | | #[test] |
276 | | fn self_terminating() { |
277 | | let m = vec![3u8; 128 * 1024 + 1]; |
278 | | let mut c = BzEncoder::new(&m[..], Compression::default()); |
279 | | |
280 | | let mut result = Vec::new(); |
281 | | c.read_to_end(&mut result).unwrap(); |
282 | | |
283 | | let v = thread_rng() |
284 | | .sample_iter(&Standard) |
285 | | .take(1024) |
286 | | .collect::<Vec<_>>(); |
287 | | for _ in 0..200 { |
288 | | result.extend(v.iter().map(|x: &u8| *x)); |
289 | | } |
290 | | |
291 | | let mut d = BzDecoder::new(&result[..]); |
292 | | let mut data = Vec::with_capacity(m.len()); |
293 | | unsafe { |
294 | | data.set_len(m.len()); |
295 | | } |
296 | | assert!(d.read(&mut data).unwrap() == m.len()); |
297 | | assert!(data == &m[..]); |
298 | | } |
299 | | |
300 | | #[test] |
301 | | fn zero_length_read_at_eof() { |
302 | | let m = Vec::new(); |
303 | | let mut c = BzEncoder::new(&m[..], Compression::default()); |
304 | | |
305 | | let mut result = Vec::new(); |
306 | | c.read_to_end(&mut result).unwrap(); |
307 | | |
308 | | let mut d = BzDecoder::new(&result[..]); |
309 | | let mut data = Vec::new(); |
310 | | assert!(d.read(&mut data).unwrap() == 0); |
311 | | } |
312 | | |
313 | | #[test] |
314 | | fn zero_length_read_with_data() { |
315 | | let m = vec![3u8; 128 * 1024 + 1]; |
316 | | let mut c = BzEncoder::new(&m[..], Compression::default()); |
317 | | |
318 | | let mut result = Vec::new(); |
319 | | c.read_to_end(&mut result).unwrap(); |
320 | | |
321 | | let mut d = BzDecoder::new(&result[..]); |
322 | | let mut data = Vec::new(); |
323 | | assert!(d.read(&mut data).unwrap() == 0); |
324 | | } |
325 | | |
326 | | #[test] |
327 | | fn multistream_read_till_eof() { |
328 | | let m = vec![3u8; 128 * 1024 + 1]; |
329 | | let repeat = 3; |
330 | | let mut result = Vec::new(); |
331 | | |
332 | | for _i in 0..repeat { |
333 | | let mut c = BzEncoder::new(&m[..], Compression::default()); |
334 | | c.read_to_end(&mut result).unwrap(); |
335 | | } |
336 | | |
337 | | let mut d = MultiBzDecoder::new(&result[..]); |
338 | | let mut data = Vec::new(); |
339 | | |
340 | | let a = d.read_to_end(&mut data).unwrap(); |
341 | | let b = m.len() * repeat; |
342 | | assert!(a == b, "{} {}", a, b); |
343 | | } |
344 | | |
345 | | #[test] |
346 | | fn empty() { |
347 | | let r = BzEncoder::new(&[][..], Compression::default()); |
348 | | let mut r = BzDecoder::new(r); |
349 | | let mut v2 = Vec::new(); |
350 | | r.read_to_end(&mut v2).unwrap(); |
351 | | assert!(v2.len() == 0); |
352 | | } |
353 | | |
354 | | #[test] |
355 | | fn qc() { |
356 | | ::quickcheck::quickcheck(test as fn(_) -> _); |
357 | | |
358 | | fn test(v: Vec<u8>) -> bool { |
359 | | let r = BzEncoder::new(&v[..], Compression::default()); |
360 | | let mut r = BzDecoder::new(r); |
361 | | let mut v2 = Vec::new(); |
362 | | r.read_to_end(&mut v2).unwrap(); |
363 | | v == v2 |
364 | | } |
365 | | } |
366 | | |
367 | | #[test] |
368 | | fn qc_partial() { |
369 | | quickcheck6::quickcheck(test as fn(_, _, _) -> _); |
370 | | |
371 | | fn test( |
372 | | v: Vec<u8>, |
373 | | encode_ops: PartialWithErrors<GenInterrupted>, |
374 | | decode_ops: PartialWithErrors<GenInterrupted>, |
375 | | ) -> bool { |
376 | | let r = BzEncoder::new(PartialRead::new(&v[..], encode_ops), Compression::default()); |
377 | | let mut r = BzDecoder::new(PartialRead::new(r, decode_ops)); |
378 | | let mut v2 = Vec::new(); |
379 | | r.read_to_end(&mut v2).unwrap(); |
380 | | v == v2 |
381 | | } |
382 | | } |
383 | | } |