use std::ffi::c_void;
use crate::error::{check, Error, Result};
use crate::generated::DataPacket;
use crate::object::Interface;
use crate::readers::Sample;
use crate::sys;
impl DataPacket {
fn buffer(&self, op: &'static str) -> Result<*mut c_void> {
let mut address: *mut c_void = std::ptr::null_mut();
check(
unsafe { (sys::api().daqDataPacket_getData)(self.as_raw() as *mut _, &mut address) },
op,
)?;
Ok(address)
}
fn expect_sample_type(&self, expected: sys::SampleType, op: &'static str) -> Result<()> {
let descriptor = self.data_descriptor()?.ok_or_else(|| {
Error::new(
sys::OPENDAQ_ERR_INVALIDSTATE,
op,
Some("packet has no data descriptor".into()),
)
})?;
let actual = descriptor.sample_type()?;
if actual != expected {
return Err(Error::new(
sys::OPENDAQ_ERR_INVALIDTYPE,
op,
Some(format!("packet holds {actual:?} samples, not {expected:?}")),
));
}
Ok(())
}
pub fn data<V: Sample>(&self) -> Result<Vec<V>> {
let op = "daqDataPacket_getData";
self.expect_sample_type(V::SAMPLE_TYPE, op)?;
let count = self.sample_count()?;
let buffer = self.buffer(op)?;
if buffer.is_null() {
return Ok(Vec::new());
}
let mut values = vec![V::default(); count];
unsafe {
std::ptr::copy_nonoverlapping(buffer as *const V, values.as_mut_ptr(), count);
}
Ok(values)
}
pub fn set_data<V: Sample>(&self, samples: &[V]) -> Result<()> {
let op = "daqDataPacket_getData";
self.expect_sample_type(V::SAMPLE_TYPE, op)?;
let count = self.sample_count()?;
if samples.len() > count {
return Err(Error::new(
sys::OPENDAQ_ERR_OUTOFRANGE,
op,
Some(format!(
"{} samples do not fit a packet of {count}",
samples.len()
)),
));
}
let buffer = self.buffer(op)?;
if buffer.is_null() {
return Err(Error::new(
sys::OPENDAQ_ERR_INVALIDSTATE,
op,
Some("packet has no buffer".into()),
));
}
unsafe {
std::ptr::copy_nonoverlapping(samples.as_ptr(), buffer as *mut V, samples.len());
}
Ok(())
}
pub fn raw_data(&self) -> Result<Vec<u8>> {
let op = "daqDataPacket_getRawData";
let mut address: *mut c_void = std::ptr::null_mut();
check(
unsafe { (sys::api().daqDataPacket_getRawData)(self.as_raw() as *mut _, &mut address) },
op,
)?;
let size = self.raw_data_size()?;
if address.is_null() || size == 0 {
return Ok(Vec::new());
}
let mut bytes = vec![0u8; size];
unsafe {
std::ptr::copy_nonoverlapping(address as *const u8, bytes.as_mut_ptr(), size);
}
Ok(bytes)
}
}