diff --git a/proxmox-protocol/src/c_chunker.rs b/proxmox-protocol/src/c_chunker.rs new file mode 100644 index 00000000..ba7835d0 --- /dev/null +++ b/proxmox-protocol/src/c_chunker.rs @@ -0,0 +1,45 @@ +//! C API for the Chunker. + +use std::os::raw::c_void; + +use crate::Chunker; + +/// Creates a new chunker instance. +#[no_mangle] +pub extern "C" fn proxmox_chunker_new(chunk_size_avg: u64) -> *mut Chunker { + Box::leak(Box::new(Chunker::new(chunk_size_avg as usize))) +} + +/// Drops an instance of a chunker. The pointer must be valid or `NULL`. +#[no_mangle] +pub extern "C" fn proxmox_chunker_done(me: *mut Chunker) { + if !me.is_null() { + unsafe { + Box::from_raw(me); + } + } +} + +/// Scan the specified data for a chunk border. Returns 0 if none was found, or a positive offset +/// to a border. +#[no_mangle] +pub extern "C" fn proxmox_chunker_scan( + me: *mut Chunker, + data: *const c_void, + size: u64, +) -> u64 { + let me = unsafe { &mut *me }; + me.scan(unsafe { + std::slice::from_raw_parts(data as *const u8, size as usize) + }) as u64 +} + +/// Compute a chunk digest. This is mostly a convenience method to avoid having to lookup the right +/// digest method for your language of choice. +#[no_mangle] +pub extern "C" fn proxmox_chunk_digest(data: *const c_void, size: u64, out_digest: *mut [u8; 32]) { + let digest = crate::FixedChunk::from_data(unsafe { + std::slice::from_raw_parts(data as *const u8, size as usize) + }); + unsafe { *out_digest = digest.0 }; +} diff --git a/proxmox-protocol/src/lib.rs b/proxmox-protocol/src/lib.rs index 8a2da6cf..acfa8a86 100644 --- a/proxmox-protocol/src/lib.rs +++ b/proxmox-protocol/src/lib.rs @@ -17,3 +17,4 @@ mod types; pub use types::*; pub mod c_client; +pub mod c_chunker;