1use std::fs::{File, OpenOptions};
2use std::io::{BufRead, BufReader, Cursor, Seek, SeekFrom, Write};
3use std::iter::repeat_n;
4use std::os::unix::fs::FileExt;
5use std::path::{Path, PathBuf};
6
7use crate::EDFSpecifications;
8use crate::error::edf_error::EDFError;
9use crate::headers::annotation_list::AnnotationList;
10use crate::headers::edf_header::EDFHeader;
11use crate::headers::signal_header::SignalHeader;
12use crate::record::{Record, SpanningRecord};
13use crate::save::{SaveInstruction, SaveValue, normalize_instructions};
14use crate::utils::take_vec;
15
16#[derive(Debug, Default, Clone, PartialEq)]
20pub enum RecordDeleteStrategy {
21 Continuous,
29
30 #[default]
35 Discontinuous,
36}
37
38#[derive(Debug, Default, Clone, PartialEq)]
42pub enum SaveMode {
43 #[default]
47 Default,
48
49 Recording,
55}
56
57pub struct EDFFile {
58 pub header: EDFHeader,
59 path: PathBuf,
60 reader: BufReader<File>,
61 record_read_offset_ns: u128,
62 instructions: Vec<SaveInstruction>,
63 signal_instructions: Vec<SaveInstruction>,
64 record_counter: usize,
65 signal_counter: usize,
66 record_delete_strategy: RecordDeleteStrategy,
67 save_mode: SaveMode,
68}
69
70impl EDFFile {
71 pub fn open<P: AsRef<Path>>(path: P) -> Result<Self, EDFError> {
72 let file = File::open(&path).map_err(EDFError::FileReadError)?;
73 let mut reader = BufReader::new(file);
74 let header = EDFHeader::deserialize(&mut reader)?;
75
76 Ok(Self {
77 record_counter: header.record_count.unwrap_or(0),
78 signal_counter: header.signal_count,
79 path: path.as_ref().to_path_buf(),
80 record_read_offset_ns: 0,
81 signal_instructions: Vec::new(),
82 instructions: Vec::new(),
83 header,
84 reader,
85 record_delete_strategy: RecordDeleteStrategy::default(),
86 save_mode: SaveMode::default(),
87 })
88 }
89
90 pub fn new<P: AsRef<Path>>(path: P) -> Result<Self, EDFError> {
91 if path.as_ref().exists() {
93 return Err(EDFError::FileAlreadyExists);
94 }
95 File::create(&path).map_err(EDFError::FileWriteError)?;
96
97 let file = File::open(&path).map_err(EDFError::FileReadError)?;
98 let reader = BufReader::new(file);
99 let header = EDFHeader::new();
100
101 Ok(Self {
102 header,
103 reader,
104 path: path.as_ref().to_path_buf(),
105 record_read_offset_ns: 0,
106 signal_counter: 0,
107 record_counter: 0,
108 signal_instructions: Vec::new(),
109 instructions: vec![SaveInstruction::WriteHeader],
110 record_delete_strategy: RecordDeleteStrategy::default(),
111 save_mode: SaveMode::default(),
112 })
113 }
114
115 pub fn set_save_mode(&mut self, mode: SaveMode) {
118 self.save_mode = mode;
119 self.instructions.insert(0, SaveInstruction::WriteHeader);
120 }
121
122 pub fn insert_signal(&mut self, index: usize, signal: SignalHeader) -> Result<(), EDFError> {
123 let instruction = SaveInstruction::Insert(index, SaveValue::Signal(signal.clone()));
124 self.header.modify_signals().insert(index, signal);
125
126 self.patch_records_with_instruction(instruction.clone())?;
128
129 self.signal_counter += 1;
131 self.signal_instructions.push(instruction);
132
133 Ok(())
134 }
135
136 pub fn update_signal(&mut self, index: usize, signal: SignalHeader) -> Result<(), EDFError> {
137 let instruction = SaveInstruction::Update(index, SaveValue::Signal(signal.clone()));
138 self.header.modify_signals()[index] = signal;
139
140 self.patch_records_with_instruction(instruction.clone())?;
142
143 self.signal_instructions.push(instruction);
145
146 Ok(())
147 }
148
149 pub fn remove_signal(&mut self, index: usize) -> Result<(), EDFError> {
150 if self.signal_counter <= index {
151 return Err(EDFError::IndexOutOfBounds);
152 }
153 let instruction = SaveInstruction::Remove(index);
154 self.header.modify_signals().remove(index);
155
156 self.patch_records_with_instruction(instruction.clone())?;
158
159 self.signal_counter -= 1;
161 self.signal_instructions.push(instruction);
162
163 Ok(())
164 }
165
166 fn patch_records_with_instruction(
167 &mut self,
168 instruction: SaveInstruction,
169 ) -> Result<(), EDFError> {
170 let instruction_listed = vec![instruction];
171 for record in self.instructions.iter_mut().filter_map(|i| match i {
172 SaveInstruction::Append(SaveValue::Record(record))
173 | SaveInstruction::Insert(_, SaveValue::Record(record))
174 | SaveInstruction::Update(_, SaveValue::Record(record)) => Some(record),
175 _ => None,
176 }) {
177 record.patch_record(&instruction_listed)?;
178 }
179
180 Ok(())
181 }
182
183 pub fn insert_record(&mut self, index: usize, record: Record) -> Result<(), EDFError> {
184 if !record.matches_signals(self.header.get_signals()) {
185 return Err(EDFError::InvalidRecordSignals);
186 }
187
188 self.record_counter += 1;
189 self.instructions
190 .push(SaveInstruction::Insert(index, SaveValue::Record(record)));
191
192 Ok(())
193 }
194
195 pub fn update_record(&mut self, index: usize, record: Record) -> Result<(), EDFError> {
196 if !record.matches_signals(self.header.get_signals()) {
197 return Err(EDFError::InvalidRecordSignals);
198 }
199
200 self.instructions
201 .push(SaveInstruction::Update(index, SaveValue::Record(record)));
202
203 Ok(())
204 }
205
206 pub fn append_record(&mut self, record: Record) -> Result<(), EDFError> {
207 if !record.matches_signals(self.header.get_signals()) {
208 return Err(EDFError::InvalidRecordSignals);
209 }
210
211 self.record_counter += 1;
212 self.instructions
213 .push(SaveInstruction::Append(SaveValue::Record(record)));
214
215 Ok(())
216 }
217
218 pub fn remove_record(&mut self, index: usize) -> Result<(), EDFError> {
223 if self.record_counter <= index {
224 return Err(EDFError::IndexOutOfBounds);
225 }
226
227 self.record_counter -= 1;
228 self.instructions.push(SaveInstruction::Remove(index));
229
230 Ok(())
231 }
232
233 fn records_match_signals(&self) -> bool {
234 !self
235 .instructions
236 .iter()
237 .filter_map(|i| match i {
238 SaveInstruction::Append(SaveValue::Record(record))
239 | SaveInstruction::Insert(_, SaveValue::Record(record))
240 | SaveInstruction::Update(_, SaveValue::Record(record)) => Some(record),
241 _ => None,
242 })
243 .any(|record| !record.matches_signals(self.header.get_signals()))
244 }
245
246 pub fn save(&mut self) -> Result<(), EDFError> {
247 let mut file = OpenOptions::new()
248 .read(true)
249 .write(true)
250 .create(true)
251 .open(&self.path)
252 .map_err(EDFError::FileWriteError)?;
253
254 let initial_filesize = file.metadata().map_err(EDFError::FileWriteError)?.len();
255 let initial_signal_count = self.header.signal_count;
256 let initial_record_count = self.header.record_count.unwrap_or(0);
257 let initial_signals = self.header.signals.clone();
258 let initial_record_duration = self.header.record_duration;
259 let initial_header_size = self.header.header_bytes as u64;
260 let initial_record_bytes = self.header.get_initial_record_bytes();
261
262 if self.save_mode == SaveMode::Default {
266 self.header.record_count = Some(self.record_counter);
267 }
268
269 if let Some(updated) = self.header.updated_signals.take() {
271 self.header.signals = updated;
272 }
273 self.header.signal_count = self.header.signals.len();
274
275 if self.header.signal_count == 0 {
277 self.header.record_count = self.header.record_count.map(|_| 0);
278 }
279
280 self.header.header_bytes = self.header.calculate_header_bytes();
282 let new_record_bytes = self.header.data_record_bytes();
283
284 let header_size_diff = self.header.header_bytes as i64 - initial_header_size as i64;
286 let header_changed =
287 *self.header.get_initial_header_sha256() != self.header.get_sha256()?;
288 let header_instruct_positions = self
289 .instructions
290 .iter()
291 .enumerate()
292 .filter_map(|(i, x)| (*x == SaveInstruction::WriteHeader).then_some(i))
293 .collect::<Vec<_>>();
294 if header_instruct_positions.len() >= 1 && header_instruct_positions[0] != 0 {
295 for i in header_instruct_positions.iter().rev() {
296 self.instructions.remove(*i);
297 }
298 self.instructions.insert(0, SaveInstruction::WriteHeader);
299 } else if header_instruct_positions.len() >= 1 {
300 for i in header_instruct_positions.iter().skip(1).rev() {
301 self.instructions.remove(*i);
302 }
303 } else if header_instruct_positions.is_empty() && header_changed {
304 self.instructions.insert(0, SaveInstruction::WriteHeader);
305 }
306
307 let initial_read_position = self
309 .reader
310 .stream_position()
311 .map_err(EDFError::FileWriteError)?;
312 let initial_record_position = if initial_record_bytes == 0 {
313 None
314 } else {
315 initial_read_position
316 .checked_sub(initial_header_size)
317 .map(|pos| pos % initial_record_bytes as u64)
318 };
319
320 if self.instructions.is_empty() && self.signal_instructions.is_empty() {
322 return Ok(());
323 }
324
325 let instructions = normalize_instructions(&self.instructions, initial_record_count);
327 let signal_instructions =
328 normalize_instructions(&self.signal_instructions, initial_signal_count);
329
330 if !self.records_match_signals() {
332 return Err(EDFError::InvalidRecordSignals);
333 }
334
335 if instructions.is_empty() && signal_instructions.is_empty() {
338 self.instructions.clear();
339 return Ok(());
340 }
341
342 let removes_middle_record = instructions.iter().any(|i| matches!(i, SaveInstruction::Remove(idx) if *idx > 0 && *idx < self.record_counter - 1));
344 if self.header.specification == EDFSpecifications::EDFPlus
345 && self.header.is_continuous
346 && removes_middle_record
347 && self.record_delete_strategy == RecordDeleteStrategy::Discontinuous
348 {
349 self.header.is_continuous = false;
350 }
351
352 let patch_trailing_records = !signal_instructions.is_empty();
353 let mut overwrite_counter = header_size_diff;
354 let mut overwrite_buffer = Vec::new();
355 let mut record_counter = instructions
356 .iter()
357 .filter(|i| i.has_record_index())
358 .map(SaveInstruction::record_index)
359 .next()
360 .unwrap_or(0);
361 let mut instruction_idx = 0;
362
363 if patch_trailing_records {
364 record_counter = 0;
365 }
366
367 file.seek(SeekFrom::Start(
369 initial_header_size + record_counter as u64 * initial_record_bytes as u64,
370 ))
371 .map_err(EDFError::FileWriteError)?;
372
373 loop {
375 let instruct = match instructions.get(instruction_idx) {
376 Some(instruct) => instruct,
377 None => {
378 if patch_trailing_records {
379 &SaveInstruction::Patch
380 } else {
381 break;
382 }
383 }
384 };
385
386 match instruct {
387 SaveInstruction::WriteHeader => {
388 instruction_idx += 1;
389
390 file.seek(SeekFrom::Start(0))
394 .map_err(EDFError::FileWriteError)?;
395 if let Ok(read_length) = usize::try_from(overwrite_counter)
396 && read_length > 0
397 {
398 let read_max = initial_filesize.saturating_sub(initial_header_size);
399 let read_length = read_length.min(read_max as usize);
400 if read_length > 0 {
401 let mut buffer = vec![0; read_length]; file.read_exact_at(&mut buffer, initial_header_size)
403 .map_err(EDFError::FileWriteError)?;
404 overwrite_buffer.append(&mut buffer);
405 }
406 }
407
408 file.write_all(self.header.serialize()?.as_bytes())
409 .map_err(EDFError::FileWriteError)?;
410
411 if overwrite_counter != 0 {
413 record_counter = 0;
414 } else if !patch_trailing_records {
415 file.seek(SeekFrom::Start(
416 initial_header_size
417 + record_counter as u64 * initial_record_bytes as u64,
418 ))
419 .map_err(EDFError::FileWriteError)?;
420 }
421 }
422 SaveInstruction::Remove(idx) if *idx == record_counter => {
423 instruction_idx += 1;
424 _ = overwrite_buffer
425 .drain(0..initial_record_bytes.min(overwrite_buffer.len()))
426 .count();
427 overwrite_counter -= initial_record_bytes as i64;
428 }
429 SaveInstruction::Insert(idx, SaveValue::Record(value))
430 if *idx == record_counter =>
431 {
432 instruction_idx += 1;
433 record_counter += 1;
434
435 let read_offset = if overwrite_counter < 0 {
437 overwrite_counter.abs()
438 } else {
439 0
440 } as u64;
441 let current_file_position =
442 file.stream_position().map_err(EDFError::FileWriteError)? + read_offset;
443 let read_max = initial_filesize.saturating_sub(current_file_position);
444 if let Ok(new_buffer_length) =
445 usize::try_from(overwrite_counter + new_record_bytes as i64)
446 && new_buffer_length > 0
447 {
448 let read_length = new_buffer_length - overwrite_buffer.len(); let read_length = read_length.min(read_max as usize);
450 if read_length > 0 {
451 let mut buffer = vec![0; read_length]; file.read_exact_at(&mut buffer, current_file_position)
453 .map_err(EDFError::FileWriteError)?;
454 overwrite_buffer.append(&mut buffer);
455 }
456 }
457
458 file.write_all(&value.serialize()?)
459 .map_err(EDFError::FileWriteError)?;
460 overwrite_counter += new_record_bytes.min(read_max as usize) as i64;
461 }
462 SaveInstruction::Update(idx, SaveValue::Record(value))
463 if *idx == record_counter =>
464 {
465 instruction_idx += 1;
466 record_counter += 1;
467
468 let buffer_read_count = overwrite_buffer
469 .drain(0..initial_record_bytes.min(overwrite_buffer.len()))
470 .count();
471 let disk_read_count = initial_record_bytes.saturating_sub(buffer_read_count);
472
473 let read_offset = if overwrite_counter < 0 {
474 overwrite_counter.abs()
475 } else {
476 0
477 } as u64;
478 let buffered_offset = if overwrite_counter > 0 {
479 overwrite_counter
480 } else {
481 0
482 } as u64;
483 let current_file_position =
484 file.stream_position().map_err(EDFError::FileWriteError)? + read_offset;
485
486 let read_max = initial_filesize.saturating_sub(current_file_position);
488 let target_read_length =
489 overwrite_counter + new_record_bytes as i64 - buffered_offset as i64;
490 let read_length = u64::try_from(target_read_length)
491 .map(|len| len.min(read_max).saturating_sub(disk_read_count as u64))
492 .unwrap_or(0) as usize;
493 if read_length > 0 {
494 let mut buffer = vec![0; read_length]; file.read_exact_at(
496 &mut buffer,
497 current_file_position + disk_read_count as u64,
498 )
499 .map_err(EDFError::FileWriteError)?;
500 overwrite_buffer.append(&mut buffer);
501 }
502
503 let exceed = if target_read_length.max(0) as u64 > read_max {
505 target_read_length.max(0) as u64 - read_max
506 } else {
507 0
508 };
509 overwrite_counter += new_record_bytes as i64
510 - disk_read_count as i64
511 - buffer_read_count as i64
512 - exceed as i64;
513
514 file.write_all(&value.serialize()?)
515 .map_err(EDFError::FileWriteError)?;
516 }
517 SaveInstruction::Patch | _ => {
518 if record_counter == self.record_counter {
520 break;
521 }
522
523 if overwrite_counter == 0 && !patch_trailing_records {
527 record_counter = instructions
528 .iter()
529 .skip(instruction_idx)
530 .find_map(|i| {
531 if i.record_index() != usize::MAX {
532 Some(i.record_index())
533 } else {
534 None
535 }
536 })
537 .unwrap_or(0);
538 file.seek(SeekFrom::Start(
539 initial_header_size
540 + record_counter as u64 * initial_record_bytes as u64,
541 ))
542 .map_err(EDFError::FileWriteError)?;
543 continue;
544 }
545
546 let read_offset = if overwrite_counter < 0 {
548 overwrite_counter.abs()
549 } else {
550 0
551 } as u64;
552 let buffered_offset = if overwrite_counter > 0 {
553 overwrite_counter
554 } else {
555 0
556 } as u64;
557 let mut buffer_read = overwrite_buffer
558 .drain(0..initial_record_bytes.min(overwrite_buffer.len()))
559 .collect::<Vec<_>>();
560 let buffer_read_count = buffer_read.len();
561 let disk_read_count = initial_record_bytes - buffer_read_count;
562
563 let current_file_position =
565 file.stream_position().map_err(EDFError::FileWriteError)? + read_offset;
566 if disk_read_count > 0 {
567 let mut buffer = vec![0; disk_read_count]; file.read_exact_at(&mut buffer, current_file_position)
569 .map_err(EDFError::FileWriteError)?;
570 buffer_read.append(&mut buffer);
571 }
572
573 let read_max = initial_filesize.saturating_sub(current_file_position);
575 let target_read_length =
576 overwrite_counter + new_record_bytes as i64 - buffered_offset as i64;
577 let read_length = u64::try_from(target_read_length)
578 .map(|len| len.min(read_max).saturating_sub(disk_read_count as u64))
579 .unwrap_or(0) as usize;
580 if read_length > 0 {
581 let mut buffer = vec![0; read_length]; file.read_exact_at(
583 &mut buffer,
584 current_file_position + disk_read_count as u64,
585 )
586 .map_err(EDFError::FileWriteError)?;
587 overwrite_buffer.append(&mut buffer);
588 }
589
590 let exceed = if target_read_length.max(0) as u64 > read_max {
592 target_read_length.max(0) as u64 - read_max
593 } else {
594 0
595 };
596 overwrite_counter += new_record_bytes as i64
597 - disk_read_count as i64
598 - buffer_read_count as i64
599 - exceed as i64;
600
601 if !signal_instructions.is_empty() {
603 let cursor = Cursor::new(buffer_read);
604 let mut reader = BufReader::new(cursor);
605 let mut record = Self::read_record_data(
606 &mut reader,
607 0,
608 &initial_signals,
609 initial_record_duration,
610 )?;
611 record.patch_record(&signal_instructions)?;
612 buffer_read = record.serialize()?;
613 }
614
615 file.write_all(&buffer_read)
616 .map_err(EDFError::FileWriteError)?;
617 record_counter += 1;
618 }
619 }
620 }
621
622 if overwrite_counter != 0 {
625 if overwrite_counter > 0 {
626 file.write_all(&overwrite_buffer)
627 .map_err(EDFError::FileWriteError)?;
628 overwrite_buffer.clear();
629 } else {
630 let reduced_by_length = overwrite_counter.abs() as usize;
631 let position = file.stream_position().map_err(EDFError::FileWriteError)?;
632 file.write_all(&repeat_n(0, reduced_by_length).collect::<Vec<_>>())
633 .map_err(EDFError::FileWriteError)?;
634 file.set_len(position).map_err(EDFError::FileWriteError)?;
635 }
636 }
637
638 file.flush().map_err(EDFError::FileWriteError)?;
640 self.instructions.clear();
641 let new_file_size = file.metadata().map_err(EDFError::FileWriteError)?.len();
642
643 self.header.update_initial_record_bytes();
646 self.header.update_initial_header_sha256()?;
647
648 if let Some(record_idx) = initial_record_position {
650 let seek_pos = self.header.header_bytes as u64 + record_idx * new_record_bytes as u64;
651 self.reader
652 .seek(SeekFrom::Start(seek_pos.min(new_file_size)))
653 .map_err(EDFError::FileWriteError)?;
654 } else {
655 self.reader
656 .seek(SeekFrom::Start(0))
657 .map_err(EDFError::FileWriteError)?;
658 }
659
660 Ok(())
661 }
662
663 pub fn read_record(&mut self) -> Result<Option<Record>, EDFError> {
664 let position = self
671 .reader
672 .stream_position()
673 .map_err(EDFError::FileReadError)?;
674
675 if position < self.header.header_bytes as u64 {
677 return Err(EDFError::InvalidReadRange);
678 }
679
680 let record_size = self.header.data_record_bytes() as u64;
682 let record_offset = position - self.header.header_bytes as u64;
683 if record_offset % record_size != 0 {
684 return Err(EDFError::InvalidReadRange);
685 }
686
687 let record_idx = (position - self.header.header_bytes as u64) / record_size;
689 let record_count = self
690 .header
691 .record_count
692 .ok_or(EDFError::ReadWhileRecording)?;
693 if record_idx + 1 > record_count as u64 {
694 return Ok(None);
695 }
696
697 let mut record = Self::read_record_data(
699 &mut self.reader,
700 record_idx,
701 &self.header.signals,
702 self.header.record_duration,
703 )?;
704
705 record.patch_record(&self.instructions)?;
707
708 Ok(Some(record))
709 }
710
711 fn read_record_data<R: BufRead + Seek>(
712 reader: &mut R,
713 record_idx: u64,
714 signals: &Vec<SignalHeader>,
715 record_duration: f64,
716 ) -> Result<Record, EDFError> {
717 let mut sample_buffer = [0; 2];
718 let mut tal_buffer = vec![];
719 let mut record = Record::new(&signals);
720 record.default_offset = record_idx as f64 * record_duration;
721
722 for (i, signal) in signals.iter().enumerate() {
723 if signal.is_annotation() {
724 let mut tals = Vec::new();
727 let mut total_read = 0;
728 while total_read < signal.samples_count * 2 {
729 total_read += reader
730 .read_until(b'\x00', &mut tal_buffer)
731 .map_err(EDFError::FileReadError)?;
732
733 if tal_buffer.is_empty() {
735 break;
736 }
737
738 if tal_buffer.len() == 1 && tal_buffer[0] == b'\x00' {
743 tal_buffer.clear();
744 continue;
745 }
746
747 let tal = AnnotationList::deserialize(&take_vec(&mut tal_buffer))?;
749 tals.push(tal);
750 }
751 record.set_annotation(i, tals)?;
752 } else {
753 let mut samples = Vec::with_capacity(signal.samples_count);
754 for _ in 0..signal.samples_count {
755 reader
756 .read_exact(&mut sample_buffer)
757 .map_err(EDFError::FileReadError)?;
758 let sample = i16::from_le_bytes(sample_buffer);
759 samples.push(sample);
760 }
761 record.set_samples(i, samples)?;
762 }
763 }
764
765 Ok(record)
766 }
767
768 pub fn read_record_at(&mut self, index: usize) -> Result<Option<Record>, EDFError> {
769 self.seek_to_record(index)?;
770 self.read_record()
771 }
772
773 pub fn seek_to_record(&mut self, index: usize) -> Result<(), EDFError> {
774 self.reader
775 .seek(SeekFrom::Start(
776 self.header.header_bytes as u64
777 + index as u64 * self.header.data_record_bytes() as u64,
778 ))
779 .map_err(EDFError::FileReadError)?;
780 Ok(())
781 }
782
783 pub fn seek_previous_record(&mut self) -> Result<bool, EDFError> {
784 let position = self
787 .reader
788 .stream_position()
789 .map_err(EDFError::FileReadError)?;
790 if position <= self.header.header_bytes as u64 {
791 return Ok(false);
792 }
793
794 self.reader
795 .seek(SeekFrom::Current(-(self.header.data_record_bytes() as i64)))
796 .map_err(EDFError::FileReadError)?;
797
798 Ok(true)
799 }
800
801 pub fn read_nanos(&mut self, nanoseconds: u128) -> Result<SpanningRecord, EDFError> {
814 let offset_end = self.record_read_offset_ns + nanoseconds;
815 let record_duration_ns = (self.header.record_duration * 1_000_000_000.0) as u128;
816
817 let mut records = SpanningRecord::new(&self.header);
823 let mut offset_current = self.record_read_offset_ns;
824 let mut read_start_ns = if self.seek_previous_record()? {
825 self.read_record()?
826 .map(|r| (r.get_start_offset() * 1_000_000_000.0) as u128)
827 } else {
828 None
829 };
830 let mut remaining_record_ns = 0;
831
832 while offset_current < offset_end {
834 let Some(mut record) = self.read_record()? else {
835 remaining_record_ns = 0;
836 break;
837 };
838
839 let onset = (record.get_start_offset() * 1_000_000_000.0) as u128;
841 let skip_duration_ns = if self.header.specification == EDFSpecifications::EDF {
842 0
843 } else if let Some(previous_onset) = &read_start_ns {
844 onset - previous_onset - record_duration_ns
845 } else {
846 let already_skipped = onset - offset_current;
847 onset - already_skipped
848 };
849
850 if read_start_ns.is_none() {
851 read_start_ns = Some(onset);
852 }
853
854 let sample_frequencies = record
855 .raw_signal_samples
856 .iter()
857 .map(|s| s.len() as f64 / self.header.record_duration)
858 .collect::<Vec<_>>();
859
860 let record_offset_ns = if offset_current == self.record_read_offset_ns {
863 records.insert_spanning_wait(
864 record.get_start_offset() + self.record_read_offset_ns as f64 / 1_000_000_000.0,
865 );
866
867 if self.record_read_offset_ns > 0 {
869 for signal in record.raw_signal_samples.iter_mut() {
871 let sample_freq = signal.len() as f64 / self.header.record_duration;
872 let sample_count = (self.record_read_offset_ns as f64 / 1_000_000_000.0
873 * sample_freq)
874 .floor() as usize;
875 signal.drain(..sample_count);
876 }
877
878 record.annotations.iter_mut().for_each(|a| {
881 a.retain(|annotation| {
882 if annotation.duration == 0.0 {
883 return true;
884 }
885 let annotation_onset_ns = (annotation.onset * 1_000_000_000.0) as u128;
886 let annotation_duration_ns =
887 (annotation.duration * 1_000_000_000.0) as u128;
888 return annotation_onset_ns + annotation_duration_ns
889 >= read_start_ns.unwrap() + self.record_read_offset_ns;
890 })
891 });
892 }
893
894 self.record_read_offset_ns
895 } else {
896 0
897 };
898
899 if skip_duration_ns != 0 && !records.is_spanning_wait() {
901 records.insert_spanning_wait(
902 record.get_start_offset() + record_offset_ns as f64 / 1_000_000_000.0,
903 );
904 }
905
906 offset_current += skip_duration_ns;
909 if offset_current >= offset_end {
910 self.seek_previous_record()?;
911 break;
912 }
913
914 remaining_record_ns = offset_end - offset_current;
916 let record_remaining_ns = record_duration_ns - self.record_read_offset_ns;
917 if remaining_record_ns >= record_remaining_ns {
918 for (i, signal) in record.raw_signal_samples.iter().enumerate() {
919 records.extend_samples(i, signal.to_vec())
920 }
921
922 records.annotations.extend(record.annotations);
923 offset_current += record_remaining_ns;
924 remaining_record_ns -= record_remaining_ns;
925
926 self.record_read_offset_ns = 0;
928 } else {
929 for (i, signal) in record.raw_signal_samples.iter().enumerate() {
930 let sample_freq = sample_frequencies[i];
931 let prev_sample_count =
932 self.record_read_offset_ns as f64 / 1_000_000_000.0 * sample_freq;
933 let current_sample_count =
934 remaining_record_ns as f64 / 1_000_000_000.0 * sample_freq;
935 let total_sample_count = prev_sample_count + current_sample_count;
936 let sample_count =
937 (total_sample_count - prev_sample_count.floor()).floor() as usize;
938 records.extend_samples(i, signal[..sample_count].to_vec())
939 }
940
941 for tal_list in record.annotations {
943 let mut tals = Vec::new();
944 for annotation_list in tal_list {
945 let annotation_onset_ns = (annotation_list.onset * 1_000_000_000.0) as u128;
946 let is_entire_record = annotation_list.duration == 0.0;
947 let is_starting_until_read_end =
948 annotation_onset_ns <= read_start_ns.unwrap() + offset_end;
949 if is_entire_record || is_starting_until_read_end {
950 tals.push(annotation_list);
951 }
952 }
953 records.annotations.push(tals);
954 }
955
956 self.seek_previous_record()?;
957 break;
958 }
959
960 read_start_ns = Some(onset);
961 }
962
963 records.finish();
965
966 self.record_read_offset_ns += remaining_record_ns;
968
969 Ok(records)
970 }
971
972 pub fn read_micros(&mut self, microseconds: u128) -> Result<SpanningRecord, EDFError> {
973 self.read_nanos(microseconds * 1_000)
974 }
975
976 pub fn read_millis(&mut self, milliseconds: u128) -> Result<SpanningRecord, EDFError> {
977 self.read_nanos(milliseconds * 1_000_000)
978 }
979
980 pub fn read_seconds(&mut self, seconds: u128) -> Result<SpanningRecord, EDFError> {
981 self.read_nanos(seconds * 1_000_000_000)
982 }
983
984 pub fn read_seconds_approx(&mut self, seconds: f32) -> Result<SpanningRecord, EDFError> {
1000 if seconds <= 0.0 {
1001 return Err(EDFError::InvalidReadRange);
1002 }
1003
1004 self.read_nanos((seconds as f64 * 1_000_000_000.0) as u128)
1005 }
1006}