diff --git a/src/lib.rs b/src/lib.rs index 9aa6c7d..7673fbc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,7 @@ pub mod packet; pub mod encoding; +pub mod utils; #[allow(unused_variables)] pub fn print_stack(file: &'static str, line: u32) { diff --git a/src/packet/property.rs b/src/packet/property.rs index c081f66..cfce750 100644 --- a/src/packet/property.rs +++ b/src/packet/property.rs @@ -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 core::str; @@ -6,30 +11,7 @@ use core::str; pub trait Decode<'a> { fn decode(input: &'a [u8], offset: &'a mut usize) -> Result 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> { PayloadFormat(Result), MessageExpiryInterval(Result), @@ -60,7 +42,7 @@ pub enum Property<'a> { SharedSubscriptionAvailable(Result) } - +/* impl<'a> Decode<'a> for Property<'a> { fn decode(input: &'a [u8], offset: &'a mut usize) -> Result { let propertyIdentifier = parseU8(input, offset); @@ -95,88 +77,5 @@ impl<'a> Decode<'a> for Property<'a> { _ => return Err(ProperyParseError::IdNotFound) } } -} +}*/ -fn parseVariableByteInt<'a>(input: &'a [u8], offset: & mut usize) -> Result { - 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 { - 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 { - 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 { - let ret: u8 = input[*offset]; - *offset = *offset + 1; - return Ok(ret); -} - -fn parseString<'a>(input: &'a [u8], offset: & mut usize) -> Result, 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, 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, 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 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 - } - } -}*/ \ No newline at end of file diff --git a/src/utils/buffer_reader.rs b/src/utils/buffer_reader.rs new file mode 100644 index 0000000..81d04d1 --- /dev/null +++ b/src/utils/buffer_reader.rs @@ -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 { + 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 { + let (int_bytes, rest) = self.buffer.split_at(mem::size_of::()); + 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 { + let (int_bytes, rest) = self.buffer.split_at(mem::size_of::()); + 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 { + let ret: u8 = self.buffer[self.position]; + self.incrementPosition(1); + return Ok(ret); + } + + pub fn readString(& mut self) -> Result, 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, 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, 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() }); + } +} \ No newline at end of file diff --git a/src/utils/mod.rs b/src/utils/mod.rs new file mode 100644 index 0000000..fbf6310 --- /dev/null +++ b/src/utils/mod.rs @@ -0,0 +1 @@ +pub mod buffer_reader; \ No newline at end of file