#![doc = include_str!("../README.MD")]
#![no_std]
#![allow(warnings)]
#[cfg(feature = "std")]
extern crate std;
use core::ffi::c_void;
extern crate alloc;
extern crate core;
#[cfg(not(feature = "generate-bindings"))]
include!("bindings.rs");
#[cfg(feature = "generate-bindings")]
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
pub struct Allocator {
alloc: ISzAlloc,
}
impl Default for Allocator {
fn default() -> Self {
Self {
alloc: ISzAlloc {
Alloc: Some(sz_alloc),
Free: Some(sz_free),
},
}
}
}
impl AsRef<ISzAlloc> for Allocator {
fn as_ref(&self) -> &ISzAlloc {
&self.alloc
}
}
unsafe extern "C" fn sz_alloc(_p: ISzAllocPtr, size: usize) -> *mut c_void {
libc::malloc(size)
}
unsafe extern "C" fn sz_free(_p: ISzAllocPtr, address: *mut c_void) {
libc::free(address)
}
#[cfg(feature = "test-build-size")]
#[no_mangle]
pub unsafe extern "C" fn LzmaDecode_Out(
dest: *mut Byte,
destLen: *mut SizeT,
src: *const Byte,
srcLen: *mut SizeT,
propData: *const Byte,
propSize: ::core::ffi::c_uint,
finishMode: ELzmaFinishMode,
status: *mut ELzmaStatus,
alloc: ISzAllocPtr,
) -> SRes {
LzmaDecode(
dest, destLen, src, srcLen, propData, propSize, finishMode, status, alloc,
)
}
#[cfg(feature = "test-build-size")]
#[no_mangle]
pub unsafe extern "C" fn LzmaEncode_Out(
dest: *mut Byte,
destLen: *mut SizeT,
src: *const Byte,
srcLen: SizeT,
props: *const CLzmaEncProps,
propsEncoded: *mut Byte,
propsSize: *mut SizeT,
writeEndMark: ::core::ffi::c_int,
progress: ICompressProgressPtr,
alloc: ISzAllocPtr,
allocBig: ISzAllocPtr,
) -> SRes {
LzmaEncode(
dest,
destLen,
src,
srcLen,
props,
propsEncoded,
propsSize,
writeEndMark,
progress,
alloc,
allocBig,
)
}
#[cfg(test)]
mod tests {
use super::*;
use alloc::vec;
use std::ptr;
#[test]
fn test_lzma_round_trip() {
let input = b"Hello LZMA compression!";
let mut props = [0u8; LZMA_PROPS_SIZE as usize];
let mut props_size = LZMA_PROPS_SIZE as SizeT;
let mut compressed = vec![0u8; input.len() * 2];
let mut compressed_size = compressed.len() as SizeT;
let alloc = Allocator::default();
unsafe {
let enc = LzmaEnc_Create(alloc.as_ref() as *const _);
assert!(!enc.is_null());
let mut enc_props = CLzmaEncProps::default();
LzmaEncProps_Init(&mut enc_props);
let res = LzmaEnc_SetProps(enc, &enc_props);
assert_eq!(res, SZ_OK as i32);
let res = LzmaEncode(
compressed.as_mut_ptr() as *mut Byte,
&mut compressed_size,
input.as_ptr() as *const Byte,
input.len() as SizeT,
&enc_props,
props.as_mut_ptr() as *mut Byte,
&mut props_size,
0,
ptr::null_mut(),
alloc.as_ref(),
alloc.as_ref(),
);
assert_eq!(res, SZ_OK as i32);
LzmaEnc_Destroy(enc, alloc.as_ref(), alloc.as_ref());
compressed.truncate(compressed_size as usize);
let mut dest = vec![0u8; input.len()];
let mut dest_size = dest.capacity() as SizeT;
let mut source_len: SizeT = compressed.len();
let mut status: ELzmaStatus = ELzmaStatus::LZMA_STATUS_NOT_SPECIFIED;
let res = LzmaDecode(
dest.as_mut_ptr() as *mut Byte,
&mut dest_size,
compressed.as_ptr() as *const Byte,
&mut source_len,
props.as_ptr() as *const Byte,
props_size as u32,
ELzmaFinishMode::LZMA_FINISH_END,
&mut status,
alloc.as_ref(),
);
assert_eq!(res, SZ_OK as i32);
assert_eq!(dest_size as usize, input.len());
assert_eq!(&dest[..dest_size as usize], input);
}
}
}