1 use std::io; 2 use std::io::prelude::*; 3 4 use crate::zio; 5 use crate::{Compress, Decompress}; 6 7 /// A ZLIB encoder, or compressor. 8 /// 9 /// This structure implements a [`Write`] interface and takes a stream of 10 /// uncompressed data, writing the compressed data to the wrapped writer. 11 /// 12 /// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html 13 /// 14 /// # Examples 15 /// 16 /// ``` 17 /// use std::io::prelude::*; 18 /// use flate2::Compression; 19 /// use flate2::write::ZlibEncoder; 20 /// 21 /// // Vec<u8> implements Write, assigning the compressed bytes of sample string 22 /// 23 /// # fn zlib_encoding() -> std::io::Result<()> { 24 /// let mut e = ZlibEncoder::new(Vec::new(), Compression::default()); 25 /// e.write_all(b"Hello World")?; 26 /// let compressed = e.finish()?; 27 /// # Ok(()) 28 /// # } 29 /// ``` 30 #[derive(Debug)] 31 pub struct ZlibEncoder<W: Write> { 32 inner: zio::Writer<W, Compress>, 33 } 34 35 impl<W: Write> ZlibEncoder<W> { 36 /// Creates a new encoder which will write compressed data to the stream 37 /// given at the given compression level. 38 /// 39 /// When this encoder is dropped or unwrapped the final pieces of data will 40 /// be flushed. new(w: W, level: crate::Compression) -> ZlibEncoder<W>41 pub fn new(w: W, level: crate::Compression) -> ZlibEncoder<W> { 42 ZlibEncoder { 43 inner: zio::Writer::new(w, Compress::new(level, true)), 44 } 45 } 46 47 /// Creates a new encoder which will write compressed data to the stream 48 /// `w` with the given `compression` settings. new_with_compress(w: W, compression: Compress) -> ZlibEncoder<W>49 pub fn new_with_compress(w: W, compression: Compress) -> ZlibEncoder<W> { 50 ZlibEncoder { 51 inner: zio::Writer::new(w, compression), 52 } 53 } 54 55 /// Acquires a reference to the underlying writer. get_ref(&self) -> &W56 pub fn get_ref(&self) -> &W { 57 self.inner.get_ref() 58 } 59 60 /// Acquires a mutable reference to the underlying writer. 61 /// 62 /// Note that mutating the output/input state of the stream may corrupt this 63 /// object, so care must be taken when using this method. get_mut(&mut self) -> &mut W64 pub fn get_mut(&mut self) -> &mut W { 65 self.inner.get_mut() 66 } 67 68 /// Resets the state of this encoder entirely, swapping out the output 69 /// stream for another. 70 /// 71 /// This function will finish encoding the current stream into the current 72 /// output stream before swapping out the two output streams. 73 /// 74 /// After the current stream has been finished, this will reset the internal 75 /// state of this encoder and replace the output stream with the one 76 /// provided, returning the previous output stream. Future data written to 77 /// this encoder will be the compressed into the stream `w` provided. 78 /// 79 /// # Errors 80 /// 81 /// This function will perform I/O to complete this stream, and any I/O 82 /// errors which occur will be returned from this function. reset(&mut self, w: W) -> io::Result<W>83 pub fn reset(&mut self, w: W) -> io::Result<W> { 84 self.inner.finish()?; 85 self.inner.data.reset(); 86 Ok(self.inner.replace(w)) 87 } 88 89 /// Attempt to finish this output stream, writing out final chunks of data. 90 /// 91 /// Note that this function can only be used once data has finished being 92 /// written to the output stream. After this function is called then further 93 /// calls to `write` may result in a panic. 94 /// 95 /// # Panics 96 /// 97 /// Attempts to write data to this stream may result in a panic after this 98 /// function is called. 99 /// 100 /// # Errors 101 /// 102 /// This function will perform I/O to complete this stream, and any I/O 103 /// errors which occur will be returned from this function. try_finish(&mut self) -> io::Result<()>104 pub fn try_finish(&mut self) -> io::Result<()> { 105 self.inner.finish() 106 } 107 108 /// Consumes this encoder, flushing the output stream. 109 /// 110 /// This will flush the underlying data stream, close off the compressed 111 /// stream and, if successful, return the contained writer. 112 /// 113 /// Note that this function may not be suitable to call in a situation where 114 /// the underlying stream is an asynchronous I/O stream. To finish a stream 115 /// the `try_finish` (or `shutdown`) method should be used instead. To 116 /// re-acquire ownership of a stream it is safe to call this method after 117 /// `try_finish` or `shutdown` has returned `Ok`. 118 /// 119 /// # Errors 120 /// 121 /// This function will perform I/O to complete this stream, and any I/O 122 /// errors which occur will be returned from this function. finish(mut self) -> io::Result<W>123 pub fn finish(mut self) -> io::Result<W> { 124 self.inner.finish()?; 125 Ok(self.inner.take_inner()) 126 } 127 128 /// Consumes this encoder, flushing the output stream. 129 /// 130 /// This will flush the underlying data stream and then return the contained 131 /// writer if the flush succeeded. 132 /// The compressed stream will not closed but only flushed. This 133 /// means that obtained byte array can by extended by another deflated 134 /// stream. To close the stream add the two bytes 0x3 and 0x0. 135 /// 136 /// # Errors 137 /// 138 /// This function will perform I/O to complete this stream, and any I/O 139 /// errors which occur will be returned from this function. flush_finish(mut self) -> io::Result<W>140 pub fn flush_finish(mut self) -> io::Result<W> { 141 self.inner.flush()?; 142 Ok(self.inner.take_inner()) 143 } 144 145 /// Returns the number of bytes that have been written to this compressor. 146 /// 147 /// Note that not all bytes written to this object may be accounted for, 148 /// there may still be some active buffering. total_in(&self) -> u64149 pub fn total_in(&self) -> u64 { 150 self.inner.data.total_in() 151 } 152 153 /// Returns the number of bytes that the compressor has produced. 154 /// 155 /// Note that not all bytes may have been written yet, some may still be 156 /// buffered. total_out(&self) -> u64157 pub fn total_out(&self) -> u64 { 158 self.inner.data.total_out() 159 } 160 } 161 162 impl<W: Write> Write for ZlibEncoder<W> { write(&mut self, buf: &[u8]) -> io::Result<usize>163 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 164 self.inner.write(buf) 165 } 166 flush(&mut self) -> io::Result<()>167 fn flush(&mut self) -> io::Result<()> { 168 self.inner.flush() 169 } 170 } 171 172 impl<W: Read + Write> Read for ZlibEncoder<W> { read(&mut self, buf: &mut [u8]) -> io::Result<usize>173 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { 174 self.get_mut().read(buf) 175 } 176 } 177 178 /// A ZLIB decoder, or decompressor. 179 /// 180 /// This structure implements a [`Write`] and will emit a stream of decompressed 181 /// data when fed a stream of compressed data. 182 /// 183 /// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html 184 /// 185 /// # Examples 186 /// 187 /// ``` 188 /// use std::io::prelude::*; 189 /// use std::io; 190 /// # use flate2::Compression; 191 /// # use flate2::write::ZlibEncoder; 192 /// use flate2::write::ZlibDecoder; 193 /// 194 /// # fn main() { 195 /// # let mut e = ZlibEncoder::new(Vec::new(), Compression::default()); 196 /// # e.write_all(b"Hello World").unwrap(); 197 /// # let bytes = e.finish().unwrap(); 198 /// # println!("{}", decode_reader(bytes).unwrap()); 199 /// # } 200 /// # 201 /// // Uncompresses a Zlib Encoded vector of bytes and returns a string or error 202 /// // Here Vec<u8> implements Write 203 /// 204 /// fn decode_reader(bytes: Vec<u8>) -> io::Result<String> { 205 /// let mut writer = Vec::new(); 206 /// let mut z = ZlibDecoder::new(writer); 207 /// z.write_all(&bytes[..])?; 208 /// writer = z.finish()?; 209 /// let return_string = String::from_utf8(writer).expect("String parsing error"); 210 /// Ok(return_string) 211 /// } 212 /// ``` 213 #[derive(Debug)] 214 pub struct ZlibDecoder<W: Write> { 215 inner: zio::Writer<W, Decompress>, 216 } 217 218 impl<W: Write> ZlibDecoder<W> { 219 /// Creates a new decoder which will write uncompressed data to the stream. 220 /// 221 /// When this decoder is dropped or unwrapped the final pieces of data will 222 /// be flushed. new(w: W) -> ZlibDecoder<W>223 pub fn new(w: W) -> ZlibDecoder<W> { 224 ZlibDecoder { 225 inner: zio::Writer::new(w, Decompress::new(true)), 226 } 227 } 228 229 /// Creates a new decoder which will write uncompressed data to the stream `w` 230 /// using the given `decompression` settings. 231 /// 232 /// When this decoder is dropped or unwrapped the final pieces of data will 233 /// be flushed. new_with_decompress(w: W, decompression: Decompress) -> ZlibDecoder<W>234 pub fn new_with_decompress(w: W, decompression: Decompress) -> ZlibDecoder<W> { 235 ZlibDecoder { 236 inner: zio::Writer::new(w, decompression), 237 } 238 } 239 240 /// Acquires a reference to the underlying writer. get_ref(&self) -> &W241 pub fn get_ref(&self) -> &W { 242 self.inner.get_ref() 243 } 244 245 /// Acquires a mutable reference to the underlying writer. 246 /// 247 /// Note that mutating the output/input state of the stream may corrupt this 248 /// object, so care must be taken when using this method. get_mut(&mut self) -> &mut W249 pub fn get_mut(&mut self) -> &mut W { 250 self.inner.get_mut() 251 } 252 253 /// Resets the state of this decoder entirely, swapping out the output 254 /// stream for another. 255 /// 256 /// This will reset the internal state of this decoder and replace the 257 /// output stream with the one provided, returning the previous output 258 /// stream. Future data written to this decoder will be decompressed into 259 /// the output stream `w`. 260 /// 261 /// # Errors 262 /// 263 /// This function will perform I/O to complete this stream, and any I/O 264 /// errors which occur will be returned from this function. reset(&mut self, w: W) -> io::Result<W>265 pub fn reset(&mut self, w: W) -> io::Result<W> { 266 self.inner.finish()?; 267 self.inner.data = Decompress::new(true); 268 Ok(self.inner.replace(w)) 269 } 270 271 /// Attempt to finish this output stream, writing out final chunks of data. 272 /// 273 /// Note that this function can only be used once data has finished being 274 /// written to the output stream. After this function is called then further 275 /// calls to `write` may result in a panic. 276 /// 277 /// # Panics 278 /// 279 /// Attempts to write data to this stream may result in a panic after this 280 /// function is called. 281 /// 282 /// # Errors 283 /// 284 /// This function will perform I/O to complete this stream, and any I/O 285 /// errors which occur will be returned from this function. try_finish(&mut self) -> io::Result<()>286 pub fn try_finish(&mut self) -> io::Result<()> { 287 self.inner.finish() 288 } 289 290 /// Consumes this encoder, flushing the output stream. 291 /// 292 /// This will flush the underlying data stream and then return the contained 293 /// writer if the flush succeeded. 294 /// 295 /// Note that this function may not be suitable to call in a situation where 296 /// the underlying stream is an asynchronous I/O stream. To finish a stream 297 /// the `try_finish` (or `shutdown`) method should be used instead. To 298 /// re-acquire ownership of a stream it is safe to call this method after 299 /// `try_finish` or `shutdown` has returned `Ok`. 300 /// 301 /// # Errors 302 /// 303 /// This function will perform I/O to complete this stream, and any I/O 304 /// errors which occur will be returned from this function. finish(mut self) -> io::Result<W>305 pub fn finish(mut self) -> io::Result<W> { 306 self.inner.finish()?; 307 Ok(self.inner.take_inner()) 308 } 309 310 /// Returns the number of bytes that the decompressor has consumed for 311 /// decompression. 312 /// 313 /// Note that this will likely be smaller than the number of bytes 314 /// successfully written to this stream due to internal buffering. total_in(&self) -> u64315 pub fn total_in(&self) -> u64 { 316 self.inner.data.total_in() 317 } 318 319 /// Returns the number of bytes that the decompressor has written to its 320 /// output stream. total_out(&self) -> u64321 pub fn total_out(&self) -> u64 { 322 self.inner.data.total_out() 323 } 324 } 325 326 impl<W: Write> Write for ZlibDecoder<W> { write(&mut self, buf: &[u8]) -> io::Result<usize>327 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 328 self.inner.write(buf) 329 } 330 flush(&mut self) -> io::Result<()>331 fn flush(&mut self) -> io::Result<()> { 332 self.inner.flush() 333 } 334 } 335 336 impl<W: Read + Write> Read for ZlibDecoder<W> { read(&mut self, buf: &mut [u8]) -> io::Result<usize>337 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { 338 self.inner.get_mut().read(buf) 339 } 340 } 341