1 //! ZLIB compression and decompression of streams
3 use std
::io
::prelude
::*;
7 #[cfg(feature = "tokio")]
9 #[cfg(feature = "tokio")]
10 use tokio_io
::{AsyncRead, AsyncWrite}
;
12 use bufreader
::BufReader
;
14 use {Compress, Decompress}
;
16 /// A ZLIB encoder, or compressor.
18 /// This structure implements a `Write` interface and takes a stream of
19 /// uncompressed data, writing the compressed data to the wrapped writer.
20 pub struct EncoderWriter
<W
: Write
> {
21 inner
: zio
::Writer
<W
, Compress
>,
24 /// A ZLIB encoder, or compressor.
26 /// This structure implements a `Read` interface and will read uncompressed
27 /// data from an underlying stream and emit a stream of compressed data.
28 pub struct EncoderReader
<R
> {
29 inner
: EncoderReaderBuf
<BufReader
<R
>>,
32 /// A ZLIB encoder, or compressor.
34 /// This structure implements a `BufRead` interface and will read uncompressed
35 /// data from an underlying stream and emit a stream of compressed data.
36 pub struct EncoderReaderBuf
<R
> {
41 /// A ZLIB decoder, or decompressor.
43 /// This structure implements a `Read` interface and takes a stream of
44 /// compressed data as input, providing the decompressed data when read from.
45 pub struct DecoderReader
<R
> {
46 inner
: DecoderReaderBuf
<BufReader
<R
>>,
49 /// A ZLIB decoder, or decompressor.
51 /// This structure implements a `BufRead` interface and takes a stream of
52 /// compressed data as input, providing the decompressed data when read from.
53 pub struct DecoderReaderBuf
<R
> {
58 /// A ZLIB decoder, or decompressor.
60 /// This structure implements a `Write` and will emit a stream of decompressed
61 /// data when fed a stream of compressed data.
62 pub struct DecoderWriter
<W
: Write
> {
63 inner
: zio
::Writer
<W
, Decompress
>,
66 impl<W
: Write
> EncoderWriter
<W
> {
67 /// Creates a new encoder which will write compressed data to the stream
68 /// given at the given compression level.
70 /// When this encoder is dropped or unwrapped the final pieces of data will
72 pub fn new(w
: W
, level
: ::Compression
) -> EncoderWriter
<W
> {
74 inner
: zio
::Writer
::new(w
, Compress
::new(level
, true)),
78 /// Acquires a reference to the underlying writer.
79 pub fn get_ref(&self) -> &W
{
83 /// Acquires a mutable reference to the underlying writer.
85 /// Note that mutating the output/input state of the stream may corrupt this
86 /// object, so care must be taken when using this method.
87 pub fn get_mut(&mut self) -> &mut W
{
91 /// Resets the state of this encoder entirely, swapping out the output
92 /// stream for another.
94 /// This function will finish encoding the current stream into the current
95 /// output stream before swapping out the two output streams. If the stream
96 /// cannot be finished an error is returned.
98 /// After the current stream has been finished, this will reset the internal
99 /// state of this encoder and replace the output stream with the one
100 /// provided, returning the previous output stream. Future data written to
101 /// this encoder will be the compressed into the stream `w` provided.
102 pub fn reset(&mut self, w
: W
) -> io
::Result
<W
> {
103 try
!(self.inner
.finish());
104 self.inner
.data
.reset();
105 Ok(self.inner
.replace(w
))
108 /// Attempt to finish this output stream, writing out final chunks of data.
110 /// Note that this function can only be used once data has finished being
111 /// written to the output stream. After this function is called then further
112 /// calls to `write` may result in a panic.
116 /// Attempts to write data to this stream may result in a panic after this
117 /// function is called.
118 pub fn try_finish(&mut self) -> io
::Result
<()> {
122 /// Consumes this encoder, flushing the output stream.
124 /// This will flush the underlying data stream, close off the compressed
125 /// stream and, if successful, return the contained writer.
127 /// Note that this function may not be suitable to call in a situation where
128 /// the underlying stream is an asynchronous I/O stream. To finish a stream
129 /// the `try_finish` (or `shutdown`) method should be used instead. To
130 /// re-acquire ownership of a stream it is safe to call this method after
131 /// `try_finish` or `shutdown` has returned `Ok`.
132 pub fn finish(mut self) -> io
::Result
<W
> {
133 try
!(self.inner
.finish());
134 Ok(self.inner
.take_inner())
137 /// Consumes this encoder, flushing the output stream.
139 /// This will flush the underlying data stream and then return the contained
140 /// writer if the flush succeeded.
141 /// The compressed stream will not closed but only flushed. This
142 /// means that obtained byte array can by extended by another deflated
143 /// stream. To close the stream add the two bytes 0x3 and 0x0.
144 pub fn flush_finish(mut self) -> io
::Result
<W
> {
145 try
!(self.inner
.flush());
146 Ok(self.inner
.take_inner())
149 /// Returns the number of bytes that have been written to this compresor.
151 /// Note that not all bytes written to this object may be accounted for,
152 /// there may still be some active buffering.
153 pub fn total_in(&self) -> u64 {
154 self.inner
.data
.total_in()
157 /// Returns the number of bytes that the compressor has produced.
159 /// Note that not all bytes may have been written yet, some may still be
161 pub fn total_out(&self) -> u64 {
162 self.inner
.data
.total_out()
166 impl<W
: Write
> Write
for EncoderWriter
<W
> {
167 fn write(&mut self, buf
: &[u8]) -> io
::Result
<usize> {
168 self.inner
.write(buf
)
171 fn flush(&mut self) -> io
::Result
<()> {
176 #[cfg(feature = "tokio")]
177 impl<W
: AsyncWrite
> AsyncWrite
for EncoderWriter
<W
> {
178 fn shutdown(&mut self) -> Poll
<(), io
::Error
> {
179 try_nb
!(self.try_finish());
180 self.get_mut().shutdown()
184 impl<W
: Read
+ Write
> Read
for EncoderWriter
<W
> {
185 fn read(&mut self, buf
: &mut [u8]) -> io
::Result
<usize> {
186 self.get_mut().read(buf
)
190 #[cfg(feature = "tokio")]
191 impl<W
: AsyncRead
+ AsyncWrite
> AsyncRead
for EncoderWriter
<W
> {
194 impl<R
: Read
> EncoderReader
<R
> {
195 /// Creates a new encoder which will read uncompressed data from the given
196 /// stream and emit the compressed stream.
197 pub fn new(r
: R
, level
: ::Compression
) -> EncoderReader
<R
> {
199 inner
: EncoderReaderBuf
::new(BufReader
::new(r
), level
),
203 /// Resets the state of this encoder entirely, swapping out the input
204 /// stream for another.
206 /// This function will reset the internal state of this encoder and replace
207 /// the input stream with the one provided, returning the previous input
208 /// stream. Future data read from this encoder will be the compressed
209 /// version of `r`'s data.
211 /// Note that there may be currently buffered data when this function is
212 /// called, and in that case the buffered data is discarded.
213 pub fn reset(&mut self, r
: R
) -> R
{
214 self.inner
.data
.reset();
215 self.inner
.obj
.reset(r
)
218 /// Acquires a reference to the underlying stream
219 pub fn get_ref(&self) -> &R
{
220 self.inner
.get_ref().get_ref()
223 /// Acquires a mutable reference to the underlying stream
225 /// Note that mutation of the stream may result in surprising results if
226 /// this encoder is continued to be used.
227 pub fn get_mut(&mut self) -> &mut R
{
228 self.inner
.get_mut().get_mut()
231 /// Consumes this encoder, returning the underlying reader.
233 /// Note that there may be buffered bytes which are not re-acquired as part
234 /// of this transition. It's recommended to only call this function after
235 /// EOF has been reached.
236 pub fn into_inner(self) -> R
{
237 self.inner
.into_inner().into_inner()
240 /// Returns the number of bytes that have been read into this compressor.
242 /// Note that not all bytes read from the underlying object may be accounted
243 /// for, there may still be some active buffering.
244 pub fn total_in(&self) -> u64 {
245 self.inner
.data
.total_in()
248 /// Returns the number of bytes that the compressor has produced.
250 /// Note that not all bytes may have been read yet, some may still be
252 pub fn total_out(&self) -> u64 {
253 self.inner
.data
.total_out()
257 impl<R
: Read
> Read
for EncoderReader
<R
> {
258 fn read(&mut self, buf
: &mut [u8]) -> io
::Result
<usize> {
263 #[cfg(feature = "tokio")]
264 impl<R
: AsyncRead
> AsyncRead
for EncoderReader
<R
> {
267 impl<W
: Read
+ Write
> Write
for EncoderReader
<W
> {
268 fn write(&mut self, buf
: &[u8]) -> io
::Result
<usize> {
269 self.get_mut().write(buf
)
272 fn flush(&mut self) -> io
::Result
<()> {
273 self.get_mut().flush()
277 #[cfg(feature = "tokio")]
278 impl<R
: AsyncRead
+ AsyncWrite
> AsyncWrite
for EncoderReader
<R
> {
279 fn shutdown(&mut self) -> Poll
<(), io
::Error
> {
280 self.get_mut().shutdown()
284 impl<R
: BufRead
> EncoderReaderBuf
<R
> {
285 /// Creates a new encoder which will read uncompressed data from the given
286 /// stream and emit the compressed stream.
287 pub fn new(r
: R
, level
: ::Compression
) -> EncoderReaderBuf
<R
> {
290 data
: Compress
::new(level
, true),
294 /// Resets the state of this encoder entirely, swapping out the input
295 /// stream for another.
297 /// This function will reset the internal state of this encoder and replace
298 /// the input stream with the one provided, returning the previous input
299 /// stream. Future data read from this encoder will be the compressed
300 /// version of `r`'s data.
301 pub fn reset(&mut self, r
: R
) -> R
{
303 mem
::replace(&mut self.obj
, r
)
306 /// Acquires a reference to the underlying reader
307 pub fn get_ref(&self) -> &R
{
311 /// Acquires a mutable reference to the underlying stream
313 /// Note that mutation of the stream may result in surprising results if
314 /// this encoder is continued to be used.
315 pub fn get_mut(&mut self) -> &mut R
{
319 /// Consumes this encoder, returning the underlying reader.
320 pub fn into_inner(self) -> R
{
324 /// Returns the number of bytes that have been read into this compressor.
326 /// Note that not all bytes read from the underlying object may be accounted
327 /// for, there may still be some active buffering.
328 pub fn total_in(&self) -> u64 {
332 /// Returns the number of bytes that the compressor has produced.
334 /// Note that not all bytes may have been read yet, some may still be
336 pub fn total_out(&self) -> u64 {
337 self.data
.total_out()
341 impl<R
: BufRead
> Read
for EncoderReaderBuf
<R
> {
342 fn read(&mut self, buf
: &mut [u8]) -> io
::Result
<usize> {
343 zio
::read(&mut self.obj
, &mut self.data
, buf
)
347 #[cfg(feature = "tokio")]
348 impl<R
: AsyncRead
+ BufRead
> AsyncRead
for EncoderReaderBuf
<R
> {
351 impl<R
: BufRead
+ Write
> Write
for EncoderReaderBuf
<R
> {
352 fn write(&mut self, buf
: &[u8]) -> io
::Result
<usize> {
353 self.get_mut().write(buf
)
356 fn flush(&mut self) -> io
::Result
<()> {
357 self.get_mut().flush()
361 #[cfg(feature = "tokio")]
362 impl<R
: AsyncWrite
+ BufRead
> AsyncWrite
for EncoderReaderBuf
<R
> {
363 fn shutdown(&mut self) -> Poll
<(), io
::Error
> {
364 self.get_mut().shutdown()
368 impl<R
: Read
> DecoderReader
<R
> {
369 /// Creates a new decoder which will decompress data read from the given
371 pub fn new(r
: R
) -> DecoderReader
<R
> {
372 DecoderReader
::new_with_buf(r
, vec
![0; 32 * 1024])
375 /// Same as `new`, but the intermediate buffer for data is specified.
377 /// Note that the specified buffer will only be used up to its current
378 /// length. The buffer's capacity will also not grow over time.
379 pub fn new_with_buf(r
: R
, buf
: Vec
<u8>) -> DecoderReader
<R
> {
381 inner
: DecoderReaderBuf
::new(BufReader
::with_buf(buf
, r
)),
385 /// Resets the state of this decoder entirely, swapping out the input
386 /// stream for another.
388 /// This will reset the internal state of this decoder and replace the
389 /// input stream with the one provided, returning the previous input
390 /// stream. Future data read from this decoder will be the decompressed
391 /// version of `r`'s data.
393 /// Note that there may be currently buffered data when this function is
394 /// called, and in that case the buffered data is discarded.
395 pub fn reset(&mut self, r
: R
) -> R
{
396 self.inner
.data
= Decompress
::new(true);
397 self.inner
.obj
.reset(r
)
400 /// Acquires a reference to the underlying stream
401 pub fn get_ref(&self) -> &R
{
402 self.inner
.get_ref().get_ref()
405 /// Acquires a mutable reference to the underlying stream
407 /// Note that mutation of the stream may result in surprising results if
408 /// this encoder is continued to be used.
409 pub fn get_mut(&mut self) -> &mut R
{
410 self.inner
.get_mut().get_mut()
413 /// Consumes this decoder, returning the underlying reader.
415 /// Note that there may be buffered bytes which are not re-acquired as part
416 /// of this transition. It's recommended to only call this function after
417 /// EOF has been reached.
418 pub fn into_inner(self) -> R
{
419 self.inner
.into_inner().into_inner()
422 /// Returns the number of bytes that the decompressor has consumed.
424 /// Note that this will likely be smaller than what the decompressor
425 /// actually read from the underlying stream due to buffering.
426 pub fn total_in(&self) -> u64 {
427 self.inner
.total_in()
430 /// Returns the number of bytes that the decompressor has produced.
431 pub fn total_out(&self) -> u64 {
432 self.inner
.total_out()
436 impl<R
: Read
> Read
for DecoderReader
<R
> {
437 fn read(&mut self, into
: &mut [u8]) -> io
::Result
<usize> {
438 self.inner
.read(into
)
442 #[cfg(feature = "tokio")]
443 impl<R
: AsyncRead
> AsyncRead
for DecoderReader
<R
> {
446 impl<R
: Read
+ Write
> Write
for DecoderReader
<R
> {
447 fn write(&mut self, buf
: &[u8]) -> io
::Result
<usize> {
448 self.get_mut().write(buf
)
451 fn flush(&mut self) -> io
::Result
<()> {
452 self.get_mut().flush()
456 #[cfg(feature = "tokio")]
457 impl<R
: AsyncWrite
+ AsyncRead
> AsyncWrite
for DecoderReader
<R
> {
458 fn shutdown(&mut self) -> Poll
<(), io
::Error
> {
459 self.get_mut().shutdown()
463 impl<R
: BufRead
> DecoderReaderBuf
<R
> {
464 /// Creates a new decoder which will decompress data read from the given
466 pub fn new(r
: R
) -> DecoderReaderBuf
<R
> {
469 data
: Decompress
::new(true),
473 /// Resets the state of this decoder entirely, swapping out the input
474 /// stream for another.
476 /// This will reset the internal state of this decoder and replace the
477 /// input stream with the one provided, returning the previous input
478 /// stream. Future data read from this decoder will be the decompressed
479 /// version of `r`'s data.
480 pub fn reset(&mut self, r
: R
) -> R
{
481 self.data
= Decompress
::new(true);
482 mem
::replace(&mut self.obj
, r
)
485 /// Acquires a reference to the underlying stream
486 pub fn get_ref(&self) -> &R
{
490 /// Acquires a mutable reference to the underlying stream
492 /// Note that mutation of the stream may result in surprising results if
493 /// this encoder is continued to be used.
494 pub fn get_mut(&mut self) -> &mut R
{
498 /// Consumes this decoder, returning the underlying reader.
499 pub fn into_inner(self) -> R
{
503 /// Returns the number of bytes that the decompressor has consumed.
505 /// Note that this will likely be smaller than what the decompressor
506 /// actually read from the underlying stream due to buffering.
507 pub fn total_in(&self) -> u64 {
511 /// Returns the number of bytes that the decompressor has produced.
512 pub fn total_out(&self) -> u64 {
513 self.data
.total_out()
517 impl<R
: BufRead
> Read
for DecoderReaderBuf
<R
> {
518 fn read(&mut self, into
: &mut [u8]) -> io
::Result
<usize> {
519 zio
::read(&mut self.obj
, &mut self.data
, into
)
523 #[cfg(feature = "tokio")]
524 impl<R
: AsyncRead
+ BufRead
> AsyncRead
for DecoderReaderBuf
<R
> {
527 impl<R
: BufRead
+ Write
> Write
for DecoderReaderBuf
<R
> {
528 fn write(&mut self, buf
: &[u8]) -> io
::Result
<usize> {
529 self.get_mut().write(buf
)
532 fn flush(&mut self) -> io
::Result
<()> {
533 self.get_mut().flush()
537 #[cfg(feature = "tokio")]
538 impl<R
: AsyncWrite
+ BufRead
> AsyncWrite
for DecoderReaderBuf
<R
> {
539 fn shutdown(&mut self) -> Poll
<(), io
::Error
> {
540 self.get_mut().shutdown()
544 impl<W
: Write
> DecoderWriter
<W
> {
545 /// Creates a new decoder which will write uncompressed data to the stream.
547 /// When this decoder is dropped or unwrapped the final pieces of data will
549 pub fn new(w
: W
) -> DecoderWriter
<W
> {
551 inner
: zio
::Writer
::new(w
, Decompress
::new(true)),
555 /// Acquires a reference to the underlying writer.
556 pub fn get_ref(&self) -> &W
{
560 /// Acquires a mutable reference to the underlying writer.
562 /// Note that mutating the output/input state of the stream may corrupt this
563 /// object, so care must be taken when using this method.
564 pub fn get_mut(&mut self) -> &mut W
{
568 /// Resets the state of this decoder entirely, swapping out the output
569 /// stream for another.
571 /// This will reset the internal state of this decoder and replace the
572 /// output stream with the one provided, returning the previous output
573 /// stream. Future data written to this decoder will be decompressed into
574 /// the output stream `w`.
575 pub fn reset(&mut self, w
: W
) -> io
::Result
<W
> {
576 try
!(self.inner
.finish());
577 self.inner
.data
= Decompress
::new(true);
578 Ok(self.inner
.replace(w
))
581 /// Attempt to finish this output stream, writing out final chunks of data.
583 /// Note that this function can only be used once data has finished being
584 /// written to the output stream. After this function is called then further
585 /// calls to `write` may result in a panic.
589 /// Attempts to write data to this stream may result in a panic after this
590 /// function is called.
591 pub fn try_finish(&mut self) -> io
::Result
<()> {
595 /// Consumes this encoder, flushing the output stream.
597 /// This will flush the underlying data stream and then return the contained
598 /// writer if the flush succeeded.
600 /// Note that this function may not be suitable to call in a situation where
601 /// the underlying stream is an asynchronous I/O stream. To finish a stream
602 /// the `try_finish` (or `shutdown`) method should be used instead. To
603 /// re-acquire ownership of a stream it is safe to call this method after
604 /// `try_finish` or `shutdown` has returned `Ok`.
605 pub fn finish(mut self) -> io
::Result
<W
> {
606 try
!(self.inner
.finish());
607 Ok(self.inner
.take_inner())
610 /// Returns the number of bytes that the decompressor has consumed for
613 /// Note that this will likely be smaller than the number of bytes
614 /// successfully written to this stream due to internal buffering.
615 pub fn total_in(&self) -> u64 {
616 self.inner
.data
.total_in()
619 /// Returns the number of bytes that the decompressor has written to its
621 pub fn total_out(&self) -> u64 {
622 self.inner
.data
.total_out()
626 impl<W
: Write
> Write
for DecoderWriter
<W
> {
627 fn write(&mut self, buf
: &[u8]) -> io
::Result
<usize> {
628 self.inner
.write(buf
)
631 fn flush(&mut self) -> io
::Result
<()> {
636 #[cfg(feature = "tokio")]
637 impl<W
: AsyncWrite
> AsyncWrite
for DecoderWriter
<W
> {
638 fn shutdown(&mut self) -> Poll
<(), io
::Error
> {
639 try_nb
!(self.inner
.finish());
640 self.inner
.get_mut().shutdown()
644 impl<W
: Read
+ Write
> Read
for DecoderWriter
<W
> {
645 fn read(&mut self, buf
: &mut [u8]) -> io
::Result
<usize> {
646 self.inner
.get_mut().read(buf
)
650 #[cfg(feature = "tokio")]
651 impl<W
: AsyncRead
+ AsyncWrite
> AsyncRead
for DecoderWriter
<W
> {
656 use std
::io
::prelude
::*;
659 use rand
::{thread_rng, Rng}
;
661 use zlib
::{EncoderWriter, EncoderReader, DecoderReader, DecoderWriter}
;
662 use Compression
::Default
;
666 let mut real
= Vec
::new();
667 let mut w
= EncoderWriter
::new(Vec
::new(), Default
);
668 let v
= thread_rng().gen_iter
::<u8>().take(1024).collect
::<Vec
<_
>>();
670 let to_write
= &v
[..thread_rng().gen_range(0, v
.len())];
671 real
.extend(to_write
.iter().map(|x
| *x
));
672 w
.write_all(to_write
).unwrap();
674 let result
= w
.finish().unwrap();
675 let mut r
= DecoderReader
::new(&result
[..]);
676 let mut ret
= Vec
::new();
677 r
.read_to_end(&mut ret
).unwrap();
678 assert
!(ret
== real
);
683 let mut data
= Vec
::new();
684 EncoderWriter
::new(&mut data
, Default
).write_all(b
"foo").unwrap();
685 let mut r
= DecoderReader
::new(&data
[..]);
686 let mut ret
= Vec
::new();
687 r
.read_to_end(&mut ret
).unwrap();
688 assert
!(ret
== b
"foo");
693 let mut real
= Vec
::new();
694 let mut w
= EncoderWriter
::new(Vec
::new(), Default
);
695 let v
= thread_rng().gen_iter
::<u8>().take(1024).collect
::<Vec
<_
>>();
697 let to_write
= &v
[..thread_rng().gen_range(0, v
.len())];
698 real
.extend(to_write
.iter().map(|x
| *x
));
699 w
.write_all(to_write
).unwrap();
701 let mut result
= w
.finish().unwrap();
703 let result_len
= result
.len();
706 result
.extend(v
.iter().map(|x
| *x
));
709 let mut r
= DecoderReader
::new(&result
[..]);
710 let mut ret
= Vec
::new();
711 r
.read_to_end(&mut ret
).unwrap();
712 assert
!(ret
== real
);
713 assert_eq
!(r
.total_in(), result_len
as u64);
721 .collect
::<Vec
<_
>>();
722 let mut r
= DecoderReader
::new(EncoderReader
::new(&v
[..], Default
));
723 let mut ret
= Vec
::new();
724 r
.read_to_end(&mut ret
).unwrap();
733 .collect
::<Vec
<_
>>();
734 let mut w
= EncoderWriter
::new(DecoderWriter
::new(Vec
::new()), Default
);
735 w
.write_all(&v
).unwrap();
736 let w
= w
.finish().unwrap().finish().unwrap();
745 .collect
::<Vec
<_
>>();
746 let mut w
= EncoderWriter
::new(Vec
::new(), Default
);
747 w
.write_all(&v
).unwrap();
748 let data
= w
.finish().unwrap();
751 let (mut a
, mut b
, mut c
) = (Vec
::new(), Vec
::new(), Vec
::new());
752 let mut r
= DecoderReader
::new(&data
[..]);
753 r
.read_to_end(&mut a
).unwrap();
755 r
.read_to_end(&mut b
).unwrap();
757 let mut r
= DecoderReader
::new(&data
[..]);
758 r
.read_to_end(&mut c
).unwrap();
759 assert
!(a
== b
&& b
== c
&& c
== v
);
763 let mut w
= DecoderWriter
::new(Vec
::new());
764 w
.write_all(&data
).unwrap();
765 let a
= w
.reset(Vec
::new()).unwrap();
766 w
.write_all(&data
).unwrap();
767 let b
= w
.finish().unwrap();
769 let mut w
= DecoderWriter
::new(Vec
::new());
770 w
.write_all(&data
).unwrap();
771 let c
= w
.finish().unwrap();
772 assert
!(a
== b
&& b
== c
&& c
== v
);
778 // regress tests: previously caused a panic on drop
779 let mut out
: Vec
<u8> = Vec
::new();
780 let data
: Vec
<u8> = (0..255).cycle().take(1024).collect();
781 let mut w
= DecoderWriter
::new(&mut out
);
782 match w
.write_all(&data
[..]) {
783 Ok(_
) => panic
!("Expected an error to be returned!"),
784 Err(e
) => assert_eq
!(e
.kind(), io
::ErrorKind
::InvalidInput
),
790 ::quickcheck
::quickcheck(test
as fn(_
) -> _
);
792 fn test(v
: Vec
<u8>) -> bool
{
793 let mut r
= DecoderReader
::new(EncoderReader
::new(&v
[..], Default
));
794 let mut v2
= Vec
::new();
795 r
.read_to_end(&mut v2
).unwrap();
802 ::quickcheck
::quickcheck(test
as fn(_
) -> _
);
804 fn test(v
: Vec
<u8>) -> bool
{
805 let mut w
= EncoderWriter
::new(DecoderWriter
::new(Vec
::new()), Default
);
806 w
.write_all(&v
).unwrap();
807 v
== w
.finish().unwrap().finish().unwrap()