diff --git a/server/src/protocol/parserv2.rs b/server/src/protocol/parserv2.rs index 6fc96ebb..06be52c7 100644 --- a/server/src/protocol/parserv2.rs +++ b/server/src/protocol/parserv2.rs @@ -26,11 +26,6 @@ use std::hint::unreachable_unchecked; -/// The header magic (a '\r' or CR) -/// -/// This demarcates distinct query packets; all queries begin with this byte -const START_HEADER_MAGIC: u8 = 0x0D; - #[derive(Debug)] pub(super) struct Parser<'a> { cursor: usize, @@ -54,8 +49,6 @@ pub enum ParseError { UnknownDatatype, } -type ActionGroup = Vec>; - #[derive(Debug, PartialEq)] pub enum Query { SimpleQuery(DataType), @@ -94,7 +87,7 @@ impl<'a> Parser<'a> { } /// This returns the position at which the line parsing began and the position at which the line parsing /// stopped, in other words, you should be able to do self.buffer[started_at..stopped_at] to get a line - /// and do it unchecked. This **will move the internal cursor ahead** + /// and do it unchecked. This **will move the internal cursor ahead** and place it **at the `\n` byte** fn read_line(&mut self) -> (usize, usize) { let started_at = self.cursor; let mut stopped_at = self.cursor; @@ -111,25 +104,6 @@ impl<'a> Parser<'a> { } (started_at, stopped_at) } - /// This function will return the number of bytes this sizeline has (this is usually the number of items in - /// the following line) - /// This **will forward the cursor itself** - fn read_sizeline(&mut self, opt_char: Option) -> ParseResult { - if let Some(b) = self.buffer.get(self.cursor) { - if *b == opt_char.unwrap_or(b'#') { - // Good, we found a opt_char; time to move ahead - self.incr_cursor(); - // Now read the remaining line - let (started_at, stopped_at) = self.read_line(); - return Self::parse_into_usize(&self.buffer[started_at..stopped_at]); - } else { - // A sizeline should begin with a opt_char; this one doesn't so it's a bad packet; ugh - Err(ParseError::UnexpectedByte) - } - } else { - Err(ParseError::NotEnough) - } - } fn incr_cursor(&mut self) { self.cursor += 1; } @@ -210,27 +184,24 @@ impl<'a> Parser<'a> { /// /// This **will forward the cursor itself** fn parse_metaframe_get_datagroup_count(&mut self) -> ParseResult { - // This will give us the `\r\n` - let metaframe_sizeline = self.read_sizeline(Some(START_HEADER_MAGIC))?; // Now we want to read `*\n` - let our_chunk = self.read_until(metaframe_sizeline)?; - if our_chunk[0] == b'*' { - // Good, this will tell us the number of actions - // Let us attempt to read the usize from this point onwards - // that is excluding the '!' (so 1..) - // also push the cursor ahead because we want to ignore the LF char - // as read_until won't skip the newline - let ret = Self::parse_into_usize(&our_chunk[1..])?; - if self.will_cursor_give_linefeed()? { - // check if the cursor points at the terminal character LF - // as it does, we can freely move past - self.incr_cursor(); - Ok(ret) + let (start, stop) = self.read_line(); + if let Some(our_chunk) = &self.buffer.get(start..stop) { + if our_chunk[0] == b'*' { + // Good, this will tell us the number of actions + // Let us attempt to read the usize from this point onwards + // that is excluding the '*' (so 1..) + if self.will_cursor_give_linefeed()? { + let ret = Self::parse_into_usize(&our_chunk[1..])?; + Ok(ret) + } else { + Err(ParseError::NotEnough) + } } else { Err(ParseError::UnexpectedByte) } } else { - Err(ParseError::UnexpectedByte) + Err(ParseError::NotEnough) } } /// Get the next element **without** the tsymbol @@ -300,6 +271,7 @@ impl<'a> Parser<'a> { } pub fn parse(mut self) -> Result<(Query, usize), ParseError> { let number_of_queries = self.parse_metaframe_get_datagroup_count()?; + println!("Got count: {}", number_of_queries); if number_of_queries == 0 { // how on earth do you expect us to execute 0 queries? waste of bandwidth return Err(ParseError::BadPacket); @@ -340,25 +312,9 @@ impl<'a> Parser<'a> { } } -#[test] -fn test_sizeline_parse() { - let sizeline = "#125\n".as_bytes(); - let mut parser = Parser::new(&sizeline); - assert_eq!(125, parser.read_sizeline(None).unwrap()); - assert_eq!(parser.cursor, sizeline.len()); -} - -#[test] -#[should_panic] -fn test_fail_sizeline_parse_wrong_firstbyte() { - let sizeline = "125\n".as_bytes(); - let mut parser = Parser::new(&sizeline); - parser.read_sizeline(None).unwrap(); -} - #[test] fn test_metaframe_parse() { - let metaframe = "\r2\n*2\n".as_bytes(); + let metaframe = "*2\n".as_bytes(); let mut parser = Parser::new(&metaframe); assert_eq!(2, parser.parse_metaframe_get_datagroup_count().unwrap()); assert_eq!(parser.cursor, metaframe.len()); @@ -404,29 +360,18 @@ fn test_metaframe_parse_fail() { #[test] fn test_query_fail_not_enough() { - let query_packet = "\r2".as_bytes(); - assert_eq!( - Parser::new(&query_packet).parse().err().unwrap(), - ParseError::NotEnough - ); - let query_packet = "\r2\n*".as_bytes(); + let query_packet = "*".as_bytes(); assert_eq!( Parser::new(&query_packet).parse().err().unwrap(), ParseError::NotEnough ); - let metaframe = "\r2\n*".as_bytes(); + let metaframe = "*2".as_bytes(); assert_eq!( Parser::new(&metaframe) .parse_metaframe_get_datagroup_count() .unwrap_err(), ParseError::NotEnough ); - let metaframe = "\r2\n*1\n".as_bytes(); - // we just got the metaframe, but there are more bytes, so this is incomplete! - assert_eq!( - Parser::new(&metaframe).parse().unwrap_err(), - ParseError::NotEnough - ); } #[test] @@ -534,8 +479,9 @@ fn test_parse_multitype_array() { #[test] fn test_parse_a_query() { - let bytes = "\r2\n*1\n&3\n+3\nACT\n+3\nfoo\n&4\n+5\nsayan\n+2\nis\n+7\nworking\n&2\n:2\n23\n+5\napril\n" - .as_bytes(); + let bytes = + "*1\n&3\n+3\nACT\n+3\nfoo\n&4\n+5\nsayan\n+2\nis\n+7\nworking\n&2\n:2\n23\n+5\napril\n" + .as_bytes(); let parser = Parser::new(&bytes); let (resp, forward_by) = parser.parse().unwrap(); assert_eq!( @@ -559,8 +505,9 @@ fn test_parse_a_query() { #[test] fn test_parse_a_query_fail_moredata() { - let bytes = "\r2\n*1\n&3\n+3\nACT\n+3\nfoo\n&4\n+5\nsayan\n+2\nis\n+7\nworking\n&1\n:2\n23\n+5\napril\n" - .as_bytes(); + let bytes = + "*1\n&3\n+3\nACT\n+3\nfoo\n&4\n+5\nsayan\n+2\nis\n+7\nworking\n&1\n:2\n23\n+5\napril\n" + .as_bytes(); let parser = Parser::new(&bytes); assert_eq!(parser.parse().unwrap_err(), ParseError::UnexpectedByte); } @@ -568,8 +515,9 @@ fn test_parse_a_query_fail_moredata() { #[test] fn test_pipelined_query_incomplete() { // this was a pipelined query: we expected two queries but got one! - let bytes = "\r2\n*2\n&3\n+3\nACT\n+3\nfoo\n&4\n+5\nsayan\n+2\nis\n+7\nworking\n&2\n:2\n23\n+5\napril\n" - .as_bytes(); + let bytes = + "*2\n&3\n+3\nACT\n+3\nfoo\n&4\n+5\nsayan\n+2\nis\n+7\nworking\n&2\n:2\n23\n+5\napril\n" + .as_bytes(); assert_eq!( Parser::new(&bytes).parse().unwrap_err(), ParseError::NotEnough @@ -579,7 +527,7 @@ fn test_pipelined_query_incomplete() { #[test] fn test_pipelined_query() { let bytes = - "\r2\n*2\n&3\n+3\nACT\n+3\nfoo\n&3\n+5\nsayan\n+2\nis\n+7\nworking\n+4\nHEYA\n".as_bytes(); + "*2\n&3\n+3\nACT\n+3\nfoo\n&3\n+5\nsayan\n+2\nis\n+7\nworking\n+4\nHEYA\n".as_bytes(); /* (\r2\n*2\n)(&3\n)({+3\nACT\n}{+3\nfoo\n}{[&3\n][+5\nsayan\n][+2\nis\n][+7\nworking\n]})(+4\nHEYA\n) */ @@ -598,5 +546,6 @@ fn test_pipelined_query() { ]), DataType::String("HEYA".to_owned()) ]) - ) + ); + assert_eq!(forward_by, bytes.len()); }