1#![doc = include_str!("../README.MD")]
2#![no_std]
3#![allow(warnings)]
4
5#[cfg(feature = "std")]
6extern crate std;
7
8use core::ffi::c_void;
9
10extern crate alloc;
11extern crate core;
12
13#[cfg(not(feature = "generate-bindings"))]
14include!("bindings.rs");
15
16#[cfg(feature = "generate-bindings")]
17include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
18
19pub struct Allocator {
21 alloc: ISzAlloc,
22}
23
24impl Default for Allocator {
25 fn default() -> Self {
26 Self {
27 alloc: ISzAlloc {
28 Alloc: Some(sz_alloc),
29 Free: Some(sz_free),
30 },
31 }
32 }
33}
34
35impl AsRef<ISzAlloc> for Allocator {
36 fn as_ref(&self) -> &ISzAlloc {
37 &self.alloc
38 }
39}
40
41unsafe extern "C" fn sz_alloc(_p: ISzAllocPtr, size: usize) -> *mut c_void {
42 libc::malloc(size)
43}
44
45unsafe extern "C" fn sz_free(_p: ISzAllocPtr, address: *mut c_void) {
46 libc::free(address)
47}
48
49#[cfg(feature = "test-build-size")]
50#[no_mangle]
51pub unsafe extern "C" fn LzmaDecode_Out(
52 dest: *mut Byte,
53 destLen: *mut SizeT,
54 src: *const Byte,
55 srcLen: *mut SizeT,
56 propData: *const Byte,
57 propSize: ::core::ffi::c_uint,
58 finishMode: ELzmaFinishMode,
59 status: *mut ELzmaStatus,
60 alloc: ISzAllocPtr,
61) -> SRes {
62 LzmaDecode(
63 dest, destLen, src, srcLen, propData, propSize, finishMode, status, alloc,
64 )
65}
66
67#[cfg(feature = "test-build-size")]
68#[no_mangle]
69pub unsafe extern "C" fn LzmaEncode_Out(
70 dest: *mut Byte,
71 destLen: *mut SizeT,
72 src: *const Byte,
73 srcLen: SizeT,
74 props: *const CLzmaEncProps,
75 propsEncoded: *mut Byte,
76 propsSize: *mut SizeT,
77 writeEndMark: ::core::ffi::c_int,
78 progress: ICompressProgressPtr,
79 alloc: ISzAllocPtr,
80 allocBig: ISzAllocPtr,
81) -> SRes {
82 LzmaEncode(
83 dest,
84 destLen,
85 src,
86 srcLen,
87 props,
88 propsEncoded,
89 propsSize,
90 writeEndMark,
91 progress,
92 alloc,
93 allocBig,
94 )
95}
96
97#[cfg(test)]
98mod tests {
99 use super::*;
100 use alloc::vec;
101 use std::ptr;
102
103 #[test]
104 fn test_lzma_round_trip() {
105 let input = b"Hello LZMA compression!";
106 let mut props = [0u8; LZMA_PROPS_SIZE as usize];
107 let mut props_size = LZMA_PROPS_SIZE as SizeT;
108
109 let mut compressed = vec![0u8; input.len() * 2];
111 let mut compressed_size = compressed.len() as SizeT;
112
113 let alloc = Allocator::default();
114
115 unsafe {
116 let enc = LzmaEnc_Create(alloc.as_ref() as *const _);
117 assert!(!enc.is_null());
118
119 let mut enc_props = CLzmaEncProps::default();
120 LzmaEncProps_Init(&mut enc_props);
121
122 let res = LzmaEnc_SetProps(enc, &enc_props);
123 assert_eq!(res, SZ_OK as i32);
124
125 let res = LzmaEncode(
126 compressed.as_mut_ptr() as *mut Byte,
127 &mut compressed_size,
128 input.as_ptr() as *const Byte,
129 input.len() as SizeT,
130 &enc_props,
131 props.as_mut_ptr() as *mut Byte,
132 &mut props_size,
133 0,
134 ptr::null_mut(),
135 alloc.as_ref(),
136 alloc.as_ref(),
137 );
138 assert_eq!(res, SZ_OK as i32);
139
140 LzmaEnc_Destroy(enc, alloc.as_ref(), alloc.as_ref());
141
142 compressed.truncate(compressed_size as usize);
144
145 let mut dest = vec![0u8; input.len()];
148 let mut dest_size = dest.capacity() as SizeT;
149 let mut source_len: SizeT = compressed.len();
150 let mut status: ELzmaStatus = ELzmaStatus::LZMA_STATUS_NOT_SPECIFIED;
151
152 let res = LzmaDecode(
153 dest.as_mut_ptr() as *mut Byte,
154 &mut dest_size,
155 compressed.as_ptr() as *const Byte,
156 &mut source_len,
157 props.as_ptr() as *const Byte,
158 props_size as u32,
159 ELzmaFinishMode::LZMA_FINISH_END,
160 &mut status,
161 alloc.as_ref(),
162 );
163 assert_eq!(res, SZ_OK as i32);
164
165 assert_eq!(dest_size as usize, input.len());
167 assert_eq!(&dest[..dest_size as usize], input);
168 }
169 }
170}