applesauce-core 0.3.0

A low level library interface for compressing and decompressing files using macos transparent compression
Documentation
use crate::compressor::lz;
use std::cmp;

pub enum Impl {}

const ALGORITHM: bindings::compression_algorithm =
    bindings::compression_algorithm::COMPRESSION_LZFSE;

impl lz::Impl for Impl {
    fn scratch_size() -> usize {
        // SAFETY: Both of these functions are always safe to call
        unsafe {
            cmp::max(
                bindings::compression_encode_scratch_buffer_size(ALGORITHM),
                bindings::compression_decode_scratch_buffer_size(ALGORITHM),
            )
        }
    }

    unsafe fn encode(dst: &mut [u8], src: &[u8], scratch: &mut [u8]) -> usize {
        debug_assert!(
            // SAFETY: function is always safe to call
            scratch.len() >= unsafe { bindings::compression_encode_scratch_buffer_size(ALGORITHM) }
        );

        // SAFETY: Buffers are valid for the specified lengths, and caller must ensure scratch is large enough
        let res = unsafe {
            bindings::compression_encode_buffer(
                dst.as_mut_ptr().cast(),
                dst.len(),
                src.as_ptr().cast(),
                src.len(),
                scratch.as_mut_ptr().cast(),
                ALGORITHM,
            )
        };
        debug_assert!(res <= dst.len());
        res
    }

    unsafe fn decode(dst: &mut [u8], src: &[u8], scratch: &mut [u8]) -> usize {
        debug_assert!(
            // SAFETY: function is always safe to call
            scratch.len() >= unsafe { bindings::compression_decode_scratch_buffer_size(ALGORITHM) }
        );

        // SAFETY: Buffers are valid for the specified lengths, and caller must ensure scratch is large enough
        let res = unsafe {
            bindings::compression_decode_buffer(
                dst.as_mut_ptr().cast(),
                dst.len(),
                src.as_ptr().cast(),
                src.len(),
                scratch.as_mut_ptr().cast(),
                ALGORITHM,
            )
        };
        debug_assert!(res <= dst.len());
        res
    }
}

mod bindings {
    /* automatically generated by rust-bindgen 0.64.0 */
    #![allow(non_camel_case_types)]

    // Generated with:
    // `bindgen tmp.h --default-enum-style=rust --no-layout-tests --allowlist-type='compression_algorithm' --allowlist-var='(?i)compression.*' --allowlist-function='compression_(encode|decode).*'  -- -isysroot$(xcrun --sdk macosx --show-sdk-path)`

    #[allow(dead_code)]
    #[repr(u32)]
    #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
    pub enum compression_algorithm {
        COMPRESSION_LZ4 = 256,
        COMPRESSION_ZLIB = 517,
        COMPRESSION_LZMA = 774,
        COMPRESSION_LZ4_RAW = 257,
        COMPRESSION_BROTLI = 2818,
        COMPRESSION_LZFSE = 2049,
        COMPRESSION_LZBITMAP = 1794,
    }

    #[link(name = "compression")]
    extern "C" {
        pub fn compression_encode_scratch_buffer_size(algorithm: compression_algorithm) -> usize;

        pub fn compression_encode_buffer(
            dst_buffer: *mut u8,
            dst_size: usize,
            src_buffer: *const u8,
            src_size: usize,
            scratch_buffer: *mut ::std::os::raw::c_void,
            algorithm: compression_algorithm,
        ) -> usize;

        pub fn compression_decode_scratch_buffer_size(algorithm: compression_algorithm) -> usize;

        pub fn compression_decode_buffer(
            dst_buffer: *mut u8,
            dst_size: usize,
            src_buffer: *const u8,
            src_size: usize,
            scratch_buffer: *mut ::std::os::raw::c_void,
            algorithm: compression_algorithm,
        ) -> usize;
    }
}