1 use std::io; 2 use std::io::prelude::*; 3 4 use super::bufread; 5 use crate::bufreader::BufReader; 6 use crate::Decompress; 7 8 /// A ZLIB encoder, or compressor. 9 /// 10 /// This structure implements a [`Read`] interface. When read from, it reads 11 /// uncompressed data from the underlying [`Read`] and provides the compressed data. 12 /// 13 /// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html 14 /// 15 /// # Examples 16 /// 17 /// ``` 18 /// use std::io::prelude::*; 19 /// use flate2::Compression; 20 /// use flate2::read::ZlibEncoder; 21 /// use std::fs::File; 22 /// 23 /// // Open example file and compress the contents using Read interface 24 /// 25 /// # fn open_hello_world() -> std::io::Result<Vec<u8>> { 26 /// let f = File::open("examples/hello_world.txt")?; 27 /// let mut z = ZlibEncoder::new(f, Compression::fast()); 28 /// let mut buffer = Vec::new(); 29 /// z.read_to_end(&mut buffer)?; 30 /// # Ok(buffer) 31 /// # } 32 /// ``` 33 #[derive(Debug)] 34 pub struct ZlibEncoder<R> { 35 inner: bufread::ZlibEncoder<BufReader<R>>, 36 } 37 38 impl<R: Read> ZlibEncoder<R> { 39 /// Creates a new encoder which will read uncompressed data from the given 40 /// stream and emit the compressed stream. new(r: R, level: crate::Compression) -> ZlibEncoder<R>41 pub fn new(r: R, level: crate::Compression) -> ZlibEncoder<R> { 42 ZlibEncoder { 43 inner: bufread::ZlibEncoder::new(BufReader::new(r), level), 44 } 45 } 46 47 /// Creates a new encoder with the given `compression` settings which will 48 /// read uncompressed data from the given stream `r` and emit the compressed stream. new_with_compress(r: R, compression: crate::Compress) -> ZlibEncoder<R>49 pub fn new_with_compress(r: R, compression: crate::Compress) -> ZlibEncoder<R> { 50 ZlibEncoder { 51 inner: bufread::ZlibEncoder::new_with_compress(BufReader::new(r), compression), 52 } 53 } 54 } 55 56 impl<R> ZlibEncoder<R> { 57 /// Resets the state of this encoder entirely, swapping out the input 58 /// stream for another. 59 /// 60 /// This function will reset the internal state of this encoder and replace 61 /// the input stream with the one provided, returning the previous input 62 /// stream. Future data read from this encoder will be the compressed 63 /// version of `r`'s data. 64 /// 65 /// Note that there may be currently buffered data when this function is 66 /// called, and in that case the buffered data is discarded. reset(&mut self, r: R) -> R67 pub fn reset(&mut self, r: R) -> R { 68 super::bufread::reset_encoder_data(&mut self.inner); 69 self.inner.get_mut().reset(r) 70 } 71 72 /// Acquires a reference to the underlying stream get_ref(&self) -> &R73 pub fn get_ref(&self) -> &R { 74 self.inner.get_ref().get_ref() 75 } 76 77 /// Acquires a mutable reference to the underlying stream 78 /// 79 /// Note that mutation of the stream may result in surprising results if 80 /// this encoder is continued to be used. get_mut(&mut self) -> &mut R81 pub fn get_mut(&mut self) -> &mut R { 82 self.inner.get_mut().get_mut() 83 } 84 85 /// Consumes this encoder, returning the underlying reader. 86 /// 87 /// Note that there may be buffered bytes which are not re-acquired as part 88 /// of this transition. It's recommended to only call this function after 89 /// EOF has been reached. into_inner(self) -> R90 pub fn into_inner(self) -> R { 91 self.inner.into_inner().into_inner() 92 } 93 94 /// Returns the number of bytes that have been read into this compressor. 95 /// 96 /// Note that not all bytes read from the underlying object may be accounted 97 /// for, there may still be some active buffering. total_in(&self) -> u6498 pub fn total_in(&self) -> u64 { 99 self.inner.total_in() 100 } 101 102 /// Returns the number of bytes that the compressor has produced. 103 /// 104 /// Note that not all bytes may have been read yet, some may still be 105 /// buffered. total_out(&self) -> u64106 pub fn total_out(&self) -> u64 { 107 self.inner.total_out() 108 } 109 } 110 111 impl<R: Read> Read for ZlibEncoder<R> { read(&mut self, buf: &mut [u8]) -> io::Result<usize>112 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { 113 self.inner.read(buf) 114 } 115 } 116 117 impl<W: Read + Write> Write for ZlibEncoder<W> { write(&mut self, buf: &[u8]) -> io::Result<usize>118 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 119 self.get_mut().write(buf) 120 } 121 flush(&mut self) -> io::Result<()>122 fn flush(&mut self) -> io::Result<()> { 123 self.get_mut().flush() 124 } 125 } 126 127 /// A ZLIB decoder, or decompressor. 128 /// 129 /// This structure implements a [`Read`] interface. When read from, it reads 130 /// compressed data from the underlying [`Read`] and provides the uncompressed data. 131 /// 132 /// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html 133 /// 134 /// # Examples 135 /// 136 /// ``` 137 /// use std::io::prelude::*; 138 /// use std::io; 139 /// # use flate2::Compression; 140 /// # use flate2::write::ZlibEncoder; 141 /// use flate2::read::ZlibDecoder; 142 /// 143 /// # fn main() { 144 /// # let mut e = ZlibEncoder::new(Vec::new(), Compression::default()); 145 /// # e.write_all(b"Hello World").unwrap(); 146 /// # let bytes = e.finish().unwrap(); 147 /// # println!("{}", decode_reader(bytes).unwrap()); 148 /// # } 149 /// # 150 /// // Uncompresses a Zlib Encoded vector of bytes and returns a string or error 151 /// // Here &[u8] implements Read 152 /// 153 /// fn decode_reader(bytes: Vec<u8>) -> io::Result<String> { 154 /// let mut z = ZlibDecoder::new(&bytes[..]); 155 /// let mut s = String::new(); 156 /// z.read_to_string(&mut s)?; 157 /// Ok(s) 158 /// } 159 /// ``` 160 #[derive(Debug)] 161 pub struct ZlibDecoder<R> { 162 inner: bufread::ZlibDecoder<BufReader<R>>, 163 } 164 165 impl<R: Read> ZlibDecoder<R> { 166 /// Creates a new decoder which will decompress data read from the given 167 /// stream. new(r: R) -> ZlibDecoder<R>168 pub fn new(r: R) -> ZlibDecoder<R> { 169 ZlibDecoder::new_with_buf(r, vec![0; 32 * 1024]) 170 } 171 172 /// Creates a new decoder which will decompress data read from the given 173 /// stream `r`, using `buf` as backing to speed up reading. 174 /// 175 /// Note that the specified buffer will only be used up to its current 176 /// length. The buffer's capacity will also not grow over time. new_with_buf(r: R, buf: Vec<u8>) -> ZlibDecoder<R>177 pub fn new_with_buf(r: R, buf: Vec<u8>) -> ZlibDecoder<R> { 178 ZlibDecoder { 179 inner: bufread::ZlibDecoder::new(BufReader::with_buf(buf, r)), 180 } 181 } 182 183 /// Creates a new decoder which will decompress data read from the given 184 /// stream `r`, along with `decompression` settings. new_with_decompress(r: R, decompression: Decompress) -> ZlibDecoder<R>185 pub fn new_with_decompress(r: R, decompression: Decompress) -> ZlibDecoder<R> { 186 ZlibDecoder::new_with_decompress_and_buf(r, vec![0; 32 * 1024], decompression) 187 } 188 189 /// Creates a new decoder which will decompress data read from the given 190 /// stream `r`, using `buf` as backing to speed up reading, 191 /// along with `decompression` settings to configure decoder. 192 /// 193 /// Note that the specified buffer will only be used up to its current 194 /// length. The buffer's capacity will also not grow over time. new_with_decompress_and_buf( r: R, buf: Vec<u8>, decompression: Decompress, ) -> ZlibDecoder<R>195 pub fn new_with_decompress_and_buf( 196 r: R, 197 buf: Vec<u8>, 198 decompression: Decompress, 199 ) -> ZlibDecoder<R> { 200 ZlibDecoder { 201 inner: bufread::ZlibDecoder::new_with_decompress( 202 BufReader::with_buf(buf, r), 203 decompression, 204 ), 205 } 206 } 207 } 208 209 impl<R> ZlibDecoder<R> { 210 /// Resets the state of this decoder entirely, swapping out the input 211 /// stream for another. 212 /// 213 /// This will reset the internal state of this decoder and replace the 214 /// input stream with the one provided, returning the previous input 215 /// stream. Future data read from this decoder will be the decompressed 216 /// version of `r`'s data. 217 /// 218 /// Note that there may be currently buffered data when this function is 219 /// called, and in that case the buffered data is discarded. reset(&mut self, r: R) -> R220 pub fn reset(&mut self, r: R) -> R { 221 super::bufread::reset_decoder_data(&mut self.inner); 222 self.inner.get_mut().reset(r) 223 } 224 225 /// Acquires a reference to the underlying stream get_ref(&self) -> &R226 pub fn get_ref(&self) -> &R { 227 self.inner.get_ref().get_ref() 228 } 229 230 /// Acquires a mutable reference to the underlying stream 231 /// 232 /// Note that mutation of the stream may result in surprising results if 233 /// this decoder is continued to be used. get_mut(&mut self) -> &mut R234 pub fn get_mut(&mut self) -> &mut R { 235 self.inner.get_mut().get_mut() 236 } 237 238 /// Consumes this decoder, returning the underlying reader. 239 /// 240 /// Note that there may be buffered bytes which are not re-acquired as part 241 /// of this transition. It's recommended to only call this function after 242 /// EOF has been reached. into_inner(self) -> R243 pub fn into_inner(self) -> R { 244 self.inner.into_inner().into_inner() 245 } 246 247 /// Returns the number of bytes that the decompressor has consumed. 248 /// 249 /// Note that this will likely be smaller than what the decompressor 250 /// actually read from the underlying stream due to buffering. total_in(&self) -> u64251 pub fn total_in(&self) -> u64 { 252 self.inner.total_in() 253 } 254 255 /// Returns the number of bytes that the decompressor has produced. total_out(&self) -> u64256 pub fn total_out(&self) -> u64 { 257 self.inner.total_out() 258 } 259 } 260 261 impl<R: Read> Read for ZlibDecoder<R> { read(&mut self, into: &mut [u8]) -> io::Result<usize>262 fn read(&mut self, into: &mut [u8]) -> io::Result<usize> { 263 self.inner.read(into) 264 } 265 } 266 267 impl<R: Read + Write> Write for ZlibDecoder<R> { write(&mut self, buf: &[u8]) -> io::Result<usize>268 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 269 self.get_mut().write(buf) 270 } 271 flush(&mut self) -> io::Result<()>272 fn flush(&mut self) -> io::Result<()> { 273 self.get_mut().flush() 274 } 275 } 276