Refactor buffer reader
This commit is contained in:
parent
2f1c317e11
commit
8a638bba29
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
pub mod packet;
|
pub mod packet;
|
||||||
pub mod encoding;
|
pub mod encoding;
|
||||||
|
pub mod utils;
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
pub fn print_stack(file: &'static str, line: u32) {
|
pub fn print_stack(file: &'static str, line: u32) {
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
use crate::encoding::variable_byte_integer::VariableByteIntegerDecoder;
|
use crate::utils::buffer_reader::ProperyParseError;
|
||||||
|
use crate::utils::buffer_reader::StringPair;
|
||||||
|
use crate::utils::buffer_reader::EncodedString;
|
||||||
|
use crate::utils::buffer_reader::BinaryData;
|
||||||
|
use crate::encoding::variable_byte_integer::VariableByteIntegerError;
|
||||||
|
/*use crate::encoding::variable_byte_integer::VariableByteIntegerDecoder;
|
||||||
use crate::encoding::variable_byte_integer::VariableByteIntegerError;
|
use crate::encoding::variable_byte_integer::VariableByteIntegerError;
|
||||||
use core::str;
|
use core::str;
|
||||||
|
|
||||||
|
@ -6,30 +11,7 @@ use core::str;
|
||||||
pub trait Decode<'a> {
|
pub trait Decode<'a> {
|
||||||
fn decode(input: &'a [u8], offset: &'a mut usize) -> Result<Self, ProperyParseError> where Self: Sized;
|
fn decode(input: &'a [u8], offset: &'a mut usize) -> Result<Self, ProperyParseError> where Self: Sized;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
pub struct EncodedString<'a> {
|
|
||||||
pub string: &'a str,
|
|
||||||
pub len: u16
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct BinaryData<'a> {
|
|
||||||
pub bin: &'a [u8],
|
|
||||||
pub len: u16
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct StringPair<'a> {
|
|
||||||
pub name: EncodedString<'a>,
|
|
||||||
pub value: EncodedString<'a>
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(core::fmt::Debug)]
|
|
||||||
pub enum ProperyParseError {
|
|
||||||
Utf8Error,
|
|
||||||
IndexOutOfBounce,
|
|
||||||
VariableByteIntegerError,
|
|
||||||
IdNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum Property<'a> {
|
pub enum Property<'a> {
|
||||||
PayloadFormat(Result<u8, ProperyParseError>),
|
PayloadFormat(Result<u8, ProperyParseError>),
|
||||||
MessageExpiryInterval(Result<u32, ProperyParseError>),
|
MessageExpiryInterval(Result<u32, ProperyParseError>),
|
||||||
|
@ -60,7 +42,7 @@ pub enum Property<'a> {
|
||||||
SharedSubscriptionAvailable(Result<u8, ProperyParseError>)
|
SharedSubscriptionAvailable(Result<u8, ProperyParseError>)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
impl<'a> Decode<'a> for Property<'a> {
|
impl<'a> Decode<'a> for Property<'a> {
|
||||||
fn decode(input: &'a [u8], offset: &'a mut usize) -> Result<Self, ProperyParseError> {
|
fn decode(input: &'a [u8], offset: &'a mut usize) -> Result<Self, ProperyParseError> {
|
||||||
let propertyIdentifier = parseU8(input, offset);
|
let propertyIdentifier = parseU8(input, offset);
|
||||||
|
@ -95,88 +77,5 @@ impl<'a> Decode<'a> for Property<'a> {
|
||||||
_ => return Err(ProperyParseError::IdNotFound)
|
_ => return Err(ProperyParseError::IdNotFound)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
fn parseVariableByteInt<'a>(input: &'a [u8], offset: & mut usize) -> Result<u32, VariableByteIntegerError> {
|
|
||||||
let variable_byte_integer: [u8; 4] = [input[*offset], input[*offset + 1], input[*offset + 2], input[*offset + 3]];
|
|
||||||
*offset = *offset + 4;
|
|
||||||
return VariableByteIntegerDecoder::decode(variable_byte_integer);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parseU32<'a>(input: &'a [u8], offset: & mut usize) -> Result<u32, ProperyParseError> {
|
|
||||||
let ret: u32 = (((input[*offset] as u32) << 24) | ((input[*offset + 1] as u32) << 16) | ((input[*offset + 2] as u32) << 8) | (input[*offset + 3] as u32)) as u32;
|
|
||||||
*offset = *offset + 4;
|
|
||||||
return Ok(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parseU16<'a>(input: &'a [u8], offset: & mut usize) -> Result<u16, ProperyParseError> {
|
|
||||||
let ret: u16 = (((input[*offset] as u16) << 8) | (input[*offset + 1] as u16)) as u16;
|
|
||||||
*offset = *offset + 2;
|
|
||||||
return Ok(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parseU8<'a>(input: &'a [u8], offset: & mut usize) -> Result<u8, ProperyParseError> {
|
|
||||||
let ret: u8 = input[*offset];
|
|
||||||
*offset = *offset + 1;
|
|
||||||
return Ok(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parseString<'a>(input: &'a [u8], offset: & mut usize) -> Result<EncodedString<'a>, ProperyParseError> {
|
|
||||||
let len = parseU16(input, offset);
|
|
||||||
match len {
|
|
||||||
Err(err) => return Err(err),
|
|
||||||
_ => log::debug!("[parseString] let not parsed")
|
|
||||||
}
|
|
||||||
let len_res = len.unwrap();
|
|
||||||
let res_str = str::from_utf8(&(input[*offset..(*offset + len_res as usize)]));
|
|
||||||
if res_str.is_err() {
|
|
||||||
log::error!("Could not parse utf-8 string");
|
|
||||||
return Err(ProperyParseError::Utf8Error);
|
|
||||||
}
|
|
||||||
return Ok(EncodedString { string: res_str.unwrap(), len: len_res });
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: Index out of bounce err !!!!!
|
|
||||||
fn parseBinary<'a>(input: &'a [u8], offset: & mut usize) -> Result<BinaryData<'a>, ProperyParseError> {
|
|
||||||
let len = parseU16(input, offset);
|
|
||||||
match len {
|
|
||||||
Err(err) => return Err(err),
|
|
||||||
_ => log::debug!("[parseBinary] let not parsed")
|
|
||||||
}
|
|
||||||
let len_res = len.unwrap();
|
|
||||||
let res_bin = &(input[*offset..(*offset + len_res as usize)]);
|
|
||||||
return Ok(BinaryData { bin: res_bin, len: len_res });
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parseStringPair<'a>(input: &'a [u8], offset: & mut usize) -> Result<StringPair<'a>, ProperyParseError> {
|
|
||||||
let name = parseString(input, offset);
|
|
||||||
match name {
|
|
||||||
Err(err) => return Err(err),
|
|
||||||
_ => log::debug!("[String pair] name not parsed")
|
|
||||||
}
|
|
||||||
let value = parseString(input, offset);
|
|
||||||
match value {
|
|
||||||
Err(err) => return Err(err),
|
|
||||||
_ => log::debug!("[String pair] value not parsed")
|
|
||||||
}
|
|
||||||
return Ok(StringPair { name: name.unwrap(), value: value.unwrap() });
|
|
||||||
}
|
|
||||||
|
|
||||||
/*impl<'a> From<u8> for Property<'a> {
|
|
||||||
fn from(orig: u8) -> Self {
|
|
||||||
match orig {
|
|
||||||
0x01 => return Property::PayloadFormat,
|
|
||||||
0x02 => return Property::MessageExpiryInterval,
|
|
||||||
0x03 => return Property::ContentType,
|
|
||||||
0x08 => return Property::ResponseTopic,
|
|
||||||
0x09 => return Property::CorrelationData,
|
|
||||||
0x0B => return Property::SubscriptionIdentifier,
|
|
||||||
0x11 => return Property::SessionExpiryInterval,
|
|
||||||
0x12 => return Property::AssignedClientIdentifier,
|
|
||||||
0x13 => return Property::ServerKeepAlive,
|
|
||||||
0x15 => return Property::AuthenticationMethod,
|
|
||||||
0x16 => return Property::AuthenticationMethod
|
|
||||||
_ => return Property::TopicAlias
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
111
src/utils/buffer_reader.rs
Normal file
111
src/utils/buffer_reader.rs
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
use crate::encoding::variable_byte_integer::VariableByteIntegerDecoder;
|
||||||
|
use crate::encoding::variable_byte_integer::VariableByteIntegerError;
|
||||||
|
use core::str;
|
||||||
|
use core::mem;
|
||||||
|
|
||||||
|
pub struct EncodedString<'a> {
|
||||||
|
pub string: &'a str,
|
||||||
|
pub len: u16
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct BinaryData<'a> {
|
||||||
|
pub bin: &'a [u8],
|
||||||
|
pub len: u16
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct StringPair<'a> {
|
||||||
|
pub name: EncodedString<'a>,
|
||||||
|
pub value: EncodedString<'a>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(core::fmt::Debug)]
|
||||||
|
pub enum ProperyParseError {
|
||||||
|
Utf8Error,
|
||||||
|
IndexOutOfBounce,
|
||||||
|
VariableByteIntegerError,
|
||||||
|
IdNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct BuffReader<'a> {
|
||||||
|
buffer: &'a [u8],
|
||||||
|
pub position: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> BuffReader<'a> {
|
||||||
|
pub fn incrementPosition(& mut self, increment: usize) {
|
||||||
|
self.position = self.position + increment;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(buffer: &'a [u8]) -> Self {
|
||||||
|
return BuffReader { buffer: buffer, position: 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn readVariableByteInt(& mut self) -> Result<u32, VariableByteIntegerError> {
|
||||||
|
let variable_byte_integer: [u8; 4] = [self.buffer[self.position], self.buffer[self.position + 1], self.buffer[self.position + 2], self.buffer[self.position + 3]];
|
||||||
|
self.incrementPosition(4);
|
||||||
|
return VariableByteIntegerDecoder::decode(variable_byte_integer);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn readU32(& mut self) -> Result<u32, ProperyParseError> {
|
||||||
|
let (int_bytes, rest) = self.buffer.split_at(mem::size_of::<u32>());
|
||||||
|
let ret: u32 = u32::from_le_bytes(int_bytes.try_into().unwrap());
|
||||||
|
//let ret: u32 = (((self.buffer[self.position] as u32) << 24) | ((self.buffer[self.position + 1] as u32) << 16) | ((self.buffer[self.position + 2] as u32) << 8) | (self.buffer[self.position + 3] as u32)) as u32;
|
||||||
|
self.incrementPosition(4);
|
||||||
|
return Ok(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn readU16(& mut self) -> Result<u16, ProperyParseError> {
|
||||||
|
let (int_bytes, rest) = self.buffer.split_at(mem::size_of::<u16>());
|
||||||
|
let ret: u16 = u16::from_le_bytes(int_bytes.try_into().unwrap());
|
||||||
|
//(((self.buffer[self.position] as u16) << 8) | (self.buffer[self.position + 1] as u16)) as u16;
|
||||||
|
self.incrementPosition(2);
|
||||||
|
return Ok(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn readU8(& mut self) -> Result<u8, ProperyParseError> {
|
||||||
|
let ret: u8 = self.buffer[self.position];
|
||||||
|
self.incrementPosition(1);
|
||||||
|
return Ok(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn readString(& mut self) -> Result<EncodedString<'a>, ProperyParseError> {
|
||||||
|
let len = self.readU16();
|
||||||
|
match len {
|
||||||
|
Err(err) => return Err(err),
|
||||||
|
_ => log::debug!("[parseString] let not parsed")
|
||||||
|
}
|
||||||
|
let len_res = len.unwrap();
|
||||||
|
let res_str = str::from_utf8(&(self.buffer[self.position..(self.position + len_res as usize)]));
|
||||||
|
if res_str.is_err() {
|
||||||
|
log::error!("Could not parse utf-8 string");
|
||||||
|
return Err(ProperyParseError::Utf8Error);
|
||||||
|
}
|
||||||
|
return Ok(EncodedString { string: res_str.unwrap(), len: len_res });
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Index out of bounce err !!!!!
|
||||||
|
pub fn readBinary(& mut self) -> Result<BinaryData<'a>, ProperyParseError> {
|
||||||
|
let len = self.readU16();
|
||||||
|
match len {
|
||||||
|
Err(err) => return Err(err),
|
||||||
|
_ => log::debug!("[parseBinary] let not parsed")
|
||||||
|
}
|
||||||
|
let len_res = len.unwrap();
|
||||||
|
let res_bin = &(self.buffer[self.position..(self.position + len_res as usize)]);
|
||||||
|
return Ok(BinaryData { bin: res_bin, len: len_res });
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn readStringPair(& mut self) -> Result<StringPair<'a>, ProperyParseError> {
|
||||||
|
let name = self.readString();
|
||||||
|
match name {
|
||||||
|
Err(err) => return Err(err),
|
||||||
|
_ => log::debug!("[String pair] name not parsed")
|
||||||
|
}
|
||||||
|
let value = self.readString();
|
||||||
|
match value {
|
||||||
|
Err(err) => return Err(err),
|
||||||
|
_ => log::debug!("[String pair] value not parsed")
|
||||||
|
}
|
||||||
|
return Ok(StringPair { name: name.unwrap(), value: value.unwrap() });
|
||||||
|
}
|
||||||
|
}
|
1
src/utils/mod.rs
Normal file
1
src/utils/mod.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub mod buffer_reader;
|
Loading…
Reference in New Issue
Block a user