aboutsummaryrefslogtreecommitdiffhomepage
path: root/libs/hbb_common/src/compress.rs
blob: a969ccf86344ec03bf70d7c27cccbd1b847fbfea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
use std::cell::RefCell;
use zstd::block::{Compressor, Decompressor};

thread_local! {
    static COMPRESSOR: RefCell<Compressor> = RefCell::new(Compressor::new());
    static DECOMPRESSOR: RefCell<Decompressor> = RefCell::new(Decompressor::new());
}

/// The library supports regular compression levels from 1 up to ZSTD_maxCLevel(),
/// which is currently 22. Levels >= 20
/// Default level is ZSTD_CLEVEL_DEFAULT==3.
/// value 0 means default, which is controlled by ZSTD_CLEVEL_DEFAULT
pub fn compress(data: &[u8], level: i32) -> Vec<u8> {
    let mut out = Vec::new();
    COMPRESSOR.with(|c| {
        if let Ok(mut c) = c.try_borrow_mut() {
            match c.compress(data, level) {
                Ok(res) => out = res,
                Err(err) => {
                    crate::log::debug!("Failed to compress: {}", err);
                }
            }
        }
    });
    out
}

pub fn decompress(data: &[u8]) -> Vec<u8> {
    let mut out = Vec::new();
    DECOMPRESSOR.with(|d| {
        if let Ok(mut d) = d.try_borrow_mut() {
            const MAX: usize = 1024 * 1024 * 64;
            const MIN: usize = 1024 * 1024;
            let mut n = 30 * data.len();
            if n > MAX {
                n = MAX;
            }
            if n < MIN {
                n = MIN;
            }
            match d.decompress(data, n) {
                Ok(res) => out = res,
                Err(err) => {
                    crate::log::debug!("Failed to decompress: {}", err);
                }
            }
        }
    });
    out
}