use crate::body_parser::{BodyParser, ParserState};
use crate::message::stomp_message::StompMessage;
#[derive(Debug, PartialEq)]
enum State {
Start,
ReadingBody,
Done
}
pub struct TextBodyParser {
state: State,
read: usize,
max_len: usize,
}
impl TextBodyParser {
pub fn new(max_len: usize) -> TextBodyParser {
TextBodyParser {
state: State::Start,
read: 0,
max_len,
}
}
pub fn bytes_read(&self) -> usize {
self.read
}
pub fn reinit(&mut self, max_len: usize) {
self.state = State::Start;
self.read = 0;
self.max_len = max_len;
}
}
impl BodyParser for TextBodyParser {
fn push(&mut self, buffer: &[u8], message: &mut StompMessage) -> Result<usize, ParserState> {
let mut p: usize = 0;
for ch in buffer {
p += 1;
if *ch == b'\0' {
message.add_body(&buffer[0..p - 1]);
self.state = State::Done;
self.read += p;
return Ok(p);
}
if self.read + p > self.max_len {
self.read += p;
return Err(ParserState::BodyFlup);
}
}
message.add_body(&buffer[0..p]);
self.state = State::ReadingBody;
self.read += p;
Ok(p)
}
fn is_done(&self) -> bool {
State::Done == self.state
}
}
#[cfg(test)]
mod tests {
use crate::message::stomp_message::Ownership;
use super::*;
#[test]
fn test_text_happy() {
let mut p = TextBodyParser::new(1048576);
let mut m = StompMessage::new(Ownership::Session);
p.reinit(1048576);
match p.push(b"abcdefghij", &mut m) {
Ok(10) => {
assert!(!p.is_done());
},
Err(_) => panic!("parse error"),
_ => panic!("unexpected")
}
match p.push(b"klmnopqrst", &mut m) {
Ok(10) => {
assert!(!p.is_done());
},
Err(_) => panic!("parse error"),
_ => panic!("unexpected")
}
match p.push(b"uvw\0", &mut m) {
Ok(4) => {
assert!(p.is_done());
},
Err(_) => panic!("parse error"),
_ => panic!("unexpected")
}
println!("parsed text message {:?}", m.as_string());
}
#[test]
fn test_text_unhappy() {
let mut p = TextBodyParser::new(10);
let mut m = StompMessage::new(Ownership::Session);
match p.push(b"abcdefghijk", &mut m) {
Ok(_) => {
panic!("should flup")
},
Err(ParserState::BodyFlup) => {}
_ => panic!("unexpected")
}
}
}