diff --git a/src/headparse.rs b/src/headparse.rs index e162603..0e5506c 100644 --- a/src/headparse.rs +++ b/src/headparse.rs @@ -155,7 +155,7 @@ enum AdcBlockKeys { #[derive(Debug, Clone)] pub struct SignalSpec { filename: String, - format: SignalFormat, + pub format: SignalFormat, samples_frame: Option, skew: Option, offset: Option, @@ -431,7 +431,17 @@ impl Header { for signal in &self.signal_specs { map.entry(signal.filename.clone()).and_modify(|val: &mut u64| *val += 1 ).or_insert(1); } - return map; + map + } + + pub fn signals_in_file(&self, filename: String) -> Vec<&SignalSpec> { + let mut buffer: Vec<&SignalSpec> = Vec::new(); + for signal in &self.signal_specs { + if signal.filename == filename { + buffer.push(signal); + } + } + buffer } } diff --git a/src/main.rs b/src/main.rs index ace1a41..42f7776 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,16 +1,17 @@ -use std::{env::{self}, path::Path}; +use std::{env::{self}, os::linux::raw, path::Path, str::FromStr}; use std::fs; pub mod headparse; // The HEAder parsing pub mod signal_data; -use crate::{headparse::Header, signal_data::SignalData}; +use crate::{headparse::{Header, SignalSpec}, signal_data::SignalData}; /// Use for handling possible formats of the WFDB data -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq)] enum SignalFormat { Format16 = 16, Format212 = 212, + Invalid = -1, Unimpl = 0 } @@ -64,7 +65,7 @@ fn main() -> Result<(), String>{ } } - let parsed_signals = get_all_data(header, path_parent); + let parsed_signal_result = get_all_data(header, path_parent); println!("Hello, world!"); Ok(()) @@ -75,14 +76,79 @@ fn help() { println!("\nUse in the format \"wfdb_corrosion (.hea filename)\"") } -fn get_signal_data(spec: headparse::SignalSpec, offset: u64, data_length: usize) -> SignalData { +fn get_signal_data(spec: &SignalSpec, offset: u64, data_length: usize, raw: &Vec) -> SignalData { todo!() } -fn get_all_data(header: Header, header_root: String) -> Vec { +fn get_all_data(header: Header, header_root: String) -> Result, String> { let signal_counts = header.signals_per_file(); - for (filename, sigcount) in signal_counts { + for (fname, sigcount) in signal_counts { + let mut full = header_root.to_owned(); // Consider refactoring these to avoid this massive amount of ownership bs + full.push('/'); + let fname = fname.to_owned(); + full.push_str(&fname); + let filepath = Path::new(&full); + if !filepath.is_file() { + return Err("Error: Could not open signal .dat file. Check if the + header points to the right .dat file and if files are present".to_string()); + } + if filepath.extension().unwrap() != "dat" { + println!("warn: Header file defines signal files with an extension + other than .dat. + Check if the header points to the right files, reading will continue + but correct data is not guaranteed"); + } + + // Time to actually do the work + let signals = header.signals_in_file(fname); + let format = file_signal_format_check(signals); + if format == SignalFormat::Invalid { + return Err("Error: Signals in single file use multiple formats. + Is your header file correctly formatted?".to_string()); + } + if format == SignalFormat::Unimpl { + println!("Warn: Signals in single file use an unimplemented format, + and will be ignored"); + continue; + } + + let raw_bytes = fs::read(filepath).unwrap(); + + match format { + SignalFormat::Format16 => { + let mut buffer: u64 = 0; + let mut do_append = false; + let mut raw_converted: Vec = Vec::with_capacity(raw_bytes.len() / 2); + + for byte in raw_bytes { + if do_append { + buffer = (buffer & 0xFF) + (byte as u64) << 8; + raw_converted.push(buffer); + do_append = false; + } else { + buffer = byte as u64; + do_append = true; + } + } + dbg!(raw_converted); + }, + _ => { + panic!("Somehow reached actual file and format processing with + unimplemented format. Please make a bug report") + } + } } todo!() +} + +fn file_signal_format_check(signals: Vec<&SignalSpec>) -> SignalFormat { + let first_sig = signals[0]; + let format = first_sig.format; + for sig in signals { + if sig.format != format { + return SignalFormat::Invalid; + } + } + return format; } \ No newline at end of file diff --git a/src/signal_data.rs b/src/signal_data.rs index 9ca1a86..93b9701 100644 --- a/src/signal_data.rs +++ b/src/signal_data.rs @@ -45,4 +45,9 @@ impl SignalData { let mut to_add: Vec = data; to_add.append(&mut self.values); } +} + +pub struct SignalDataRaw { + name: String, + raw_data: Vec } \ No newline at end of file