use core::{
ffi::{c_char, c_void},
ptr::NonNull,
};
use crate::{device::MTLIOCompressionMethod, io_compressor::MTLCompressionStatus};
#[repr(transparent)]
pub struct MTLCompressionContext(*mut c_void);
unsafe extern "C-unwind" {
fn MTLIOCompressionContextDefaultChunkSize() -> usize;
}
unsafe extern "C-unwind" {
fn MTLIOCreateCompressionContext(
path: *const c_char,
r#type: MTLIOCompressionMethod,
chunk_size: usize,
) -> *mut c_void;
}
unsafe extern "C-unwind" {
fn MTLIOCompressionContextAppendData(
context: *mut c_void,
data: *const c_void,
size: usize,
);
}
unsafe extern "C-unwind" {
fn MTLIOFlushAndDestroyCompressionContext(context: *mut c_void) -> MTLCompressionStatus;
}
impl MTLCompressionContext {
pub fn default_chunk_size() -> usize {
unsafe { MTLIOCompressionContextDefaultChunkSize() }
}
pub fn create(
path: NonNull<c_char>,
method: MTLIOCompressionMethod,
chunk_size: usize,
) -> Option<Self> {
let raw = unsafe { MTLIOCreateCompressionContext(path.as_ptr(), method, chunk_size) };
if raw.is_null() {
None
} else {
Some(Self(raw))
}
}
pub fn append_data(
&mut self,
data: NonNull<c_void>,
size: usize,
) {
unsafe { MTLIOCompressionContextAppendData(self.0, data.as_ptr(), size) };
}
pub fn flush_and_destroy(self) -> MTLCompressionStatus {
let status = unsafe { MTLIOFlushAndDestroyCompressionContext(self.0) };
core::mem::forget(self);
status
}
}
impl Drop for MTLCompressionContext {
fn drop(&mut self) {
unsafe {
let _ = MTLIOFlushAndDestroyCompressionContext(self.0);
}
}
}