#![allow(dead_code)]
use std::io;
#[allow(dead_code)]
pub fn is_available() -> bool {
true
}
pub struct IsalInflater {
inner: libdeflater::Decompressor,
}
impl IsalInflater {
pub fn new() -> io::Result<Self> {
Ok(Self {
inner: libdeflater::Decompressor::new(),
})
}
pub fn reset(&mut self) -> io::Result<()> {
self.inner = libdeflater::Decompressor::new();
Ok(())
}
#[allow(dead_code)]
pub fn set_dict(&mut self, _dict: &[u8]) -> io::Result<()> {
Err(io::Error::new(
io::ErrorKind::Unsupported,
"Dictionary not supported (ISA-L not available)",
))
}
#[allow(dead_code)]
pub fn decompress(&mut self, input: &[u8], output: &mut [u8]) -> io::Result<usize> {
match self.inner.gzip_decompress(input, output) {
Ok(n) => Ok(n),
Err(e) => Err(io::Error::new(
io::ErrorKind::InvalidData,
format!("Decompression failed: {:?}", e),
)),
}
}
pub fn decompress_all(&mut self, input: &[u8], initial_size: usize) -> io::Result<Vec<u8>> {
let mut output = vec![0u8; initial_size];
loop {
match self.inner.gzip_decompress(input, &mut output) {
Ok(n) => {
output.truncate(n);
return Ok(output);
}
Err(libdeflater::DecompressionError::InsufficientSpace) => {
output.resize(output.len() * 2, 0);
}
Err(e) => {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!("Decompression failed: {:?}", e),
));
}
}
}
}
}
impl Default for IsalInflater {
fn default() -> Self {
Self::new().expect("Failed to create inflater")
}
}
#[cfg(test)]
mod tests {
use super::*;
use flate2::write::GzEncoder;
use flate2::Compression;
use std::io::Write;
#[test]
fn test_decompress() {
let original = b"Hello, World! This is a test of gzip decompression.";
let mut encoder = GzEncoder::new(Vec::new(), Compression::default());
encoder.write_all(original).unwrap();
let compressed = encoder.finish().unwrap();
let mut inflater = IsalInflater::new().unwrap();
let decompressed = inflater.decompress_all(&compressed, 1024).unwrap();
assert_eq!(&decompressed, original);
}
#[test]
fn test_large_decompress() {
let original: Vec<u8> = (0..1_000_000).map(|i| (i % 256) as u8).collect();
let mut encoder = GzEncoder::new(Vec::new(), Compression::default());
encoder.write_all(&original).unwrap();
let compressed = encoder.finish().unwrap();
let mut inflater = IsalInflater::new().unwrap();
let decompressed = inflater
.decompress_all(&compressed, compressed.len() * 2)
.unwrap();
assert_eq!(decompressed, original);
}
#[test]
fn test_reset() {
let original = b"Test data for reset";
let mut encoder = GzEncoder::new(Vec::new(), Compression::default());
encoder.write_all(original).unwrap();
let compressed = encoder.finish().unwrap();
let mut inflater = IsalInflater::new().unwrap();
let result1 = inflater.decompress_all(&compressed, 1024).unwrap();
inflater.reset().unwrap();
let result2 = inflater.decompress_all(&compressed, 1024).unwrap();
assert_eq!(result1, result2);
assert_eq!(&result1[..], original);
}
}