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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use crate::error::check;
use crate::Result;
use absperf_minilzo_sys::{lzo1x_1_compress, lzo_uint};
use std::cell::RefCell;
use std::ffi::c_void;
use std::mem::size_of;
use std::os::raw::c_char;
const LZO1X_MEM_COMPRESS: usize = 16384 * size_of::<*const c_char>();
thread_local!(
static WRKMEM: RefCell<[u8; LZO1X_MEM_COMPRESS]> = RefCell::new([0u8; LZO1X_MEM_COMPRESS])
);
pub trait CompressInto<T: ?Sized> {
fn compress_into<'buffer>(&self, destination: &'buffer mut T) -> Result<&'buffer [u8]>;
}
impl CompressInto<[u8]> for [u8] {
fn compress_into<'buffer>(&self, destination: &'buffer mut [u8]) -> Result<&'buffer [u8]> {
WRKMEM.with(move |wrkmem| {
let mut wrkmem = wrkmem.borrow_mut();
let mut out_len = destination.len() as lzo_uint;
let ret = unsafe {
lzo1x_1_compress(
self.as_ptr(),
self.len() as lzo_uint,
destination.as_mut_ptr(),
&mut out_len,
wrkmem.as_mut_ptr() as *mut c_void,
)
};
check(ret)?;
Ok(&destination[..out_len as usize])
})
}
}
impl CompressInto<Vec<u8>> for [u8] {
fn compress_into<'buffer>(&self, destination: &'buffer mut Vec<u8>) -> Result<&'buffer [u8]> {
WRKMEM.with(move |wrkmem| {
let mut wrkmem = wrkmem.borrow_mut();
let in_len = self.len() as lzo_uint;
let mut out_len = in_len + in_len / 16 + 64 + 3;
if destination.capacity() < out_len as usize {
destination.reserve_exact(out_len as usize - destination.len());
}
out_len = destination.capacity() as lzo_uint;
let ret = unsafe {
lzo1x_1_compress(
self.as_ptr(),
in_len,
destination.as_mut_ptr(),
&mut out_len,
wrkmem.as_mut_ptr() as *mut c_void,
)
};
check(ret)?;
unsafe {
destination.set_len(out_len as usize);
}
Ok(&destination[..out_len as usize])
})
}
}