use crate::{
datagroup::{DataGroup, DataGroupRef},
error::{MdfError, Result},
header::MdfHeaderRef,
MdfFileRef,
};
use mdflib_sys::*;
use std::ffi::CString;
use std::path::Path;
pub struct MdfReader {
inner: *mut mdflib_sys::MdfReader,
}
impl MdfReader {
pub fn new<P: AsRef<Path>>(path: P) -> Result<Self> {
let path_str = path.as_ref().to_str().unwrap();
let c_path = CString::new(path_str)?;
unsafe {
let reader = MdfReaderInit(c_path.as_ptr());
if reader.is_null() {
return Err(MdfError::FileOpen(path_str.to_string()));
}
Ok(MdfReader { inner: reader })
}
}
pub fn is_ok(&self) -> bool {
unsafe { MdfReaderIsOk(self.inner) }
}
pub fn is_finalized(&self) -> bool {
unsafe { MdfReaderIsFinalized(self.inner) }
}
pub fn open(&mut self) -> Result<()> {
unsafe {
if MdfReaderOpen(self.inner) {
Ok(())
} else {
Err(MdfError::FileOpen("Failed to open file".to_string()))
}
}
}
pub fn close(&mut self) {
unsafe {
MdfReaderClose(self.inner);
}
}
pub fn get_file(&self) -> Option<MdfFileRef> {
unsafe {
let file = MdfReaderGetFile(self.inner);
if file.is_null() {
None
} else {
Some(MdfFileRef::new(file))
}
}
}
pub fn read_header(&mut self) -> Result<()> {
unsafe {
if MdfReaderReadHeader(self.inner) {
Ok(())
} else {
Err(MdfError::HeaderRead)
}
}
}
pub fn read_measurement_info(&mut self) -> Result<()> {
unsafe {
if MdfReaderReadMeasurementInfo(self.inner) {
Ok(())
} else {
Err(MdfError::MeasurementInfo)
}
}
}
pub fn get_header(&self) -> Option<MdfHeaderRef> {
unsafe {
let header = MdfReaderGetHeader(self.inner);
if header.is_null() {
None
} else {
Some(MdfHeaderRef::new(header))
}
}
}
pub fn read_everything_but_data(&mut self) -> Result<()> {
unsafe {
if MdfReaderReadEverythingButData(self.inner) {
Ok(())
} else {
Err(MdfError::DataRead)
}
}
}
pub fn get_data_group_count(&self) -> usize {
unsafe { MdfReaderGetDataGroupCount(self.inner) }
}
pub fn get_data_group(&self, index: usize) -> Option<DataGroupRef> {
unsafe {
let dg = MdfReaderGetDataGroup(self.inner, index);
if dg.is_null() {
None
} else {
Some(DataGroupRef::new(dg))
}
}
}
pub fn read_data(&mut self, group: &mut DataGroup) -> Result<()> {
unsafe {
if MdfReaderReadData(self.inner, group.inner) {
Ok(())
} else {
Err(MdfError::DataRead)
}
}
}
}
impl Drop for MdfReader {
fn drop(&mut self) {
if !self.inner.is_null() {
unsafe {
MdfReaderUnInit(self.inner);
}
}
}
}
unsafe impl Send for MdfReader {}
#[cfg(test)]
mod tests {
use super::*;
use tempfile::NamedTempFile;
#[test]
#[ignore] fn test_reader_creation() {
let temp_file = NamedTempFile::new().unwrap();
let reader = MdfReader::new(temp_file.path());
match reader {
Ok(_) => println!("Reader created successfully"),
Err(e) => println!("Expected error: {e}"),
}
}
}