use indexmap::{IndexMap, IndexSet};
use std::fs;
use std::fs::File;
use std::io::{BufReader, Seek, SeekFrom};
use std::path::Path;
pub mod error;
use crate::channel_iter::ChannelDataIter;
use crate::data_type::TdmsTimestamp;
use crate::TdmsError::{
General, InvalidDAQmxDataIndex, InvalidSegment, StringConversionError, UnknownDataType,
};
pub use error::TdmsError;
use segment::Endianness::{Big, Little};
use segment::{Channel, Endianness, Segment};
pub mod channel_iter;
pub mod data_type;
pub mod segment;
#[cfg(test)]
mod tests;
#[derive(Debug, Clone)]
pub struct TDMSFile<'a> {
pub segments: Vec<Segment>,
path: &'a Path,
}
impl<'a> TDMSFile<'a> {
pub fn from_path(path: &'a Path) -> Result<Self, TdmsError> {
let metadata = fs::metadata(path)?;
let file = File::open(path)?;
let mut reader = BufReader::with_capacity(4096, file);
let mut segments: Vec<Segment> = vec![];
let mut i = 0;
loop {
let previous_segment = if i == 0 { None } else { segments.get(i - 1) };
let segment = Segment::new(&mut reader, previous_segment)?;
if segment.end_pos == metadata.len() {
segments.push(segment);
break;
}
reader.seek(SeekFrom::Start(segment.end_pos))?;
segments.push(segment);
i += 1;
}
return Ok(TDMSFile { segments, path });
}
pub fn groups(&self) -> Vec<String> {
let mut map: IndexSet<String> = IndexSet::new();
for segment in &self.segments {
for (group, _) in &segment.groups {
map.insert(String::from(group));
}
}
return Vec::from_iter(map);
}
pub fn channels(&self, group_path: &str) -> IndexMap<String, &Channel> {
let mut map: IndexMap<String, &Channel> = IndexMap::new();
for segment in &self.segments {
let channel_map = match segment.groups.get(group_path) {
Some(m) => m,
None => &None,
};
let channel_map = match channel_map {
None => continue,
Some(m) => m,
};
for (channel_path, channel) in channel_map {
map.insert(String::from(channel_path), channel);
}
}
return map;
}
pub fn channel_data_double_float(
&self,
channel: &'a Channel,
) -> Result<ChannelDataIter<f64, File>, TdmsError> {
let vec = self.load_segments(channel.group_path.as_str(), channel.path.as_str());
let reader = BufReader::with_capacity(4096, File::open(self.path)?);
return ChannelDataIter::new(vec, channel, reader);
}
pub fn channel_data_single_float(
&self,
channel: &'a Channel,
) -> Result<ChannelDataIter<f32, File>, TdmsError> {
let vec = self.load_segments(channel.group_path.as_str(), channel.path.as_str());
let reader = BufReader::with_capacity(4096, File::open(self.path)?);
return ChannelDataIter::new(vec, channel, reader);
}
pub fn channel_data_complex_double_float(
&self,
channel: &'a Channel,
) -> Result<ChannelDataIter<f64, File>, TdmsError> {
let vec = self.load_segments(channel.group_path.as_str(), channel.path.as_str());
let reader = BufReader::with_capacity(4096, File::open(self.path)?);
return ChannelDataIter::new(vec, channel, reader);
}
pub fn channel_data_complex_single_float(
&self,
channel: &'a Channel,
) -> Result<ChannelDataIter<f32, File>, TdmsError> {
let vec = self.load_segments(channel.group_path.as_str(), channel.path.as_str());
let reader = BufReader::with_capacity(4096, File::open(self.path)?);
return ChannelDataIter::new(vec, channel, reader);
}
pub fn channel_data_double_float_unit(
&self,
channel: &'a Channel,
) -> Result<ChannelDataIter<f64, File>, TdmsError> {
let vec = self.load_segments(channel.group_path.as_str(), channel.path.as_str());
let reader = BufReader::with_capacity(4096, File::open(self.path)?);
return ChannelDataIter::new(vec, channel, reader);
}
pub fn channel_data_single_float_unit(
&self,
channel: &'a Channel,
) -> Result<ChannelDataIter<f32, File>, TdmsError> {
let vec = self.load_segments(channel.group_path.as_str(), channel.path.as_str());
let reader = BufReader::with_capacity(4096, File::open(self.path)?);
return ChannelDataIter::new(vec, channel, reader);
}
pub fn channel_data_i8(
&self,
channel: &'a Channel,
) -> Result<ChannelDataIter<i8, File>, TdmsError> {
let vec = self.load_segments(channel.group_path.as_str(), channel.path.as_str());
let reader = BufReader::with_capacity(4096, File::open(self.path)?);
return ChannelDataIter::new(vec, channel, reader);
}
pub fn channel_data_i16(
&self,
channel: &'a Channel,
) -> Result<ChannelDataIter<i16, File>, TdmsError> {
let vec = self.load_segments(channel.group_path.as_str(), channel.path.as_str());
let reader = BufReader::with_capacity(4096, File::open(self.path)?);
return ChannelDataIter::new(vec, channel, reader);
}
pub fn channel_data_i32(
&self,
channel: &'a Channel,
) -> Result<ChannelDataIter<i32, File>, TdmsError> {
let vec = self.load_segments(channel.group_path.as_str(), channel.path.as_str());
let reader = BufReader::with_capacity(4096, File::open(self.path)?);
return ChannelDataIter::new(vec, channel, reader);
}
pub fn channel_data_i64(
&self,
channel: &'a Channel,
) -> Result<ChannelDataIter<i64, File>, TdmsError> {
let vec = self.load_segments(channel.group_path.as_str(), channel.path.as_str());
let reader = BufReader::with_capacity(4096, File::open(self.path)?);
return ChannelDataIter::new(vec, channel, reader);
}
pub fn channel_data_u8(
&self,
channel: &'a Channel,
) -> Result<ChannelDataIter<u8, File>, TdmsError> {
let vec = self.load_segments(channel.group_path.as_str(), channel.path.as_str());
let reader = BufReader::with_capacity(4096, File::open(self.path)?);
return ChannelDataIter::new(vec, channel, reader);
}
pub fn channel_data_u16(
&self,
channel: &'a Channel,
) -> Result<ChannelDataIter<u16, File>, TdmsError> {
let vec = self.load_segments(channel.group_path.as_str(), channel.path.as_str());
let reader = BufReader::with_capacity(4096, File::open(self.path)?);
return ChannelDataIter::new(vec, channel, reader);
}
pub fn channel_data_u32(
&self,
channel: &'a Channel,
) -> Result<ChannelDataIter<u32, File>, TdmsError> {
let vec = self.load_segments(channel.group_path.as_str(), channel.path.as_str());
let reader = BufReader::with_capacity(4096, File::open(self.path)?);
return ChannelDataIter::new(vec, channel, reader);
}
pub fn channel_data_u64(
&self,
channel: &'a Channel,
) -> Result<ChannelDataIter<u64, File>, TdmsError> {
let vec = self.load_segments(channel.group_path.as_str(), channel.path.as_str());
let reader = BufReader::with_capacity(4096, File::open(self.path)?);
return ChannelDataIter::new(vec, channel, reader);
}
pub fn channel_data_bool(
&self,
channel: &'a Channel,
) -> Result<ChannelDataIter<bool, File>, TdmsError> {
let vec = self.load_segments(channel.group_path.as_str(), channel.path.as_str());
let reader = BufReader::with_capacity(4096, File::open(self.path)?);
return ChannelDataIter::new(vec, channel, reader);
}
pub fn channel_data_timestamp(
&self,
channel: &'a Channel,
) -> Result<ChannelDataIter<TdmsTimestamp, File>, TdmsError> {
let vec = self.load_segments(channel.group_path.as_str(), channel.path.as_str());
let reader = BufReader::with_capacity(4096, File::open(self.path)?);
return ChannelDataIter::new(vec, channel, reader);
}
pub fn channel_data_string(
&self,
channel: &'a Channel,
) -> Result<ChannelDataIter<String, File>, TdmsError> {
let vec = self.load_segments(channel.group_path.as_str(), channel.path.as_str());
let reader = BufReader::with_capacity(4096, File::open(self.path)?);
return ChannelDataIter::new(vec, channel, reader);
}
fn load_segments(&self, group_path: &str, path: &str) -> Vec<&Segment> {
let mut vec: Vec<&Segment> = vec![];
let mut channel_in_segment: bool = false;
for segment in &self.segments {
match segment.groups.get(group_path) {
None => {
if !segment.has_new_obj_list() && channel_in_segment {
vec.push(&segment)
} else {
channel_in_segment = false
}
}
Some(channels) => match channels {
None => {
if !segment.has_new_obj_list() && channel_in_segment {
vec.push(&segment)
} else {
channel_in_segment = false
}
}
Some(channels) => {
let channel = channels.get(path);
match channel {
None => {
if !segment.has_new_obj_list() && channel_in_segment {
vec.push(&segment)
} else {
channel_in_segment = false
}
}
Some(_) => {
vec.push(&segment);
channel_in_segment = true;
}
}
}
},
}
}
return vec;
}
}