diff --git a/src/gz/write.rs b/src/gz/write.rs index 00f85bc47..8ff4e5120 100644 --- a/src/gz/write.rs +++ b/src/gz/write.rs @@ -209,7 +209,7 @@ impl Drop for GzEncoder { /// fn decode_writer(bytes: Vec) -> io::Result { /// let mut writer = Vec::new(); /// let mut decoder = GzDecoder::new(writer); -/// decoder.write(&bytes[..])?; +/// decoder.write_all(&bytes[..])?; /// writer = decoder.finish()?; /// let return_string = String::from_utf8(writer).expect("String parsing error"); /// Ok(return_string) @@ -320,20 +320,6 @@ impl GzDecoder { } Ok(()) } - - fn write_buf(&mut self, buf: &[u8]) -> io::Result { - let (n, status) = self.inner.write_with_status(buf)?; - - if status == Status::StreamEnd { - if n < buf.len() && self.crc_bytes.len() < 8 { - let remaining = buf.len() - n; - let crc_bytes = cmp::min(remaining, CRC_BYTES_LEN - self.crc_bytes.len()); - self.crc_bytes.extend(&buf[n..n + crc_bytes]); - return Ok(n + crc_bytes); - } - } - Ok(n) - } } struct Wrapper<'a> { @@ -376,11 +362,7 @@ impl Write for GzDecoder { fn write(&mut self, buf: &[u8]) -> io::Result { if self.header.is_none() { // trying to avoid buffer usage - let (res, pos) = if self.header_buf.is_empty() { - let mut cur = io::Cursor::new(buf); - let res = read_gz_header(&mut cur); - (res, cur.position() as usize) - } else { + let (res, pos) = { let mut wrp = Wrapper { buf: buf, header_buf: &mut self.header_buf, @@ -403,12 +385,21 @@ impl Write for GzDecoder { Ok(header) => { self.header = Some(header); self.header_buf.truncate(0); - let n = self.write_buf(&buf[pos..])?; - Ok(n + pos) + Ok(pos) } } } else { - self.write_buf(buf) + let (n, status) = self.inner.write_with_status(buf)?; + + if status == Status::StreamEnd { + if n < buf.len() && self.crc_bytes.len() < 8 { + let remaining = buf.len() - n; + let crc_bytes = cmp::min(remaining, CRC_BYTES_LEN - self.crc_bytes.len()); + self.crc_bytes.extend(&buf[n..n + crc_bytes]); + return Ok(n + crc_bytes); + } + } + Ok(n) } } @@ -452,7 +443,8 @@ mod tests { let mut writer = Vec::new(); let mut decoder = GzDecoder::new(writer); - decoder.write(&bytes[..]).unwrap(); + let n = decoder.write(&bytes[..]).unwrap(); + decoder.write(&bytes[n..]).unwrap(); decoder.try_finish().unwrap(); writer = decoder.finish().unwrap(); let return_string = String::from_utf8(writer).expect("String parsing error"); @@ -468,7 +460,10 @@ mod tests { let mut writer = Vec::new(); let mut decoder = GzDecoder::new(writer); assert_eq!(decoder.write(&bytes[..5]).unwrap(), 5); - decoder.write(&bytes[5..]).unwrap(); + let n = decoder.write(&bytes[5..]).unwrap(); + if n < bytes.len() - 5 { + decoder.write(&bytes[n + 5..]).unwrap(); + } writer = decoder.finish().unwrap(); let return_string = String::from_utf8(writer).expect("String parsing error"); assert_eq!(return_string, STR); @@ -498,8 +493,8 @@ mod tests { let mut writer = Vec::new(); let mut decoder = GzDecoder::new(writer); let l = bytes.len() - 5; - decoder.write(&bytes[..l]).unwrap(); - decoder.write(&bytes[l..]).unwrap(); + let n = decoder.write(&bytes[..l]).unwrap(); + decoder.write(&bytes[n..]).unwrap(); writer = decoder.finish().unwrap(); let return_string = String::from_utf8(writer).expect("String parsing error"); assert_eq!(return_string, STR); diff --git a/src/mem.rs b/src/mem.rs index 6c68c54db..91c606aaf 100644 --- a/src/mem.rs +++ b/src/mem.rs @@ -137,14 +137,14 @@ pub enum FlushDecompress { } /// The inner state for an error when decompressing -#[derive(Debug, Default, PartialEq)] +#[derive(Debug, Default)] struct DecompressErrorInner { needs_dictionary: Option, } /// Error returned when a decompression object finds that the input stream of /// bytes was not a valid input stream of bytes. -#[derive(Debug, PartialEq)] +#[derive(Debug)] pub struct DecompressError(DecompressErrorInner); impl DecompressError { diff --git a/src/zio.rs b/src/zio.rs index 5fc43250c..1222a6c3e 100644 --- a/src/zio.rs +++ b/src/zio.rs @@ -217,7 +217,12 @@ impl Writer { let ret = self.data.run_vec(buf, &mut self.buf, D::Flush::none()); let written = (self.data.total_in() - before_in) as usize; - if buf.len() > 0 && written == 0 && ret.is_ok() && ret != Ok(Status::StreamEnd) { + let is_stream_end = match ret { + Ok(Status::StreamEnd) => true, + _ => false, + }; + + if buf.len() > 0 && written == 0 && ret.is_ok() && !is_stream_end { continue; } return match ret {