#[cfg(test)]
use crate as fdeflate;
use fdeflate::{DecompressionError, Decompressor};
#[derive(Debug, PartialEq)]
pub enum TestDecompressionError {
ProdError(DecompressionError),
TestError(TestErrorKind),
}
#[derive(Debug, Eq, PartialEq)]
pub enum TestErrorKind {
OutputTooLarge,
TooManyIterations,
}
impl From<DecompressionError> for TestDecompressionError {
fn from(e: DecompressionError) -> Self {
Self::ProdError(e)
}
}
impl From<TestErrorKind> for TestDecompressionError {
fn from(kind: TestErrorKind) -> Self {
Self::TestError(kind)
}
}
pub fn decompress_by_chunks(
input: &[u8],
chunks: impl IntoIterator<Item = usize>,
early_eof: bool,
) -> Result<Vec<u8>, TestDecompressionError> {
let mut chunks = chunks.into_iter();
let mut iteration_counter = 0;
let mut d = Decompressor::new();
d.ignore_adler32();
let mut out_buf = vec![0; 1_000_000];
let mut in_pos = 0;
let mut out_pos = 0;
while !d.is_done() {
iteration_counter += 1;
if iteration_counter > 5000 {
return Err(TestErrorKind::TooManyIterations.into());
}
let chunk_size = chunks.next().unwrap_or(0);
let start = in_pos;
let end = std::cmp::min(start + chunk_size, input.len());
let eof = if early_eof {
end == input.len()
} else {
start == input.len()
};
let (in_consumed, out_written) =
d.read(&input[start..end], out_buf.as_mut_slice(), out_pos, eof)?;
in_pos += in_consumed;
out_pos += out_written;
if out_pos == out_buf.len() && in_consumed == 0 && !d.is_done() {
return Err(TestErrorKind::OutputTooLarge.into());
}
}
out_buf.resize(out_pos, 0xFF);
Ok(out_buf)
}