use std::ffi::CStr;
use std::ptr::NonNull;
use crate::nd::DimVec;
use crate::{CParams, DParams, Error};
#[derive(Debug, Clone, Default)]
pub struct NdarrayParams {
pub(crate) cparams: CParams,
pub(crate) dparams: DParams,
pub(crate) chunkshape: Option<DimVec<i32>>,
pub(crate) blockshape: Option<DimVec<i32>>,
}
impl NdarrayParams {
pub fn new() -> Self {
Self::default()
}
pub fn cparams(&mut self, cparams: CParams) -> &mut Self {
self.cparams = cparams;
self
}
pub fn dparams(&mut self, dparams: DParams) -> &mut Self {
self.dparams = dparams;
self
}
pub fn chunkshape(&mut self, chunkshape: Option<&[usize]>) -> &mut Self {
self.chunkshape = chunkshape
.map(|shape| DimVec::from_slice_fn(shape, |s| *s as i32).expect("Too many dimensions"));
self
}
pub(crate) fn chunkshape_required(&self) -> Result<&DimVec<i32>, Error> {
self.chunkshape.as_ref().ok_or_else(|| {
crate::trace!("Chunkshape is required");
Error::InvalidParam
})
}
pub fn blockshape(&mut self, blockshape: Option<&[usize]>) -> &mut Self {
self.blockshape = blockshape
.map(|shape| DimVec::from_slice_fn(shape, |s| *s as i32).expect("Too many dimensions"));
self
}
pub(crate) fn blockshape_required(&self) -> Result<&DimVec<i32>, Error> {
self.blockshape.as_ref().ok_or_else(|| {
crate::trace!("Blockshape is required");
Error::InvalidParam
})
}
}
pub(crate) struct Ctx(NonNull<blosc2_sys::b2nd_context_t>);
impl Ctx {
pub(crate) fn new(
storage: &blosc2_sys::blosc2_storage,
shape: &[i64],
chunkshape: &[i32],
blockshape: &[i32],
dtype: &CStr,
dtype_format: i8,
) -> Result<Self, Error> {
let ndim = shape.len();
if chunkshape.len() != ndim || blockshape.len() != ndim {
crate::trace!(
"Chunkshape {} and blockshape {} lengths must match shape dimension: {}",
chunkshape.len(),
blockshape.len(),
ndim
);
return Err(Error::InvalidParam);
}
let metalayers = [];
let ctx = unsafe {
blosc2_sys::b2nd_create_ctx(
storage as *const _,
ndim as i8,
shape.as_ptr(),
chunkshape.as_ptr(),
blockshape.as_ptr(),
dtype.as_ptr(),
dtype_format,
metalayers.as_ptr(),
metalayers.len() as i32,
)
};
Ok(Ctx(NonNull::new(ctx.cast()).ok_or(Error::Failure)?))
}
pub(crate) fn as_ptr(&self) -> *mut blosc2_sys::b2nd_context_t {
self.0.as_ptr()
}
}
impl Drop for Ctx {
fn drop(&mut self) {
unsafe { blosc2_sys::b2nd_free_ctx(self.0.as_ptr()) };
}
}