use crate::checksum;
use crate::non_blocking::deflate;
use crate::zlib::Header;
use std::io::{self, Read};
#[derive(Debug)]
pub struct Decoder<R> {
header: Option<Header>,
reader: deflate::Decoder<R>,
adler32: checksum::Adler32,
eos: bool,
}
impl<R: Read> Decoder<R> {
pub fn new(inner: R) -> Self {
Decoder {
header: None,
reader: deflate::Decoder::new(inner),
adler32: checksum::Adler32::new(),
eos: false,
}
}
pub fn header(&mut self) -> io::Result<&Header> {
if let Some(ref header) = self.header {
Ok(header)
} else {
let header = self
.reader
.bit_reader_mut()
.transaction(|r| Header::read_from(r.as_inner_mut()))?;
self.header = Some(header);
self.header()
}
}
pub fn as_inner_ref(&self) -> &R {
self.reader.as_inner_ref()
}
pub fn as_inner_mut(&mut self) -> &mut R {
self.reader.as_inner_mut()
}
pub fn into_inner(self) -> R {
self.reader.into_inner()
}
}
impl<R: Read> Read for Decoder<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
if self.header.is_none() {
self.header()?;
}
if self.eos {
Ok(0)
} else {
let read_size = self.reader.read(buf)?;
if read_size == 0 {
let adler32 = self.reader.bit_reader_mut().transaction(|r| {
let mut buf = [0; 4];
r.as_inner_mut()
.read_exact(&mut buf)
.and(Ok(u32::from_be_bytes(buf)))
})?;
self.eos = true;
if cfg!(not(fuzzing)) && adler32 != self.adler32.value() {
Err(invalid_data_error!(
"Adler32 checksum mismatched: value={}, expected={}",
self.adler32.value(),
adler32
))
} else {
Ok(0)
}
} else {
self.adler32.update(&buf[..read_size]);
Ok(read_size)
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::util::{nb_read_to_end, WouldBlockReader};
use crate::zlib::{EncodeOptions, Encoder};
use std::io;
fn decode_all(buf: &[u8]) -> io::Result<Vec<u8>> {
let decoder = Decoder::new(WouldBlockReader::new(buf));
nb_read_to_end(decoder)
}
fn default_encode(buf: &[u8]) -> io::Result<Vec<u8>> {
let mut encoder = Encoder::new(Vec::new()).unwrap();
io::copy(&mut &buf[..], &mut encoder).unwrap();
encoder.finish().into_result()
}
macro_rules! assert_encode_decode {
($input:expr) => {{
let encoded = default_encode(&$input[..]).unwrap();
assert_eq!(decode_all(&encoded).unwrap(), &$input[..]);
}};
}
const DECODE_WORKS_TESTDATA: [u8; 20] = [
120, 156, 243, 72, 205, 201, 201, 87, 8, 207, 47, 202, 73, 81, 4, 0, 28, 73, 4, 62,
];
#[test]
fn decode_works() {
let encoded = DECODE_WORKS_TESTDATA;
let buf = decode_all(&encoded[..]).unwrap();
let expected = b"Hello World!";
assert_eq!(buf, expected);
}
#[test]
fn default_encode_works() {
let plain = b"Hello World! Hello ZLIB!!";
let mut encoder = Encoder::new(Vec::new()).unwrap();
io::copy(&mut &plain[..], &mut encoder).unwrap();
let encoded = encoder.finish().into_result().unwrap();
assert_eq!(decode_all(&encoded).unwrap(), plain);
}
#[test]
fn best_speed_encode_works() {
let plain = b"Hello World! Hello ZLIB!!";
let mut encoder =
Encoder::with_options(Vec::new(), EncodeOptions::default().fixed_huffman_codes())
.unwrap();
io::copy(&mut &plain[..], &mut encoder).unwrap();
let encoded = encoder.finish().into_result().unwrap();
assert_eq!(decode_all(&encoded).unwrap(), plain);
}
const RAW_ENCODE_WORKS_EXPECTED: [u8; 23] = [
120, 1, 1, 12, 0, 243, 255, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33, 28, 73,
4, 62,
];
#[test]
fn raw_encode_works() {
let plain = b"Hello World!";
let mut encoder =
Encoder::with_options(Vec::new(), EncodeOptions::new().no_compression()).unwrap();
io::copy(&mut &plain[..], &mut encoder).unwrap();
let encoded = encoder.finish().into_result().unwrap();
let expected = RAW_ENCODE_WORKS_EXPECTED;
assert_eq!(encoded, expected);
assert_eq!(decode_all(&encoded).unwrap(), plain);
}
#[test]
fn test_issue_2() {
assert_encode_decode!([
163, 181, 167, 40, 62, 239, 41, 125, 189, 217, 61, 122, 20, 136, 160, 178, 119, 217,
217, 41, 125, 189, 97, 195, 101, 47, 170,
]);
assert_encode_decode!([
162, 58, 99, 211, 7, 64, 96, 36, 57, 155, 53, 166, 76, 14, 238, 66, 66, 148, 154, 124,
162, 58, 99, 188, 138, 131, 171, 189, 54, 229, 192, 38, 29, 240, 122, 28,
]);
assert_encode_decode!([
239, 238, 212, 42, 5, 46, 186, 67, 122, 247, 30, 61, 219, 62, 228, 202, 164, 205, 139,
109, 99, 181, 99, 181, 99, 122, 30, 12, 62, 46, 27, 145, 241, 183, 137,
]);
assert_encode_decode!([
88, 202, 64, 12, 125, 108, 153, 49, 164, 250, 71, 19, 4, 108, 111, 108, 237, 205, 208,
77, 217, 100, 118, 49, 10, 64, 12, 125, 51, 202, 69, 67, 181, 146, 86,
]);
}
}