| @@ -6,6 +6,7 @@ use crate::{ · 5 unmodified lines |
| 6 | 6 | }; |
| 7 | 7 | use bstr::BString; |
| 8 | 8 | use quick_error::quick_error; |
| 9 | +use std::convert::TryInto; |
| 9 | 10 | |
| 10 | 11 | quick_error! { |
| 11 | 12 | #[derive(Debug)] |
| @@ -39,6 +40,43 @@ pub enum Stream<'a> { · 27 unmodified lines |
| 39 | 40 | }, |
| 40 | 41 | } |
| 41 | 42 | |
| 43 | +pub enum PacketLineOrWantedSize<'a> { |
| 44 | + Line(PacketLine<'a>), |
| 45 | + Wanted(u16), |
| 46 | +} |
| 47 | + |
| 48 | +pub fn hex_prefix(data: &[u8; 4]) -> Result<PacketLineOrWantedSize, Error> { |
| 49 | + for (line_bytes, line_type) in &[ |
| 50 | + (FLUSH_LINE, PacketLine::Flush), |
| 51 | + (DELIMITER_LINE, PacketLine::Delimiter), |
| 52 | + (RESPONSE_END_LINE, PacketLine::ResponseEnd), |
| 53 | + ] { |
| 54 | + if data == *line_bytes { |
| 55 | + return Ok(PacketLineOrWantedSize::Line(*line_type)); |
| 56 | + } |
| 57 | + } |
| 58 | + |
| 59 | + let mut buf = [0u8; U16_HEX_BYTES / 2]; |
| 60 | + hex::decode_to_slice(data, &mut buf)?; |
| 61 | + let wanted_bytes = u16::from_be_bytes(buf); |
| 62 | + if wanted_bytes == 4 { |
| 63 | + return Err(Error::DataIsEmpty); |
| 64 | + } |
| 65 | + Ok(PacketLineOrWantedSize::Wanted(wanted_bytes)) |
| 66 | +} |
| 67 | + |
| 68 | +pub fn to_data_line(data: &[u8]) -> Result<PacketLine, Error> { |
| 69 | + if data.len() > MAX_LINE_LEN { |
| 70 | + return Err(Error::DataLengthLimitExceeded(data.len())); |
| 71 | + } |
| 72 | + |
| 73 | + if data.len() >= ERR_PREFIX.len() && &data[..ERR_PREFIX.len()] == ERR_PREFIX { |
| 74 | + return Err(Error::Line(data[ERR_PREFIX.len()..].into(), data.len())); |
| 75 | + } |
| 76 | + Ok(PacketLine::Data(data)) |
| 77 | +} |
| 78 | + |
| 79 | +// TODO: verify this one is actually needed in the end |
| 42 | 80 | pub fn streaming(data: &[u8]) -> Result<Stream, Error> { |
| 43 | 81 | let data_len = data.len(); |
| 44 | 82 | if data_len < U16_HEX_BYTES { |
| @@ -46,23 +84,15 @@ pub fn streaming(data: &[u8]) -> Result<Stream, Error> { · 1 unmodified line |
| 46 | 84 | bytes_needed: U16_HEX_BYTES - data_len, |
| 47 | 85 | }); |
| 48 | 86 | } |
| 49 | | − let hex_bytes = &data[..U16_HEX_BYTES]; |
| 50 | | − for (line_bytes, line_type) in &[ |
| 51 | | − (FLUSH_LINE, PacketLine::Flush), |
| 52 | | − (DELIMITER_LINE, PacketLine::Delimiter), |
| 53 | | − (RESPONSE_END_LINE, PacketLine::ResponseEnd), |
| 54 | | − ] { |
| 55 | | − if hex_bytes == *line_bytes { |
| 87 | + let wanted_bytes = match hex_prefix(data[..U16_HEX_BYTES].try_into().expect("sizes to match"))? { |
| 88 | + PacketLineOrWantedSize::Wanted(s) => s as usize, |
| 89 | + PacketLineOrWantedSize::Line(line) => { |
| 56 | 90 | return Ok(Stream::Complete { |
| 57 | | − line: *line_type, |
| 91 | + line, |
| 58 | 92 | bytes_consumed: 4, |
| 59 | | − }); |
| 93 | + }) |
| 60 | 94 | } |
| 61 | | − } |
| 62 | | − |
| 63 | | − let mut buf = [0u8; U16_HEX_BYTES / 2]; |
| 64 | | − hex::decode_to_slice(hex_bytes, &mut buf)?; |
| 65 | | − let wanted_bytes = u16::from_be_bytes(buf) as usize; |
| 95 | + }; |
| 66 | 96 | if wanted_bytes > MAX_LINE_LEN { |
| 67 | 97 | return Err(Error::DataLengthLimitExceeded(wanted_bytes)); |
| 68 | 98 | } |
| @@ -72,17 +102,8 @@ pub fn streaming(data: &[u8]) -> Result<Stream, Error> { · 3 unmodified lines |
| 72 | 102 | }); |
| 73 | 103 | } |
| 74 | 104 | |
| 75 | | − if wanted_bytes == 4 { |
| 76 | | − return Err(Error::DataIsEmpty); |
| 77 | | − } |
| 78 | | − |
| 79 | | − let data = &data[U16_HEX_BYTES..wanted_bytes]; |
| 80 | | − if data.len() >= ERR_PREFIX.len() && &data[..ERR_PREFIX.len()] == ERR_PREFIX { |
| 81 | | − return Err(Error::Line(data[ERR_PREFIX.len()..].into(), wanted_bytes)); |
| 82 | | − } |
| 83 | | − |
| 84 | 105 | Ok(Stream::Complete { |
| 85 | | − line: PacketLine::Data(data), |
| 106 | + line: to_data_line(&data[U16_HEX_BYTES..wanted_bytes])?, |
| 86 | 107 | bytes_consumed: wanted_bytes, |
| 87 | 108 | }) |
| 88 | 109 | } |