1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
use crate::error::Error; use crate::frame::{MTFrame, MTHeader}; use std::io::Cursor; const START_OF_FRAME_TOKEN: u8 = 0xfe; pub trait ToBytes { fn to_bytes(s: Self) -> Vec<u8>; } enum State { WaitingStartOfFrame, GatheringMTFrameBytes, WaitingFrameCheckSequence, } pub struct Parser { buffer: Vec<u8>, state: State, } impl Parser { pub fn new() -> Parser { Parser { buffer: Vec::new(), state: State::WaitingStartOfFrame, } } pub fn feed(&mut self, new_byte: u8) -> Option<Result<MTFrame, Error>> { match self.state { State::WaitingStartOfFrame => { if new_byte != START_OF_FRAME_TOKEN { return Some(Err(Error::InvalidStartOfFrame(new_byte))); } self.state = State::GatheringMTFrameBytes; } State::GatheringMTFrameBytes => { self.buffer.push(new_byte); let payload_length = self.buffer[0] as usize; let expected_frame_size = MTHeader::size() + payload_length; if self.buffer.len() >= expected_frame_size { self.state = State::WaitingFrameCheckSequence; } } State::WaitingFrameCheckSequence => { let fcs = MTFrame::compute_frame_check_sequence(self.buffer.as_slice()); let result = if fcs == new_byte { self.parse_frame() } else { Err(Error::InvalidFrameCheckSequence(self.buffer.clone())) }; self.reset(); return Some(result); } } None } pub fn reset(&mut self) { self.buffer.clear(); self.state = State::WaitingStartOfFrame; } fn parse_frame(&self) -> Result<MTFrame, Error> { let mut cursor = Cursor::new(self.buffer.as_slice()); MTFrame::try_decode(&mut cursor) } }