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