use mdflib_sys as ffi;
use std::ffi::{CStr, CString};
use std::ops::Deref;
use std::os::raw::c_char;
use crate::channel::{Channel, ChannelRef};
use crate::metadata::{MetaData, MetaDataRef};
use crate::sourceinformation::{SourceInformation, SourceInformationRef};
#[derive(Debug, Clone, Copy)]
pub struct ChannelGroupRef {
pub(crate) inner: *const ffi::IChannelGroup,
}
impl std::fmt::Display for ChannelGroupRef {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"ChannelGroup {{ index: {}, name: {}, description: {}, nof_samples: {}, channel_count: {} }}",
self.get_index(),
self.get_name(),
self.get_description(),
self.get_nof_samples(),
self.get_channel_count(),
)
}
}
impl ChannelGroupRef {
pub(crate) fn new(inner: *const ffi::IChannelGroup) -> Self {
Self { inner }
}
pub fn as_ptr(&self) -> *const ffi::IChannelGroup {
self.inner
}
pub fn get_index(&self) -> u64 {
unsafe { ffi::ChannelGroupGetIndex(self.inner) }
}
pub fn get_name(&self) -> String {
unsafe {
let mut len = ffi::ChannelGroupGetName(self.inner, std::ptr::null_mut(), 0);
if len == 0 {
return String::new();
}
len += 1; let mut buf = vec![0 as c_char; len as usize];
ffi::ChannelGroupGetName(self.inner, buf.as_mut_ptr(), len);
CStr::from_ptr(buf.as_ptr()).to_string_lossy().into_owned()
}
}
pub fn get_description(&self) -> String {
unsafe {
let mut len = ffi::ChannelGroupGetDescription(self.inner, std::ptr::null_mut(), 0);
if len == 0 {
return String::new();
}
len += 1; let mut buf = vec![0 as c_char; len as usize];
ffi::ChannelGroupGetDescription(self.inner, buf.as_mut_ptr(), len);
CStr::from_ptr(buf.as_ptr()).to_string_lossy().into_owned()
}
}
pub fn get_nof_samples(&self) -> u64 {
unsafe { ffi::ChannelGroupGetNofSamples(self.inner) }
}
pub fn get_channel_count(&self) -> usize {
unsafe { ffi::ChannelGroupGetChannelCount(self.inner) }
}
pub fn get_channel_by_index(&self, index: usize) -> Option<ChannelRef<'_>> {
unsafe {
let ch = ffi::ChannelGroupGetChannelByIndex(self.inner, index);
if ch.is_null() {
None
} else {
Some(ChannelRef::new(ch))
}
}
}
pub fn get_channel(&self, name: &str) -> Option<ChannelRef<'_>> {
let c_name = CString::new(name).unwrap();
unsafe {
let ch = ffi::ChannelGroupGetChannelByName(self.inner, c_name.as_ptr());
if ch.is_null() {
None
} else {
Some(ChannelRef::new(ch))
}
}
}
pub fn get_channels(&self) -> Vec<ChannelRef<'_>> {
let count = self.get_channel_count();
(0..count)
.filter_map(|i| self.get_channel_by_index(i))
.collect()
}
pub fn get_metadata(&self) -> Option<MetaDataRef<'_>> {
unsafe {
let metadata = ffi::ChannelGroupGetMetaData(self.inner);
if metadata.is_null() {
None
} else {
Some(MetaDataRef::new(metadata))
}
}
}
pub fn get_source_information(&self) -> Option<SourceInformationRef<'_>> {
unsafe {
let source_info = ffi::ChannelGroupGetSourceInformation(self.inner);
if source_info.is_null() {
None
} else {
Some(SourceInformationRef::new(source_info))
}
}
}
pub fn get_bus_type(&self) -> u8 {
unsafe { ffi::ChannelGroupGetBusType(self.inner) }
}
}
#[derive(Debug)]
pub struct ChannelGroup {
pub(crate) inner: *mut ffi::IChannelGroup,
inner_ref: ChannelGroupRef,
}
impl ChannelGroup {
pub(crate) fn new(inner: *mut ffi::IChannelGroup) -> Self {
Self {
inner,
inner_ref: ChannelGroupRef::new(inner),
}
}
pub fn set_name(&mut self, name: &str) {
let c_name = CString::new(name).unwrap();
unsafe {
ffi::ChannelGroupSetName(self.inner, c_name.as_ptr());
}
}
pub fn set_description(&mut self, description: &str) {
let c_description = CString::new(description).unwrap();
unsafe {
ffi::ChannelGroupSetDescription(self.inner, c_description.as_ptr());
}
}
pub fn set_nof_samples(&mut self, samples: u64) {
unsafe {
ffi::ChannelGroupSetNofSamples(self.inner, samples);
}
}
pub fn create_channel(&mut self) -> Option<Channel<'_>> {
unsafe {
let ch = ffi::ChannelGroupCreateChannel(self.inner);
if ch.is_null() {
None
} else {
Some(Channel::new(ch))
}
}
}
pub fn create_metadata(&mut self) -> Option<MetaData<'_>> {
unsafe {
let metadata = ffi::ChannelGroupCreateMetaData(self.inner);
if metadata.is_null() {
None
} else {
Some(MetaData::new(metadata))
}
}
}
pub fn create_source_information(&mut self) -> Option<SourceInformation<'_>> {
unsafe {
let source_info = ffi::ChannelGroupCreateSourceInformation(self.inner);
if source_info.is_null() {
None
} else {
Some(SourceInformation::new(source_info))
}
}
}
}
impl std::fmt::Display for ChannelGroup {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.inner_ref)
}
}
impl Deref for ChannelGroup {
type Target = ChannelGroupRef;
fn deref(&self) -> &Self::Target {
&self.inner_ref
}
}