[![Documentation](https://docs.rs/xpress_rs/badge.svg)](https://docs.rs/xpress_rs) [![Crates.io](https://img.shields.io/crates/v/xpress_rs.svg)](https://crates.io/crates/xpress_rs) [![dependency status](https://deps.rs/crate/xpress_rs/0.1.1/status.svg)](https://deps.rs/crate/xpress_rs/0.1.1) [![Rust](https://github.com/rthidfrev/Xpress_rs/actions/workflows/rust.yml/badge.svg)](https://github.com/rthidfrev/Xpress_rs/actions/workflows/rust.yml) [![rust-clippy analyze](https://github.com/rthidfrev/Xpress_rs/actions/workflows/rust-clippy.yml/badge.svg)](https://github.com/rthidfrev/Xpress_rs/actions/workflows/rust-clippy.yml) [![DevSkim](https://github.com/rthidfrev/Xpress_rs/actions/workflows/devskim.yml/badge.svg)](https://github.com/rthidfrev/Xpress_rs/actions/workflows/devskim.yml) # Xpress_rs A rust implementation of the xpress compression algorithm. Defined in the [MS-XCA](https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-XCA/%5bMS-XCA%5d.pdf) Work in progress, only the LZ77 algorithm is implemented. ## LZ77 : - [x] Comment - [x] Doc - [x] Rewrite tests - [x] Add benchmark - [x] logging - [ ] optimization : - [x] use other hashmap implementation - [x] Make a custom hashmap implementation with hash function - [ ] Try chained hashmap, multiple hashmap and trees - [x] Try to avoid hashmap reallocation (use a fixed size hashmap) - [x] Global code optimization ### Logging The logging feature use a lot of macro, so the execution time is not optimal. I recommend to disable the logging feature in release mode, but can be useful for testing or debugging. - Use "cargo test --features logging" to enable logging in test - Future release will have more logging feature (ex: only compile log macro you need) ### Error handling The error handling is not optimal, and can be improved. In the compression algorithm, the output buffer is a fixed size buffer, is defined to be 2 times the size of the input buffer. Im not sure if this can result in a buffer overflow. I didn't check size in the algorithm, because it will slow down the algorithm and i didn't want to use vector for avoiding reallocation. --> TODO: find a better way to implement this. ### Example ```rust use xpress_rs::lz77::{LZ77Compressor,LZ77Decompressor}; use std::error::Error; #[cfg(feature = "logging")] { use env_logger::Env; use log::{info, LevelFilter}; env_logger::Builder::new().filter(None, LevelFilter::Info).init(); } // data to compress let data_to_compress: Vec = b"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.".to_vec(); // init the Compressor let compressor = LZ77Compressor::new(data_to_compress); // compress the data let result: Result,Box> = compressor.compress(); // check if the compression is successful match result { Ok(compressed_data) => { // init the Decompressor let decompressor = LZ77Decompressor::new(compressed_data); // decompress the data let result: Result,Box> = decompressor.decompress(); // check if the decompression is successful match result { Ok(decompressed_data) => { println!("Decompressed data: {:?}",decompressed_data); }, Err(e) => { println!("Error: {}",e); } } }, Err(e) => { println!("Error: {}",e); } } ```