#[derive(Debug, Clone, PartialEq, Eq)]
pub enum LzoError {
InvalidInput,
OutputLength,
}
impl std::fmt::Display for LzoError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::InvalidInput => write!(f, "LZO invalid input"),
Self::OutputLength => write!(f, "LZO output length mismatch"),
}
}
}
impl std::error::Error for LzoError {}
pub fn decompress(src: &[u8], dst: &mut [u8]) -> Result<(), LzoError> {
lzo1x::decompress(src, dst).map_err(|e| match e {
lzo1x::DecompressError::InvalidInput => LzoError::InvalidInput,
lzo1x::DecompressError::OutputLength => LzoError::OutputLength,
})
}
#[cfg(test)]
mod tests {
use super::*;
fn compress(data: &[u8]) -> Vec<u8> {
lzo1x::compress(data, lzo1x::CompressLevel::default())
}
#[test]
fn decompress_empty_data() {
let input: &[u8] = &[];
let compressed = compress(input);
let mut dst = [];
decompress(&compressed, &mut dst).unwrap();
}
#[test]
fn decompress_short_literal() {
let data = [0xDE, 0xAD, 0xBE, 0xEF];
let compressed = compress(&data);
let mut dst = [0u8; 4];
decompress(&compressed, &mut dst).unwrap();
assert_eq!(dst, data);
}
#[test]
fn decompress_repeated_bytes_match_copy() {
let data = [b'A'; 32];
let compressed = compress(&data);
let mut dst = [0u8; 32];
decompress(&compressed, &mut dst).unwrap();
assert_eq!(dst, data);
}
#[test]
fn decompress_full_kernel_page() {
let data = vec![0x55u8; 4096];
let compressed = compress(&data);
let mut dst = vec![0u8; 4096];
decompress(&compressed, &mut dst).unwrap();
assert_eq!(dst, data);
}
#[test]
fn decompress_invalid_input_errors() {
let mut dst = [0u8; 4];
let result = decompress(&[0xFF, 0xFF, 0xFF], &mut dst);
assert_eq!(result, Err(LzoError::InvalidInput));
}
#[test]
fn decompress_output_length_mismatch_errors() {
let data = [0xDE, 0xAD, 0xBE, 0xEF];
let compressed = compress(&data);
let mut dst = [0u8; 2];
let result = decompress(&compressed, &mut dst);
assert_eq!(result, Err(LzoError::OutputLength));
}
#[test]
fn decompress_empty_input_errors() {
let mut dst = [0u8; 4];
let result = decompress(&[], &mut dst);
assert!(result.is_err());
}
}