summaryrefslogtreecommitdiffstats
path: root/third_party/rust/flate2/src/zlib
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
commit43a97878ce14b72f0981164f87f2e35e14151312 (patch)
tree620249daf56c0258faa40cbdcf9cfba06de2a846 /third_party/rust/flate2/src/zlib
parentInitial commit. (diff)
downloadfirefox-upstream.tar.xz
firefox-upstream.zip
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/flate2/src/zlib')
-rw-r--r--third_party/rust/flate2/src/zlib/bufread.rs233
-rw-r--r--third_party/rust/flate2/src/zlib/mod.rs159
-rw-r--r--third_party/rust/flate2/src/zlib/read.rs240
-rw-r--r--third_party/rust/flate2/src/zlib/write.rs321
4 files changed, 953 insertions, 0 deletions
diff --git a/third_party/rust/flate2/src/zlib/bufread.rs b/third_party/rust/flate2/src/zlib/bufread.rs
new file mode 100644
index 0000000000..f1d3231651
--- /dev/null
+++ b/third_party/rust/flate2/src/zlib/bufread.rs
@@ -0,0 +1,233 @@
+use std::io;
+use std::io::prelude::*;
+use std::mem;
+
+use crate::zio;
+use crate::{Compress, Decompress};
+
+/// A ZLIB encoder, or compressor.
+///
+/// This structure consumes a [`BufRead`] interface, reading uncompressed data
+/// from the underlying reader, and emitting compressed data.
+///
+/// [`BufRead`]: https://doc.rust-lang.org/std/io/trait.BufRead.html
+///
+/// # Examples
+///
+/// ```
+/// use std::io::prelude::*;
+/// use flate2::Compression;
+/// use flate2::bufread::ZlibEncoder;
+/// use std::fs::File;
+/// use std::io::BufReader;
+///
+/// // Use a buffered file to compress contents into a Vec<u8>
+///
+/// # fn open_hello_world() -> std::io::Result<Vec<u8>> {
+/// let f = File::open("examples/hello_world.txt")?;
+/// let b = BufReader::new(f);
+/// let mut z = ZlibEncoder::new(b, Compression::fast());
+/// let mut buffer = Vec::new();
+/// z.read_to_end(&mut buffer)?;
+/// # Ok(buffer)
+/// # }
+/// ```
+#[derive(Debug)]
+pub struct ZlibEncoder<R> {
+ obj: R,
+ data: Compress,
+}
+
+impl<R: BufRead> ZlibEncoder<R> {
+ /// Creates a new encoder which will read uncompressed data from the given
+ /// stream and emit the compressed stream.
+ pub fn new(r: R, level: crate::Compression) -> ZlibEncoder<R> {
+ ZlibEncoder {
+ obj: r,
+ data: Compress::new(level, true),
+ }
+ }
+}
+
+pub fn reset_encoder_data<R>(zlib: &mut ZlibEncoder<R>) {
+ zlib.data.reset()
+}
+
+impl<R> ZlibEncoder<R> {
+ /// Resets the state of this encoder entirely, swapping out the input
+ /// stream for another.
+ ///
+ /// This function will reset the internal state of this encoder and replace
+ /// the input stream with the one provided, returning the previous input
+ /// stream. Future data read from this encoder will be the compressed
+ /// version of `r`'s data.
+ pub fn reset(&mut self, r: R) -> R {
+ reset_encoder_data(self);
+ mem::replace(&mut self.obj, r)
+ }
+
+ /// Acquires a reference to the underlying reader
+ pub fn get_ref(&self) -> &R {
+ &self.obj
+ }
+
+ /// Acquires a mutable reference to the underlying stream
+ ///
+ /// Note that mutation of the stream may result in surprising results if
+ /// this encoder is continued to be used.
+ pub fn get_mut(&mut self) -> &mut R {
+ &mut self.obj
+ }
+
+ /// Consumes this encoder, returning the underlying reader.
+ pub fn into_inner(self) -> R {
+ self.obj
+ }
+
+ /// Returns the number of bytes that have been read into this compressor.
+ ///
+ /// Note that not all bytes read from the underlying object may be accounted
+ /// for, there may still be some active buffering.
+ pub fn total_in(&self) -> u64 {
+ self.data.total_in()
+ }
+
+ /// Returns the number of bytes that the compressor has produced.
+ ///
+ /// Note that not all bytes may have been read yet, some may still be
+ /// buffered.
+ pub fn total_out(&self) -> u64 {
+ self.data.total_out()
+ }
+}
+
+impl<R: BufRead> Read for ZlibEncoder<R> {
+ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+ zio::read(&mut self.obj, &mut self.data, buf)
+ }
+}
+
+impl<R: BufRead + Write> Write for ZlibEncoder<R> {
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ self.get_mut().write(buf)
+ }
+
+ fn flush(&mut self) -> io::Result<()> {
+ self.get_mut().flush()
+ }
+}
+
+/// A ZLIB decoder, or decompressor.
+///
+/// This structure consumes a [`BufRead`] interface, reading compressed data
+/// from the underlying reader, and emitting uncompressed data.
+///
+/// [`BufRead`]: https://doc.rust-lang.org/std/io/trait.BufRead.html
+///
+/// # Examples
+///
+/// ```
+/// use std::io::prelude::*;
+/// use std::io;
+/// # use flate2::Compression;
+/// # use flate2::write::ZlibEncoder;
+/// use flate2::bufread::ZlibDecoder;
+///
+/// # fn main() {
+/// # let mut e = ZlibEncoder::new(Vec::new(), Compression::default());
+/// # e.write_all(b"Hello World").unwrap();
+/// # let bytes = e.finish().unwrap();
+/// # println!("{}", decode_bufreader(bytes).unwrap());
+/// # }
+/// #
+/// // Uncompresses a Zlib Encoded vector of bytes and returns a string or error
+/// // Here &[u8] implements BufRead
+///
+/// fn decode_bufreader(bytes: Vec<u8>) -> io::Result<String> {
+/// let mut z = ZlibDecoder::new(&bytes[..]);
+/// let mut s = String::new();
+/// z.read_to_string(&mut s)?;
+/// Ok(s)
+/// }
+/// ```
+#[derive(Debug)]
+pub struct ZlibDecoder<R> {
+ obj: R,
+ data: Decompress,
+}
+
+impl<R: BufRead> ZlibDecoder<R> {
+ /// Creates a new decoder which will decompress data read from the given
+ /// stream.
+ pub fn new(r: R) -> ZlibDecoder<R> {
+ ZlibDecoder {
+ obj: r,
+ data: Decompress::new(true),
+ }
+ }
+}
+
+pub fn reset_decoder_data<R>(zlib: &mut ZlibDecoder<R>) {
+ zlib.data = Decompress::new(true);
+}
+
+impl<R> ZlibDecoder<R> {
+ /// Resets the state of this decoder entirely, swapping out the input
+ /// stream for another.
+ ///
+ /// This will reset the internal state of this decoder and replace the
+ /// input stream with the one provided, returning the previous input
+ /// stream. Future data read from this decoder will be the decompressed
+ /// version of `r`'s data.
+ pub fn reset(&mut self, r: R) -> R {
+ reset_decoder_data(self);
+ mem::replace(&mut self.obj, r)
+ }
+
+ /// Acquires a reference to the underlying stream
+ pub fn get_ref(&self) -> &R {
+ &self.obj
+ }
+
+ /// Acquires a mutable reference to the underlying stream
+ ///
+ /// Note that mutation of the stream may result in surprising results if
+ /// this encoder is continued to be used.
+ pub fn get_mut(&mut self) -> &mut R {
+ &mut self.obj
+ }
+
+ /// Consumes this decoder, returning the underlying reader.
+ pub fn into_inner(self) -> R {
+ self.obj
+ }
+
+ /// Returns the number of bytes that the decompressor has consumed.
+ ///
+ /// Note that this will likely be smaller than what the decompressor
+ /// actually read from the underlying stream due to buffering.
+ pub fn total_in(&self) -> u64 {
+ self.data.total_in()
+ }
+
+ /// Returns the number of bytes that the decompressor has produced.
+ pub fn total_out(&self) -> u64 {
+ self.data.total_out()
+ }
+}
+
+impl<R: BufRead> Read for ZlibDecoder<R> {
+ fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
+ zio::read(&mut self.obj, &mut self.data, into)
+ }
+}
+
+impl<R: BufRead + Write> Write for ZlibDecoder<R> {
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ self.get_mut().write(buf)
+ }
+
+ fn flush(&mut self) -> io::Result<()> {
+ self.get_mut().flush()
+ }
+}
diff --git a/third_party/rust/flate2/src/zlib/mod.rs b/third_party/rust/flate2/src/zlib/mod.rs
new file mode 100644
index 0000000000..9d3de95c54
--- /dev/null
+++ b/third_party/rust/flate2/src/zlib/mod.rs
@@ -0,0 +1,159 @@
+pub mod bufread;
+pub mod read;
+pub mod write;
+
+#[cfg(test)]
+mod tests {
+ use std::io;
+ use std::io::prelude::*;
+
+ use rand::{thread_rng, Rng};
+
+ use crate::zlib::{read, write};
+ use crate::Compression;
+
+ #[test]
+ fn roundtrip() {
+ let mut real = Vec::new();
+ let mut w = write::ZlibEncoder::new(Vec::new(), Compression::default());
+ let v = crate::random_bytes().take(1024).collect::<Vec<_>>();
+ for _ in 0..200 {
+ let to_write = &v[..thread_rng().gen_range(0..v.len())];
+ real.extend(to_write.iter().map(|x| *x));
+ w.write_all(to_write).unwrap();
+ }
+ let result = w.finish().unwrap();
+ let mut r = read::ZlibDecoder::new(&result[..]);
+ let mut ret = Vec::new();
+ r.read_to_end(&mut ret).unwrap();
+ assert!(ret == real);
+ }
+
+ #[test]
+ fn drop_writes() {
+ let mut data = Vec::new();
+ write::ZlibEncoder::new(&mut data, Compression::default())
+ .write_all(b"foo")
+ .unwrap();
+ let mut r = read::ZlibDecoder::new(&data[..]);
+ let mut ret = Vec::new();
+ r.read_to_end(&mut ret).unwrap();
+ assert!(ret == b"foo");
+ }
+
+ #[test]
+ fn total_in() {
+ let mut real = Vec::new();
+ let mut w = write::ZlibEncoder::new(Vec::new(), Compression::default());
+ let v = crate::random_bytes().take(1024).collect::<Vec<_>>();
+ for _ in 0..200 {
+ let to_write = &v[..thread_rng().gen_range(0..v.len())];
+ real.extend(to_write.iter().map(|x| *x));
+ w.write_all(to_write).unwrap();
+ }
+ let mut result = w.finish().unwrap();
+
+ let result_len = result.len();
+
+ for _ in 0..200 {
+ result.extend(v.iter().map(|x| *x));
+ }
+
+ let mut r = read::ZlibDecoder::new(&result[..]);
+ let mut ret = Vec::new();
+ r.read_to_end(&mut ret).unwrap();
+ assert!(ret == real);
+ assert_eq!(r.total_in(), result_len as u64);
+ }
+
+ #[test]
+ fn roundtrip2() {
+ let v = crate::random_bytes().take(1024 * 1024).collect::<Vec<_>>();
+ let mut r = read::ZlibDecoder::new(read::ZlibEncoder::new(&v[..], Compression::default()));
+ let mut ret = Vec::new();
+ r.read_to_end(&mut ret).unwrap();
+ assert_eq!(ret, v);
+ }
+
+ #[test]
+ fn roundtrip3() {
+ let v = crate::random_bytes().take(1024 * 1024).collect::<Vec<_>>();
+ let mut w =
+ write::ZlibEncoder::new(write::ZlibDecoder::new(Vec::new()), Compression::default());
+ w.write_all(&v).unwrap();
+ let w = w.finish().unwrap().finish().unwrap();
+ assert!(w == v);
+ }
+
+ #[test]
+ fn reset_decoder() {
+ let v = crate::random_bytes().take(1024 * 1024).collect::<Vec<_>>();
+ let mut w = write::ZlibEncoder::new(Vec::new(), Compression::default());
+ w.write_all(&v).unwrap();
+ let data = w.finish().unwrap();
+
+ {
+ let (mut a, mut b, mut c) = (Vec::new(), Vec::new(), Vec::new());
+ let mut r = read::ZlibDecoder::new(&data[..]);
+ r.read_to_end(&mut a).unwrap();
+ r.reset(&data);
+ r.read_to_end(&mut b).unwrap();
+
+ let mut r = read::ZlibDecoder::new(&data[..]);
+ r.read_to_end(&mut c).unwrap();
+ assert!(a == b && b == c && c == v);
+ }
+
+ {
+ let mut w = write::ZlibDecoder::new(Vec::new());
+ w.write_all(&data).unwrap();
+ let a = w.reset(Vec::new()).unwrap();
+ w.write_all(&data).unwrap();
+ let b = w.finish().unwrap();
+
+ let mut w = write::ZlibDecoder::new(Vec::new());
+ w.write_all(&data).unwrap();
+ let c = w.finish().unwrap();
+ assert!(a == b && b == c && c == v);
+ }
+ }
+
+ #[test]
+ fn bad_input() {
+ // regress tests: previously caused a panic on drop
+ let mut out: Vec<u8> = Vec::new();
+ let data: Vec<u8> = (0..255).cycle().take(1024).collect();
+ let mut w = write::ZlibDecoder::new(&mut out);
+ match w.write_all(&data[..]) {
+ Ok(_) => panic!("Expected an error to be returned!"),
+ Err(e) => assert_eq!(e.kind(), io::ErrorKind::InvalidInput),
+ }
+ }
+
+ #[test]
+ fn qc_reader() {
+ ::quickcheck::quickcheck(test as fn(_) -> _);
+
+ fn test(v: Vec<u8>) -> bool {
+ let mut r =
+ read::ZlibDecoder::new(read::ZlibEncoder::new(&v[..], Compression::default()));
+ let mut v2 = Vec::new();
+ r.read_to_end(&mut v2).unwrap();
+ v == v2
+ }
+ }
+
+ #[test]
+ fn qc_writer() {
+ ::quickcheck::quickcheck(test as fn(_) -> _);
+
+ fn test(v: Vec<u8>) -> bool {
+ let mut w = write::ZlibEncoder::new(
+ write::ZlibDecoder::new(Vec::new()),
+ Compression::default(),
+ );
+ w.write_all(&v).unwrap();
+ v == w.finish().unwrap().finish().unwrap()
+ }
+ }
+}
diff --git a/third_party/rust/flate2/src/zlib/read.rs b/third_party/rust/flate2/src/zlib/read.rs
new file mode 100644
index 0000000000..5094931665
--- /dev/null
+++ b/third_party/rust/flate2/src/zlib/read.rs
@@ -0,0 +1,240 @@
+use std::io;
+use std::io::prelude::*;
+
+use super::bufread;
+use crate::bufreader::BufReader;
+
+/// A ZLIB encoder, or compressor.
+///
+/// This structure implements a [`Read`] interface and will read uncompressed
+/// data from an underlying stream and emit a stream of compressed data.
+///
+/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
+///
+/// # Examples
+///
+/// ```
+/// use std::io::prelude::*;
+/// use flate2::Compression;
+/// use flate2::read::ZlibEncoder;
+/// use std::fs::File;
+///
+/// // Open example file and compress the contents using Read interface
+///
+/// # fn open_hello_world() -> std::io::Result<Vec<u8>> {
+/// let f = File::open("examples/hello_world.txt")?;
+/// let mut z = ZlibEncoder::new(f, Compression::fast());
+/// let mut buffer = [0;50];
+/// let byte_count = z.read(&mut buffer)?;
+/// # Ok(buffer[0..byte_count].to_vec())
+/// # }
+/// ```
+#[derive(Debug)]
+pub struct ZlibEncoder<R> {
+ inner: bufread::ZlibEncoder<BufReader<R>>,
+}
+
+impl<R: Read> ZlibEncoder<R> {
+ /// Creates a new encoder which will read uncompressed data from the given
+ /// stream and emit the compressed stream.
+ pub fn new(r: R, level: crate::Compression) -> ZlibEncoder<R> {
+ ZlibEncoder {
+ inner: bufread::ZlibEncoder::new(BufReader::new(r), level),
+ }
+ }
+}
+
+impl<R> ZlibEncoder<R> {
+ /// Resets the state of this encoder entirely, swapping out the input
+ /// stream for another.
+ ///
+ /// This function will reset the internal state of this encoder and replace
+ /// the input stream with the one provided, returning the previous input
+ /// stream. Future data read from this encoder will be the compressed
+ /// version of `r`'s data.
+ ///
+ /// Note that there may be currently buffered data when this function is
+ /// called, and in that case the buffered data is discarded.
+ pub fn reset(&mut self, r: R) -> R {
+ super::bufread::reset_encoder_data(&mut self.inner);
+ self.inner.get_mut().reset(r)
+ }
+
+ /// Acquires a reference to the underlying stream
+ pub fn get_ref(&self) -> &R {
+ self.inner.get_ref().get_ref()
+ }
+
+ /// Acquires a mutable reference to the underlying stream
+ ///
+ /// Note that mutation of the stream may result in surprising results if
+ /// this encoder is continued to be used.
+ pub fn get_mut(&mut self) -> &mut R {
+ self.inner.get_mut().get_mut()
+ }
+
+ /// Consumes this encoder, returning the underlying reader.
+ ///
+ /// Note that there may be buffered bytes which are not re-acquired as part
+ /// of this transition. It's recommended to only call this function after
+ /// EOF has been reached.
+ pub fn into_inner(self) -> R {
+ self.inner.into_inner().into_inner()
+ }
+
+ /// Returns the number of bytes that have been read into this compressor.
+ ///
+ /// Note that not all bytes read from the underlying object may be accounted
+ /// for, there may still be some active buffering.
+ pub fn total_in(&self) -> u64 {
+ self.inner.total_in()
+ }
+
+ /// Returns the number of bytes that the compressor has produced.
+ ///
+ /// Note that not all bytes may have been read yet, some may still be
+ /// buffered.
+ pub fn total_out(&self) -> u64 {
+ self.inner.total_out()
+ }
+}
+
+impl<R: Read> Read for ZlibEncoder<R> {
+ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+ self.inner.read(buf)
+ }
+}
+
+impl<W: Read + Write> Write for ZlibEncoder<W> {
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ self.get_mut().write(buf)
+ }
+
+ fn flush(&mut self) -> io::Result<()> {
+ self.get_mut().flush()
+ }
+}
+
+/// A ZLIB decoder, or decompressor.
+///
+/// This structure implements a [`Read`] interface and takes a stream of
+/// compressed data as input, providing the decompressed data when read from.
+///
+/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
+///
+/// # Examples
+///
+/// ```
+/// use std::io::prelude::*;
+/// use std::io;
+/// # use flate2::Compression;
+/// # use flate2::write::ZlibEncoder;
+/// use flate2::read::ZlibDecoder;
+///
+/// # fn main() {
+/// # let mut e = ZlibEncoder::new(Vec::new(), Compression::default());
+/// # e.write_all(b"Hello World").unwrap();
+/// # let bytes = e.finish().unwrap();
+/// # println!("{}", decode_reader(bytes).unwrap());
+/// # }
+/// #
+/// // Uncompresses a Zlib Encoded vector of bytes and returns a string or error
+/// // Here &[u8] implements Read
+///
+/// fn decode_reader(bytes: Vec<u8>) -> io::Result<String> {
+/// let mut z = ZlibDecoder::new(&bytes[..]);
+/// let mut s = String::new();
+/// z.read_to_string(&mut s)?;
+/// Ok(s)
+/// }
+/// ```
+#[derive(Debug)]
+pub struct ZlibDecoder<R> {
+ inner: bufread::ZlibDecoder<BufReader<R>>,
+}
+
+impl<R: Read> ZlibDecoder<R> {
+ /// Creates a new decoder which will decompress data read from the given
+ /// stream.
+ pub fn new(r: R) -> ZlibDecoder<R> {
+ ZlibDecoder::new_with_buf(r, vec![0; 32 * 1024])
+ }
+
+ /// Same as `new`, but the intermediate buffer for data is specified.
+ ///
+ /// Note that the specified buffer will only be used up to its current
+ /// length. The buffer's capacity will also not grow over time.
+ pub fn new_with_buf(r: R, buf: Vec<u8>) -> ZlibDecoder<R> {
+ ZlibDecoder {
+ inner: bufread::ZlibDecoder::new(BufReader::with_buf(buf, r)),
+ }
+ }
+}
+
+impl<R> ZlibDecoder<R> {
+ /// Resets the state of this decoder entirely, swapping out the input
+ /// stream for another.
+ ///
+ /// This will reset the internal state of this decoder and replace the
+ /// input stream with the one provided, returning the previous input
+ /// stream. Future data read from this decoder will be the decompressed
+ /// version of `r`'s data.
+ ///
+ /// Note that there may be currently buffered data when this function is
+ /// called, and in that case the buffered data is discarded.
+ pub fn reset(&mut self, r: R) -> R {
+ super::bufread::reset_decoder_data(&mut self.inner);
+ self.inner.get_mut().reset(r)
+ }
+
+ /// Acquires a reference to the underlying stream
+ pub fn get_ref(&self) -> &R {
+ self.inner.get_ref().get_ref()
+ }
+
+ /// Acquires a mutable reference to the underlying stream
+ ///
+ /// Note that mutation of the stream may result in surprising results if
+ /// this encoder is continued to be used.
+ pub fn get_mut(&mut self) -> &mut R {
+ self.inner.get_mut().get_mut()
+ }
+
+ /// Consumes this decoder, returning the underlying reader.
+ ///
+ /// Note that there may be buffered bytes which are not re-acquired as part
+ /// of this transition. It's recommended to only call this function after
+ /// EOF has been reached.
+ pub fn into_inner(self) -> R {
+ self.inner.into_inner().into_inner()
+ }
+
+ /// Returns the number of bytes that the decompressor has consumed.
+ ///
+ /// Note that this will likely be smaller than what the decompressor
+ /// actually read from the underlying stream due to buffering.
+ pub fn total_in(&self) -> u64 {
+ self.inner.total_in()
+ }
+
+ /// Returns the number of bytes that the decompressor has produced.
+ pub fn total_out(&self) -> u64 {
+ self.inner.total_out()
+ }
+}
+
+impl<R: Read> Read for ZlibDecoder<R> {
+ fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
+ self.inner.read(into)
+ }
+}
+
+impl<R: Read + Write> Write for ZlibDecoder<R> {
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ self.get_mut().write(buf)
+ }
+
+ fn flush(&mut self) -> io::Result<()> {
+ self.get_mut().flush()
+ }
+}
diff --git a/third_party/rust/flate2/src/zlib/write.rs b/third_party/rust/flate2/src/zlib/write.rs
new file mode 100644
index 0000000000..c67181402b
--- /dev/null
+++ b/third_party/rust/flate2/src/zlib/write.rs
@@ -0,0 +1,321 @@
+use std::io;
+use std::io::prelude::*;
+
+use crate::zio;
+use crate::{Compress, Decompress};
+
+/// A ZLIB encoder, or compressor.
+///
+/// This structure implements a [`Write`] interface and takes a stream of
+/// uncompressed data, writing the compressed data to the wrapped writer.
+///
+/// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
+///
+/// # Examples
+///
+/// ```
+/// use std::io::prelude::*;
+/// use flate2::Compression;
+/// use flate2::write::ZlibEncoder;
+///
+/// // Vec<u8> implements Write, assigning the compressed bytes of sample string
+///
+/// # fn zlib_encoding() -> std::io::Result<()> {
+/// let mut e = ZlibEncoder::new(Vec::new(), Compression::default());
+/// e.write_all(b"Hello World")?;
+/// let compressed = e.finish()?;
+/// # Ok(())
+/// # }
+/// ```
+#[derive(Debug)]
+pub struct ZlibEncoder<W: Write> {
+ inner: zio::Writer<W, Compress>,
+}
+
+impl<W: Write> ZlibEncoder<W> {
+ /// Creates a new encoder which will write compressed data to the stream
+ /// given at the given compression level.
+ ///
+ /// When this encoder is dropped or unwrapped the final pieces of data will
+ /// be flushed.
+ pub fn new(w: W, level: crate::Compression) -> ZlibEncoder<W> {
+ ZlibEncoder {
+ inner: zio::Writer::new(w, Compress::new(level, true)),
+ }
+ }
+
+ /// Acquires a reference to the underlying writer.
+ pub fn get_ref(&self) -> &W {
+ self.inner.get_ref()
+ }
+
+ /// Acquires a mutable reference to the underlying writer.
+ ///
+ /// Note that mutating the output/input state of the stream may corrupt this
+ /// object, so care must be taken when using this method.
+ pub fn get_mut(&mut self) -> &mut W {
+ self.inner.get_mut()
+ }
+
+ /// Resets the state of this encoder entirely, swapping out the output
+ /// stream for another.
+ ///
+ /// This function will finish encoding the current stream into the current
+ /// output stream before swapping out the two output streams.
+ ///
+ /// After the current stream has been finished, this will reset the internal
+ /// state of this encoder and replace the output stream with the one
+ /// provided, returning the previous output stream. Future data written to
+ /// this encoder will be the compressed into the stream `w` provided.
+ ///
+ /// # Errors
+ ///
+ /// This function will perform I/O to complete this stream, and any I/O
+ /// errors which occur will be returned from this function.
+ pub fn reset(&mut self, w: W) -> io::Result<W> {
+ self.inner.finish()?;
+ self.inner.data.reset();
+ Ok(self.inner.replace(w))
+ }
+
+ /// Attempt to finish this output stream, writing out final chunks of data.
+ ///
+ /// Note that this function can only be used once data has finished being
+ /// written to the output stream. After this function is called then further
+ /// calls to `write` may result in a panic.
+ ///
+ /// # Panics
+ ///
+ /// Attempts to write data to this stream may result in a panic after this
+ /// function is called.
+ ///
+ /// # Errors
+ ///
+ /// This function will perform I/O to complete this stream, and any I/O
+ /// errors which occur will be returned from this function.
+ pub fn try_finish(&mut self) -> io::Result<()> {
+ self.inner.finish()
+ }
+
+ /// Consumes this encoder, flushing the output stream.
+ ///
+ /// This will flush the underlying data stream, close off the compressed
+ /// stream and, if successful, return the contained writer.
+ ///
+ /// Note that this function may not be suitable to call in a situation where
+ /// the underlying stream is an asynchronous I/O stream. To finish a stream
+ /// the `try_finish` (or `shutdown`) method should be used instead. To
+ /// re-acquire ownership of a stream it is safe to call this method after
+ /// `try_finish` or `shutdown` has returned `Ok`.
+ ///
+ /// # Errors
+ ///
+ /// This function will perform I/O to complete this stream, and any I/O
+ /// errors which occur will be returned from this function.
+ pub fn finish(mut self) -> io::Result<W> {
+ self.inner.finish()?;
+ Ok(self.inner.take_inner())
+ }
+
+ /// Consumes this encoder, flushing the output stream.
+ ///
+ /// This will flush the underlying data stream and then return the contained
+ /// writer if the flush succeeded.
+ /// The compressed stream will not closed but only flushed. This
+ /// means that obtained byte array can by extended by another deflated
+ /// stream. To close the stream add the two bytes 0x3 and 0x0.
+ ///
+ /// # Errors
+ ///
+ /// This function will perform I/O to complete this stream, and any I/O
+ /// errors which occur will be returned from this function.
+ pub fn flush_finish(mut self) -> io::Result<W> {
+ self.inner.flush()?;
+ Ok(self.inner.take_inner())
+ }
+
+ /// Returns the number of bytes that have been written to this compressor.
+ ///
+ /// Note that not all bytes written to this object may be accounted for,
+ /// there may still be some active buffering.
+ pub fn total_in(&self) -> u64 {
+ self.inner.data.total_in()
+ }
+
+ /// Returns the number of bytes that the compressor has produced.
+ ///
+ /// Note that not all bytes may have been written yet, some may still be
+ /// buffered.
+ pub fn total_out(&self) -> u64 {
+ self.inner.data.total_out()
+ }
+}
+
+impl<W: Write> Write for ZlibEncoder<W> {
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ self.inner.write(buf)
+ }
+
+ fn flush(&mut self) -> io::Result<()> {
+ self.inner.flush()
+ }
+}
+
+impl<W: Read + Write> Read for ZlibEncoder<W> {
+ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+ self.get_mut().read(buf)
+ }
+}
+
+/// A ZLIB decoder, or decompressor.
+///
+/// This structure implements a [`Write`] and will emit a stream of decompressed
+/// data when fed a stream of compressed data.
+///
+/// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
+///
+/// # Examples
+///
+/// ```
+/// use std::io::prelude::*;
+/// use std::io;
+/// # use flate2::Compression;
+/// # use flate2::write::ZlibEncoder;
+/// use flate2::write::ZlibDecoder;
+///
+/// # fn main() {
+/// # let mut e = ZlibEncoder::new(Vec::new(), Compression::default());
+/// # e.write_all(b"Hello World").unwrap();
+/// # let bytes = e.finish().unwrap();
+/// # println!("{}", decode_reader(bytes).unwrap());
+/// # }
+/// #
+/// // Uncompresses a Zlib Encoded vector of bytes and returns a string or error
+/// // Here Vec<u8> implements Write
+///
+/// fn decode_reader(bytes: Vec<u8>) -> io::Result<String> {
+/// let mut writer = Vec::new();
+/// let mut z = ZlibDecoder::new(writer);
+/// z.write_all(&bytes[..])?;
+/// writer = z.finish()?;
+/// let return_string = String::from_utf8(writer).expect("String parsing error");
+/// Ok(return_string)
+/// }
+/// ```
+#[derive(Debug)]
+pub struct ZlibDecoder<W: Write> {
+ inner: zio::Writer<W, Decompress>,
+}
+
+impl<W: Write> ZlibDecoder<W> {
+ /// Creates a new decoder which will write uncompressed data to the stream.
+ ///
+ /// When this decoder is dropped or unwrapped the final pieces of data will
+ /// be flushed.
+ pub fn new(w: W) -> ZlibDecoder<W> {
+ ZlibDecoder {
+ inner: zio::Writer::new(w, Decompress::new(true)),
+ }
+ }
+
+ /// Acquires a reference to the underlying writer.
+ pub fn get_ref(&self) -> &W {
+ self.inner.get_ref()
+ }
+
+ /// Acquires a mutable reference to the underlying writer.
+ ///
+ /// Note that mutating the output/input state of the stream may corrupt this
+ /// object, so care must be taken when using this method.
+ pub fn get_mut(&mut self) -> &mut W {
+ self.inner.get_mut()
+ }
+
+ /// Resets the state of this decoder entirely, swapping out the output
+ /// stream for another.
+ ///
+ /// This will reset the internal state of this decoder and replace the
+ /// output stream with the one provided, returning the previous output
+ /// stream. Future data written to this decoder will be decompressed into
+ /// the output stream `w`.
+ ///
+ /// # Errors
+ ///
+ /// This function will perform I/O to complete this stream, and any I/O
+ /// errors which occur will be returned from this function.
+ pub fn reset(&mut self, w: W) -> io::Result<W> {
+ self.inner.finish()?;
+ self.inner.data = Decompress::new(true);
+ Ok(self.inner.replace(w))
+ }
+
+ /// Attempt to finish this output stream, writing out final chunks of data.
+ ///
+ /// Note that this function can only be used once data has finished being
+ /// written to the output stream. After this function is called then further
+ /// calls to `write` may result in a panic.
+ ///
+ /// # Panics
+ ///
+ /// Attempts to write data to this stream may result in a panic after this
+ /// function is called.
+ ///
+ /// # Errors
+ ///
+ /// This function will perform I/O to complete this stream, and any I/O
+ /// errors which occur will be returned from this function.
+ pub fn try_finish(&mut self) -> io::Result<()> {
+ self.inner.finish()
+ }
+
+ /// Consumes this encoder, flushing the output stream.
+ ///
+ /// This will flush the underlying data stream and then return the contained
+ /// writer if the flush succeeded.
+ ///
+ /// Note that this function may not be suitable to call in a situation where
+ /// the underlying stream is an asynchronous I/O stream. To finish a stream
+ /// the `try_finish` (or `shutdown`) method should be used instead. To
+ /// re-acquire ownership of a stream it is safe to call this method after
+ /// `try_finish` or `shutdown` has returned `Ok`.
+ ///
+ /// # Errors
+ ///
+ /// This function will perform I/O to complete this stream, and any I/O
+ /// errors which occur will be returned from this function.
+ pub fn finish(mut self) -> io::Result<W> {
+ self.inner.finish()?;
+ Ok(self.inner.take_inner())
+ }
+
+ /// Returns the number of bytes that the decompressor has consumed for
+ /// decompression.
+ ///
+ /// Note that this will likely be smaller than the number of bytes
+ /// successfully written to this stream due to internal buffering.
+ pub fn total_in(&self) -> u64 {
+ self.inner.data.total_in()
+ }
+
+ /// Returns the number of bytes that the decompressor has written to its
+ /// output stream.
+ pub fn total_out(&self) -> u64 {
+ self.inner.data.total_out()
+ }
+}
+
+impl<W: Write> Write for ZlibDecoder<W> {
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ self.inner.write(buf)
+ }
+
+ fn flush(&mut self) -> io::Result<()> {
+ self.inner.flush()
+ }
+}
+
+impl<W: Read + Write> Read for ZlibDecoder<W> {
+ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+ self.inner.get_mut().read(buf)
+ }
+}