[](https://docs.rs/xpress_rs)
[](https://crates.io/crates/xpress_rs)
[](https://deps.rs/crate/xpress_rs/0.1.1)
[](https://github.com/rthidfrev/Xpress_rs/actions/workflows/rust.yml)
[](https://github.com/rthidfrev/Xpress_rs/actions/workflows/rust-clippy.yml)
[](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
- [ ] Doc
- [ ] Rewrite tests
- [ ] Add benchmark
- [x] logging
- [ ] optimization :
- [ ] use other hashmap implementation
- [ ] Make a custom hashmap implementation with hash function
- [ ] Try chained hashmap, multiple hashmap and trees
- [ ] Try to avoid hashmap reallocation (use a fixed size hashmap)
- [ ] 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<u8> = 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<Vec<u8>,Box<dyn Error>> = 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<Vec<u8>,Box<dyn Error>> = 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);
}
}
```