1mod lzo1x_compress;
2mod lzo1x_decompress_safe;
3extern crate libc;
4use std::mem;
5use std::slice;
6
7pub fn worst_compress(size: usize) -> usize {
9 ((size) + ((size) / 16) + 64 + 3)
10}
11
12const LZO1X_1_MEM_COMPRESS: usize = (8192 * 16);
13const LZO1X_MEM_COMPRESS: usize = LZO1X_1_MEM_COMPRESS;
14
15#[repr(i32)]
16#[derive(PartialEq)]
17pub enum LZOError {
18 OK = 0,
19 ERROR = -1,
20 OUT_OF_MEMORY = -2,
21 NOT_COMPRESSIBLE = -3,
22 INPUT_OVERRUN = -4,
23 OUTPUT_OVERRUN = -5,
24 LOOKBEHIND_OVERRUN = -6,
25 EOF_NOT_FOUND = -7,
26 INPUT_NOT_CONSUMED = -8,
27 NOT_YET_IMPLEMENTED = -9,
28 INVALID_ARGUMENT = -10,
29}
30
31pub struct LZOContext {
32 wrkmem: *mut libc::c_void,
33}
34
35impl Drop for LZOContext {
36 fn drop(&mut self) {
37 unsafe {
38 libc::free(self.wrkmem);
39 }
40 }
41}
42
43impl LZOContext {
44 pub fn new() -> LZOContext {
45 LZOContext { wrkmem: unsafe { libc::malloc(LZO1X_MEM_COMPRESS) } }
46 }
47
48 pub fn compress(&mut self, input: &[u8], output: &mut Vec<u8>) -> LZOError {
51 unsafe {
52 let mut out_len = output.capacity();
53 let err = lzo1x_compress::lzo1x_1_compress(input.as_ptr(),
54 input.len(),
55 output.as_mut_ptr(),
56 &mut out_len,
57 &mut *self.wrkmem as *mut _ as *mut _);
58
59 output.set_len(out_len);
60 mem::transmute::<i32, LZOError>(err)
61 }
62 }
63
64 pub fn compress_to_slice<'a>(&mut self, in_: &[u8], out: &'a mut [u8]) -> (&'a mut [u8], LZOError) {
66 unsafe {
67 let mut out_len = out.len();
68 let err = lzo1x_compress::lzo1x_1_compress(in_.as_ptr(),
69 in_.len(),
70 out.as_mut_ptr(),
71 &mut out_len,
72 &mut *self.wrkmem as *mut _ as *mut _);
73 (slice::from_raw_parts_mut(out.as_mut_ptr(), out_len),
74 mem::transmute::<i32, LZOError>(err))
75 }
76 }
77
78 pub fn decompress_to_slice<'a>(in_: &[u8], out: &'a mut [u8]) -> (&'a mut [u8], LZOError) {
80 unsafe {
81 let mut out_len = out.len();
82 let err = lzo1x_decompress_safe::lzo1x_decompress_safe(in_.as_ptr(),
83 in_.len(),
84 out.as_mut_ptr(),
85 &mut out_len);
86 (slice::from_raw_parts_mut(out.as_mut_ptr(), out_len),
87 mem::transmute::<i32, LZOError>(err))
88 }
89 }
90}
91
92#[test]
93fn it_works() {
94 unsafe {
95 let data = [0u8, 2, 3, 4, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
96 2, 3, 4, 2, 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3,
97 4, 2, 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 2,
98 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4];
99 let mut dst_len: usize = worst_compress(mem::size_of_val(&data));
100 let mut v = Vec::with_capacity(dst_len);
101 let dst = libc::malloc(dst_len);
102 let mut ctx = LZOContext::new();
103 let mut dst = slice::from_raw_parts_mut(dst as *mut u8, dst_len);
104 let (dst, err) = ctx.compress_to_slice(&data, &mut dst);
105 assert!(err == LZOError::OK);
106 let err = ctx.compress(&data, &mut v);
107 assert!(err == LZOError::OK);
108 println!("{}", dst.len());
109
110 let dec_dst = libc::malloc(mem::size_of_val(&data));
111 let result_len = mem::size_of_val(&data);
112 let mut dec_dst = slice::from_raw_parts_mut(dec_dst as *mut u8, result_len);
113 let (result, err) = LZOContext::decompress_to_slice(&dst, &mut dec_dst);
114 assert!(err == LZOError::OK);
115 println!("{}", result.len());
116 assert!(result.len() == mem::size_of_val(&data));
117 assert!(&data[..] == result);
118 }
119
120}