|
|
|
@ -162,10 +162,49 @@ impl<'a> Parser<'a> {
|
|
|
|
|
}
|
|
|
|
|
None => return Err(ParseError::UnexpectedByte),
|
|
|
|
|
};
|
|
|
|
|
item_usize = (item_usize * 10) + curdig;
|
|
|
|
|
// The usize can overflow; check that case
|
|
|
|
|
let product = match item_usize.checked_mul(10) {
|
|
|
|
|
Some(not_overflowed) => not_overflowed,
|
|
|
|
|
None => return Err(ParseError::DataTypeParseError),
|
|
|
|
|
};
|
|
|
|
|
let sum = match product.checked_add(curdig) {
|
|
|
|
|
Some(not_overflowed) => not_overflowed,
|
|
|
|
|
None => return Err(ParseError::DataTypeParseError),
|
|
|
|
|
};
|
|
|
|
|
item_usize = sum;
|
|
|
|
|
}
|
|
|
|
|
Ok(item_usize)
|
|
|
|
|
}
|
|
|
|
|
fn parse_into_u64(bytes: &[u8]) -> ParseResult<u64> {
|
|
|
|
|
let mut byte_iter = bytes.into_iter();
|
|
|
|
|
let mut item_u64 = 0u64;
|
|
|
|
|
while let Some(dig) = byte_iter.next() {
|
|
|
|
|
// 48 is the ASCII code for 0, and 57 is the ascii code for 9
|
|
|
|
|
// so if 0 is given, the subtraction should give 0; similarly
|
|
|
|
|
// if 9 is given, the subtraction should give us 9!
|
|
|
|
|
let curdig: u64 = match dig.checked_sub(48) {
|
|
|
|
|
Some(dig) => {
|
|
|
|
|
if dig > 9 {
|
|
|
|
|
return Err(ParseError::UnexpectedByte);
|
|
|
|
|
} else {
|
|
|
|
|
dig.into()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
None => return Err(ParseError::UnexpectedByte),
|
|
|
|
|
};
|
|
|
|
|
// Now the entire u64 can overflow, so let's attempt to check it
|
|
|
|
|
let product = match item_u64.checked_mul(10) {
|
|
|
|
|
Some(not_overflowed) => not_overflowed,
|
|
|
|
|
None => return Err(ParseError::DataTypeParseError),
|
|
|
|
|
};
|
|
|
|
|
let sum = match product.checked_add(curdig) {
|
|
|
|
|
Some(not_overflowed) => not_overflowed,
|
|
|
|
|
None => return Err(ParseError::DataTypeParseError),
|
|
|
|
|
};
|
|
|
|
|
item_u64 = sum;
|
|
|
|
|
}
|
|
|
|
|
Ok(item_u64)
|
|
|
|
|
}
|
|
|
|
|
/// This will return the number of datagroups present in this query packet
|
|
|
|
|
///
|
|
|
|
|
/// This **will forward the cursor itself**
|
|
|
|
@ -217,12 +256,19 @@ impl<'a> Parser<'a> {
|
|
|
|
|
Err(ParseError::UnexpectedByte)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/// The cursor should have passed the `+` tsymbol
|
|
|
|
|
fn parse_next_string(&mut self) -> ParseResult<String> {
|
|
|
|
|
/// Get the next element **without** the tsymbol
|
|
|
|
|
///
|
|
|
|
|
/// This function **does not forward the newline**
|
|
|
|
|
fn __parse_next_element(&mut self) -> ParseResult<&[u8]> {
|
|
|
|
|
let string_sizeline = self.read_line();
|
|
|
|
|
let string_size =
|
|
|
|
|
Self::parse_into_usize(&self.buffer[string_sizeline.0..string_sizeline.1])?;
|
|
|
|
|
let our_string_chunk = self.read_until(string_size)?;
|
|
|
|
|
let our_chunk = self.read_until(string_size)?;
|
|
|
|
|
Ok(our_chunk)
|
|
|
|
|
}
|
|
|
|
|
/// The cursor should have passed the `+` tsymbol
|
|
|
|
|
fn parse_next_string(&mut self) -> ParseResult<String> {
|
|
|
|
|
let our_string_chunk = self.__parse_next_element()?;
|
|
|
|
|
let our_string = String::from_utf8_lossy(&our_string_chunk).to_string();
|
|
|
|
|
if self.will_cursor_give_linefeed()? {
|
|
|
|
|
// there is a lf after the end of the string; great!
|
|
|
|
@ -234,6 +280,18 @@ impl<'a> Parser<'a> {
|
|
|
|
|
Err(ParseError::UnexpectedByte)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/// The cursor should have passed the `:` tsymbol
|
|
|
|
|
fn parse_next_u64(&mut self) -> ParseResult<u64> {
|
|
|
|
|
let our_u64_chunk = self.__parse_next_element()?;
|
|
|
|
|
let our_u64 = Self::parse_into_u64(our_u64_chunk)?;
|
|
|
|
|
if self.will_cursor_give_linefeed()? {
|
|
|
|
|
// line feed after u64; heck yeah!
|
|
|
|
|
self.incr_cursor();
|
|
|
|
|
Ok(our_u64)
|
|
|
|
|
} else {
|
|
|
|
|
Err(ParseError::UnexpectedByte)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/// This will read a datagroup element and return an **owned vector** containing the bytes
|
|
|
|
|
/// for the next datagroup element
|
|
|
|
|
fn parse_next_datagroup_element(&mut self) -> ParseResult<Vec<u8>> {
|
|
|
|
@ -506,3 +564,16 @@ fn test_parse_next_string() {
|
|
|
|
|
let st = Parser::new(&bytes).parse_next_string().unwrap();
|
|
|
|
|
assert_eq!(st, "sayan".to_owned());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_parse_next_u64() {
|
|
|
|
|
let max = 18446744073709551615;
|
|
|
|
|
assert!(u64::MAX == max);
|
|
|
|
|
let bytes = "20\n18446744073709551615\n".as_bytes();
|
|
|
|
|
let our_u64 = Parser::new(&bytes).parse_next_u64().unwrap();
|
|
|
|
|
assert_eq!(our_u64, max);
|
|
|
|
|
// now overflow the u64
|
|
|
|
|
let bytes = "21\n184467440737095516156\n".as_bytes();
|
|
|
|
|
let our_u64 = Parser::new(&bytes).parse_next_u64().unwrap_err();
|
|
|
|
|
assert_eq!(our_u64, ParseError::DataTypeParseError);
|
|
|
|
|
}
|
|
|
|
|