use std::os::raw::c_char;
use std::slice;
use std::sync::Arc;
use crate::ffi::utils::{ForeignObject, SourmashStr};
use crate::prelude::*;
use crate::storage::ZipStorage;
pub struct SourmashZipStorage;
impl ForeignObject for SourmashZipStorage {
type RustObject = Arc<ZipStorage>;
}
ffi_fn! {
unsafe fn zipstorage_new(ptr: *const c_char, insize: usize) -> Result<*mut SourmashZipStorage> {
let path = {
assert!(!ptr.is_null());
let path = slice::from_raw_parts(ptr as *mut u8, insize);
std::str::from_utf8(path)?
};
let zipstorage = ZipStorage::from_file(path)?;
Ok(SourmashZipStorage::from_rust(Arc::new(zipstorage)))
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn zipstorage_free(ptr: *mut SourmashZipStorage) {
unsafe { SourmashZipStorage::drop(ptr) };
}
ffi_fn! {
unsafe fn zipstorage_load(ptr: *const SourmashZipStorage,
path_ptr: *const c_char,
insize: usize,
size: *mut usize) -> Result<*const u8> {
let storage = SourmashZipStorage::as_rust(ptr);
let path = {
assert!(!path_ptr.is_null());
let path = slice::from_raw_parts(path_ptr as *mut u8, insize);
std::str::from_utf8(path)?
};
let buffer = storage.load(path)?;
let b = buffer.into_boxed_slice();
*size = b.len();
Ok(Box::into_raw(b) as *const u8)
}
}
ffi_fn! {
unsafe fn zipstorage_list_sbts(
ptr: *const SourmashZipStorage,
size: *mut usize,
) -> Result<*mut *mut SourmashStr> {
let storage = SourmashZipStorage::as_rust(ptr);
let sbts = storage.list_sbts()?;
let ptr_sigs: Vec<*mut SourmashStr> = sbts
.into_iter()
.map(|x| Box::into_raw(Box::new(SourmashStr::from_string(x))))
.collect();
let b = ptr_sigs.into_boxed_slice();
*size = b.len();
Ok(Box::into_raw(b) as *mut *mut SourmashStr)
}
}
ffi_fn! {
unsafe fn zipstorage_filenames(
ptr: *const SourmashZipStorage,
size: *mut usize,
) -> Result<*mut *mut SourmashStr> {
let storage = SourmashZipStorage::as_rust(ptr);
let files = storage.filenames()?;
let ptr_sigs: Vec<*mut SourmashStr> = files
.into_iter()
.map(|x| Box::into_raw(Box::new(SourmashStr::from_string(x))))
.collect();
let b = ptr_sigs.into_boxed_slice();
*size = b.len();
Ok(Box::into_raw(b) as *mut *mut SourmashStr)
}
}
ffi_fn! {
unsafe fn zipstorage_set_subdir(
ptr: *mut SourmashZipStorage,
path_ptr: *const c_char,
insize: usize,
) -> Result<()> {
let storage = SourmashZipStorage::as_rust_mut(ptr);
let path = {
assert!(!path_ptr.is_null());
let path = slice::from_raw_parts(path_ptr as *mut u8, insize);
std::str::from_utf8(path)?
};
(*Arc::get_mut(storage).unwrap()).set_subdir(path.to_string());
Ok(())
}
}
ffi_fn! {
unsafe fn zipstorage_path(ptr: *const SourmashZipStorage) -> Result<SourmashStr> {
let storage = SourmashZipStorage::as_rust(ptr);
if let Some(ref path) = storage.path() {
Ok(path.clone().into_string().into())
} else {
Ok("".into())
}
}
}
ffi_fn! {
unsafe fn zipstorage_subdir(ptr: *const SourmashZipStorage) -> Result<SourmashStr> {
let storage = SourmashZipStorage::as_rust(ptr);
if let Some(ref path) = storage.subdir() {
Ok(path.clone().into())
} else {
Ok("".into())
}
}
}