use std::error::Error;
use std::fs;
use std::io::Read;
use std::time::Instant;
use xpress_rs::lz77::{LZ77Compressor, LZ77Decompressor};
fn test_compress_lz77(data_to_compress: Vec<u8>) -> Result<Vec<u8>, Box<dyn Error>> {
let compressor = LZ77Compressor::new(data_to_compress);
let result: Result<Vec<u8>, Box<dyn Error>> = compressor.compress();
match result {
Ok(compressed_data) => Ok(compressed_data),
Err(e) => Err(e),
}
}
fn test_lz77_decompression(data_to_decompress: Vec<u8>) -> Result<Vec<u8>, Box<dyn Error>> {
let decompressor = LZ77Decompressor::new(data_to_decompress);
let result: Result<Vec<u8>, Box<dyn Error>> = decompressor.decompress();
match result {
Ok(decompressed_data) => Ok(decompressed_data),
Err(e) => Err(e),
}
}
#[test]
fn testlz77() {
#[cfg(feature = "logging")]
{
use env_logger::Env;
use log::{info, LevelFilter};
env_logger::Builder::new()
.filter(None, LevelFilter::Info)
.init();
}
let data_to_compress: Vec<u8> = b"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.".to_vec();
let data_to_decompress: Vec<u8> = test_compress_lz77(data_to_compress.clone())
.map_err(|e| format!("Error: {}", e))
.unwrap();
let result = test_lz77_decompression(data_to_decompress)
.map_err(|e| format!("Error: {}", e))
.unwrap();
assert_eq!(result, data_to_compress);
}
#[test]
fn bench_lz77() {
let mut data = fs::File::open("tests/large.txt").unwrap();
let mut data_content = Vec::new();
data.read_to_end(&mut data_content).unwrap();
let time = Instant::now();
let compressed_data = test_compress_lz77(data_content.clone()).unwrap();
println!(
"Crate : time to compress: {}s",
time.elapsed().as_secs_f64()
);
println!(
"Crate : compress ratio: {}%",
compressed_data.len() as f64 / data_content.len() as f64 * 100.0
);
let time = Instant::now();
let _ = test_lz77_decompression(compressed_data.clone()).unwrap();
println!(
"Crate : time to decompress: {}s",
time.elapsed().as_secs_f64()
);
}
#[cfg(windows)]
mod windows_only {
use std::fs;
use std::io::Read;
use windows::Win32::Foundation::{GetLastError, BOOL};
#[cfg(target_os = "windows")]
use windows::Win32::Storage::Compression::{
Compress, CreateCompressor, COMPRESSOR_HANDLE, COMPRESS_ALGORITHM_XPRESS,
};
#[test]
fn test_windows_api() {
unsafe {
let instant = std::time::Instant::now();
let mut compressor_handle: isize = 0;
let result = CreateCompressor(COMPRESS_ALGORITHM_XPRESS, None, &mut compressor_handle);
if result == BOOL(0) {
println!("Error: {:?}", GetLastError());
}
let mut data = fs::File::open("tests/large.txt").unwrap();
let mut data_content = Vec::new();
data.read_to_end(&mut data_content).unwrap();
let mut compressed_data = vec![0u8; data_content.len()];
let mut compressed_data_len: usize = 0;
let compressor_handle = COMPRESSOR_HANDLE(compressor_handle);
let result = Compress(
compressor_handle,
Some(data_content.as_ptr() as *const _),
data_content.len(),
Some(compressed_data.as_mut_ptr() as *mut _),
compressed_data.len(),
&mut compressed_data_len,
);
if result == BOOL(0) {
println!("Error: {:?}", GetLastError());
} else {
println!(
"Winapi : time to compress: {}s",
instant.elapsed().as_secs_f64()
);
println!(
"Winapi : compress ratio: {}%",
(compressed_data_len as f64 / data_content.len() as f64) * 100.0
);
}
}
}
}