aboutsummaryrefslogtreecommitdiffstats
path: root/src/parser.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.rs')
-rw-r--r--src/parser.rs88
1 files changed, 88 insertions, 0 deletions
diff --git a/src/parser.rs b/src/parser.rs
new file mode 100644
index 0000000..89c88ab
--- /dev/null
+++ b/src/parser.rs
@@ -0,0 +1,88 @@
+#[repr(packed)]
+struct Header {
+ secs: u32,
+ micros: u32,
+ len: u32,
+}
+
+impl Header {
+ fn time(&self) -> std::time::Duration {
+ std::time::Duration::from_micros(u64::from(
+ self.secs * 1_000_000 + self.micros,
+ ))
+ }
+
+ fn len(&self) -> usize {
+ self.len as usize
+ }
+}
+
+pub struct Parser {
+ reading: std::collections::VecDeque<u8>,
+ read_state: Option<Header>,
+}
+
+impl Parser {
+ pub fn new() -> Self {
+ Default::default()
+ }
+
+ pub fn add_bytes(&mut self, bytes: &[u8]) {
+ self.reading.extend(bytes.iter());
+ }
+
+ pub fn next_frame(&mut self) -> Option<crate::frame::Frame> {
+ let header = if let Some(header) = &self.read_state {
+ header
+ } else {
+ if self.reading.len() < std::mem::size_of::<Header>() {
+ return None;
+ }
+
+ let secs1 = self.reading.pop_front().unwrap();
+ let secs2 = self.reading.pop_front().unwrap();
+ let secs3 = self.reading.pop_front().unwrap();
+ let secs4 = self.reading.pop_front().unwrap();
+ let secs = u32::from_le_bytes([secs1, secs2, secs3, secs4]);
+
+ let usecs1 = self.reading.pop_front().unwrap();
+ let usecs2 = self.reading.pop_front().unwrap();
+ let usecs3 = self.reading.pop_front().unwrap();
+ let usecs4 = self.reading.pop_front().unwrap();
+ let micros = u32::from_le_bytes([usecs1, usecs2, usecs3, usecs4]);
+
+ let len1 = self.reading.pop_front().unwrap();
+ let len2 = self.reading.pop_front().unwrap();
+ let len3 = self.reading.pop_front().unwrap();
+ let len4 = self.reading.pop_front().unwrap();
+ let len = u32::from_le_bytes([len1, len2, len3, len4]);
+
+ let header = Header { secs, micros, len };
+ self.read_state = Some(header);
+ self.read_state.as_ref().unwrap()
+ };
+
+ if self.reading.len() < header.len() {
+ return None;
+ }
+
+ let mut data = vec![];
+ for _ in 0..header.len() {
+ data.push(self.reading.pop_front().unwrap());
+ }
+
+ let time = header.time();
+
+ self.read_state = None;
+ Some(crate::frame::Frame { time, data })
+ }
+}
+
+impl Default for Parser {
+ fn default() -> Self {
+ Self {
+ reading: std::collections::VecDeque::new(),
+ read_state: None,
+ }
+ }
+}