use super::super::lspk::CompressionMethod;
use crate::error::{Error, Result};
use std::io::Read;
pub fn decompress_lz4_standalone(compressed: &[u8], expected_size: usize) -> Result<Vec<u8>> {
if let Ok(data) = lz4_flex::block::decompress(compressed, expected_size) {
return Ok(data);
}
let larger_size = expected_size.saturating_mul(2).max(65536);
if let Ok(data) = lz4_flex::block::decompress(compressed, larger_size) {
return Ok(data);
}
if let Ok(data) = lz4_flex::decompress_size_prepended(compressed) {
return Ok(data);
}
let mut decoder = lz4_flex::frame::FrameDecoder::new(compressed);
let mut decompressed = Vec::with_capacity(expected_size);
if decoder.read_to_end(&mut decompressed).is_ok() && !decompressed.is_empty() {
return Ok(decompressed);
}
Err(Error::DecompressionError(format!(
"Failed to decompress LZ4 data: all methods failed (compressed: {} bytes, expected: {} bytes)",
compressed.len(),
expected_size
)))
}
pub fn decompress_zlib_standalone(compressed: &[u8], expected_size: usize) -> Result<Vec<u8>> {
use flate2::read::ZlibDecoder;
let mut decoder = ZlibDecoder::new(compressed);
let mut decompressed = Vec::with_capacity(expected_size);
decoder
.read_to_end(&mut decompressed)
.map_err(|e| Error::DecompressionError(format!("Failed to decompress Zlib data: {e}")))?;
Ok(decompressed)
}
pub fn decompress_data(
compressed: &[u8],
compression: CompressionMethod,
size_decompressed: u32,
) -> Result<Vec<u8>> {
if compression == CompressionMethod::None || size_decompressed == 0 {
return Ok(compressed.to_vec());
}
match compression {
CompressionMethod::None => Ok(compressed.to_vec()),
CompressionMethod::Lz4 => decompress_lz4_standalone(compressed, size_decompressed as usize),
CompressionMethod::Zlib => {
decompress_zlib_standalone(compressed, size_decompressed as usize)
}
}
}