5 releases

0.2.0 Jul 7, 2023
0.1.3 Jul 2, 2023
0.1.2 Jul 2, 2023
0.1.1 Jul 2, 2023
0.1.0 Jul 2, 2023

#317 in Compression

Download history 69/week @ 2024-04-27 1/week @ 2024-05-04 29/week @ 2024-06-29 37/week @ 2024-07-27

62 downloads per month

MIT license

42KB
362 lines

Documentation Crates.io dependency status Rust rust-clippy analyze DevSkim

Xpress_rs

A rust implementation of the xpress compression algorithm. Defined in the MS-XCA

Work in progress, only the LZ77 algorithm is implemented.

LZ77 :

  • Comment
  • Doc
  • Rewrite tests
  • Add benchmark
  • 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

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);
    }
}

Dependencies

~100–750KB
~13K SLoC