use core::mem::MaybeUninit;
use core::ptr::NonNull;
use lz4_sys::{
c_int, LZ4_compress_continue, LZ4_createStream, LZ4_createStreamDecode,
LZ4_decompress_safe_continue, LZ4_freeStream, LZ4_freeStreamDecode,
};
pub struct CompressStream {
#[cfg(not(miri))]
stream: NonNull<lz4_sys::LZ4StreamEncode>,
}
impl CompressStream {
pub fn new() -> Self {
#[cfg(not(miri))]
{
let raw_ptr = unsafe {
LZ4_createStream()
};
let stream = NonNull::new(raw_ptr).expect("LZ4_createStream returned NULL pointer");
Self { stream }
}
#[cfg(miri)]
{
Self {}
}
}
pub unsafe fn compress(&self, src: &[u8], dst: &mut [MaybeUninit<u8>]) -> Option<usize> {
#[cfg(not(miri))]
{
let result = unsafe {
LZ4_compress_continue(
self.stream.as_ptr(),
src.as_ptr().cast(),
dst.as_mut_ptr().cast(),
src.len() as c_int,
)
};
(result > 0).then_some(result as usize)
}
#[cfg(miri)]
{
unsafe {
core::ptr::copy_nonoverlapping(src.as_ptr(), dst.as_mut_ptr().cast(), src.len());
}
Some(src.len())
}
}
}
#[cfg(not(miri))]
impl Drop for CompressStream {
fn drop(&mut self) {
unsafe {
LZ4_freeStream(self.stream.as_ptr());
}
}
}
pub const fn compress_bound(size: usize) -> usize {
if size > 0x7E000000 {
0
} else {
size + (size / 255) + 16
}
}
pub struct DecompressStream {
#[cfg(not(miri))]
stream: NonNull<lz4_sys::LZ4StreamDecode>,
}
impl DecompressStream {
pub fn new() -> Self {
#[cfg(not(miri))]
{
let raw_ptr = unsafe {
LZ4_createStreamDecode()
};
let stream = NonNull::new(raw_ptr).expect("LZ4_createStreamDecode returned NULL pointer");
Self { stream }
}
#[cfg(miri)]
{
Self {}
}
}
pub unsafe fn decompress(&self, src: &[u8], dst: &mut [MaybeUninit<u8>]) -> Option<usize> {
#[cfg(not(miri))]
{
let decompressed = unsafe {
LZ4_decompress_safe_continue(
self.stream.as_ptr(),
src.as_ptr().cast(),
dst.as_mut_ptr().cast(),
src.len() as c_int,
dst.len() as c_int,
)
};
(decompressed > 0).then_some(decompressed as usize)
}
#[cfg(miri)]
{
unsafe {
copy_nonoverlapping(src.as_ptr(), dst.as_mut_ptr().cast(), src.len());
}
Some(src.len())
}
}
}
#[cfg(not(miri))]
impl Drop for DecompressStream {
fn drop(&mut self) {
unsafe {
LZ4_freeStreamDecode(self.stream.as_ptr());
}
}
}