From 202fa39a42e6340ccf7ed7fc4363b65bce382129 Mon Sep 17 00:00:00 2001 From: Anton Tarasenko Date: Fri, 23 Jul 2021 01:22:29 +0700 Subject: [PATCH 1/8] Fix comments for some `MessageReader` contants --- src/link/mod.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/link/mod.rs b/src/link/mod.rs index 87d8533..d10f93a 100644 --- a/src/link/mod.rs +++ b/src/link/mod.rs @@ -10,12 +10,10 @@ const UE_RECEIVED_FIELD_SIZE: usize = 4; // Defines how many bytes is used to encode "LENGTH" field, describing length of // next JSON message from ue-server const UE_LENGTH_FIELD_SIZE: usize = 4; -// Value indicating that next byte sequence from ue-server reports amount of bytes received by -// that server so far. Value itself is arbitrary. - +// Arbitrary value indicating that next byte sequence from ue-server reports amount of bytes +// received by that server so far. const HEAD_UE_RECEIVED: u8 = 85; -// Value indicating that next byte sequence from ue-server contains JSON message. -// Value itself is arbitrary. +// Arbitrary value indicating that next byte sequence from ue-server contains JSON message. const HEAD_UE_MESSAGE: u8 = 42; // Maximum allowed size of JSON message sent from ue-server. const MAX_UE_MESSAGE_LENGTH: usize = 25 * 1024 * 1024; From f118767e3faddad55cdc4751f64a0c4209be7156 Mon Sep 17 00:00:00 2001 From: Anton Tarasenko Date: Fri, 23 Jul 2021 01:23:13 +0700 Subject: [PATCH 2/8] Rename `buffer` into `length_buffer` --- src/link/mod.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/link/mod.rs b/src/link/mod.rs index d10f93a..c58ce13 100644 --- a/src/link/mod.rs +++ b/src/link/mod.rs @@ -39,7 +39,7 @@ pub struct MessageReader { is_broken: bool, reading_state: ReadingState, read_bytes: usize, - buffer: [u8; 4], + length_buffer: [u8; 4], current_message_length: usize, current_message: Vec, read_messages: VecDeque, @@ -63,7 +63,7 @@ impl MessageReader { is_broken: false, reading_state: ReadingState::Head, read_bytes: 0, - buffer: [0; 4], + length_buffer: [0; 4], current_message_length: 0, // Will be recreated with `with_capacity` in `push_byte()` current_message: Vec::new(), @@ -88,18 +88,18 @@ impl MessageReader { } } ReadingState::ReceivedBytes => { - self.buffer[self.read_bytes] = input; + self.length_buffer[self.read_bytes] = input; self.read_bytes += 1; if self.read_bytes >= UE_RECEIVED_FIELD_SIZE { - self.ue_received_bytes += array_of_u8_to_u32(self.buffer) as u64; + self.ue_received_bytes += array_of_u8_to_u32(self.length_buffer) as u64; self.change_state(ReadingState::Head); } } ReadingState::Length => { - self.buffer[self.read_bytes] = input; + self.length_buffer[self.read_bytes] = input; self.read_bytes += 1; if self.read_bytes >= UE_LENGTH_FIELD_SIZE { - self.current_message_length = array_of_u8_to_u32(self.buffer) as usize; + self.current_message_length = array_of_u8_to_u32(self.length_buffer) as usize; self.change_state(ReadingState::Payload); if self.current_message_length > MAX_UE_MESSAGE_LENGTH { self.is_broken = true; From 9ca00c5b8cbf480b24aae0753a327f4965307c8e Mon Sep 17 00:00:00 2001 From: Anton Tarasenko Date: Fri, 23 Jul 2021 01:28:33 +0700 Subject: [PATCH 3/8] Refactor tests for clarity --- src/link/mod.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/link/mod.rs b/src/link/mod.rs index c58ce13..0fce536 100644 --- a/src/link/mod.rs +++ b/src/link/mod.rs @@ -203,19 +203,19 @@ fn received_push_byte() { reader.push_byte(0).unwrap(); reader.push_byte(0).unwrap(); reader.push_byte(0).unwrap(); - reader.push_byte(243).unwrap(); - assert_eq!(reader.ue_received_bytes(), 243); + reader.push_byte(0xf3).unwrap(); + assert_eq!(reader.ue_received_bytes(), 0xf3); reader.push_byte(HEAD_UE_RECEIVED).unwrap(); - reader.push_byte(65).unwrap(); - reader.push_byte(25).unwrap(); - reader.push_byte(178).unwrap(); - reader.push_byte(4).unwrap(); - assert_eq!(reader.ue_received_bytes(), 1092203255); + reader.push_byte(0x41).unwrap(); + reader.push_byte(0x19).unwrap(); + reader.push_byte(0xb2).unwrap(); + reader.push_byte(0x04).unwrap(); + assert_eq!(reader.ue_received_bytes(), 0x41_19_b2_f7); // 0xf7 = 0x04 + 0xf3 reader.push_byte(HEAD_UE_RECEIVED).unwrap(); reader.push_byte(231).unwrap(); reader.push_byte(34).unwrap(); reader.push_byte(154).unwrap(); - assert_eq!(reader.ue_received_bytes(), 1092203255); + assert_eq!(reader.ue_received_bytes(), 0x41_19_b2_f7); } #[test] From e3f554218acdf2582176d52684fc5c983bb6cb97 Mon Sep 17 00:00:00 2001 From: Anton Tarasenko Date: Fri, 23 Jul 2021 01:31:40 +0700 Subject: [PATCH 4/8] Refactor `push_byte`'s code Move logic below error checking with early exit. --- src/link/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/link/mod.rs b/src/link/mod.rs index 0fce536..f9b69a6 100644 --- a/src/link/mod.rs +++ b/src/link/mod.rs @@ -100,7 +100,6 @@ impl MessageReader { self.read_bytes += 1; if self.read_bytes >= UE_LENGTH_FIELD_SIZE { self.current_message_length = array_of_u8_to_u32(self.length_buffer) as usize; - self.change_state(ReadingState::Payload); if self.current_message_length > MAX_UE_MESSAGE_LENGTH { self.is_broken = true; return Err(ReadingStreamError::MessageTooLong { @@ -108,6 +107,7 @@ impl MessageReader { }); } self.current_message = Vec::with_capacity(self.current_message_length); + self.change_state(ReadingState::Payload); } } ReadingState::Payload => { From 978a5c4182296ae45ca7a2aa780e53a5278819d4 Mon Sep 17 00:00:00 2001 From: Anton Tarasenko Date: Fri, 23 Jul 2021 01:48:42 +0700 Subject: [PATCH 5/8] Change `UE_RECEIVED_FIELD_SIZE` to 2 ue-server is only supposed to receive up to 4095 bytes at once and is expected to report after reading them, therefore 4 bytes for the amount of received bytes is excessive and 2 will suffice. --- src/link/mod.rs | 58 ++++++++++++++++++++----------------------------- 1 file changed, 23 insertions(+), 35 deletions(-) diff --git a/src/link/mod.rs b/src/link/mod.rs index f9b69a6..9cb8637 100644 --- a/src/link/mod.rs +++ b/src/link/mod.rs @@ -6,7 +6,7 @@ use custom_error::custom_error; // Defines how many bytes is used to encode "AMOUNT" field in the response from ue-server about // amount of bytes it received since the last update -const UE_RECEIVED_FIELD_SIZE: usize = 4; +const UE_RECEIVED_FIELD_SIZE: usize = 2; // Defines how many bytes is used to encode "LENGTH" field, describing length of // next JSON message from ue-server const UE_LENGTH_FIELD_SIZE: usize = 4; @@ -49,7 +49,7 @@ pub struct MessageReader { /// For converting byte stream that is expected from the ue-server into actual messages. /// Expected format is a sequence of either: /// 1. [HEAD_UE_RECEIVED: marker byte | 1 byte] -/// [AMOUNT: amount of bytes received by ue-server since last update | 4 bytes: u32 BE] +/// [AMOUNT: amount of bytes received by ue-server since last update | 2 bytes: u16 BE] /// 2. [HEAD_UE_MESSAGE: marker byte | 1 byte] /// [LENGTH: length of the JSON message in utf8 encoding | 4 bytes: u32 BE] /// [PAYLOAD: utf8-encoded string | `LENGTH` bytes] @@ -91,7 +91,7 @@ impl MessageReader { self.length_buffer[self.read_bytes] = input; self.read_bytes += 1; if self.read_bytes >= UE_RECEIVED_FIELD_SIZE { - self.ue_received_bytes += array_of_u8_to_u32(self.length_buffer) as u64; + self.ue_received_bytes += array_of_u8_to_u16(self.length_buffer) as u64; self.change_state(ReadingState::Head); } } @@ -155,11 +155,15 @@ impl MessageReader { } } -fn array_of_u8_to_u32(bytes: [u8; 4]) -> u64 { - (u64::from(bytes[0]) << 24) - + (u64::from(bytes[1]) << 16) - + (u64::from(bytes[2]) << 8) - + (u64::from(bytes[3])) +fn array_of_u8_to_u16(bytes: [u8; 4]) -> u16 { + (u16::from(bytes[0]) << 8) + u16::from(bytes[1]) +} + +fn array_of_u8_to_u32(bytes: [u8; 4]) -> u32 { + (u32::from(bytes[0]) << 24) + + (u32::from(bytes[1]) << 16) + + (u32::from(bytes[2]) << 8) + + (u32::from(bytes[3])) } #[test] @@ -201,21 +205,15 @@ fn received_push_byte() { let mut reader = MessageReader::new(); reader.push_byte(HEAD_UE_RECEIVED).unwrap(); reader.push_byte(0).unwrap(); - reader.push_byte(0).unwrap(); - reader.push_byte(0).unwrap(); reader.push_byte(0xf3).unwrap(); assert_eq!(reader.ue_received_bytes(), 0xf3); reader.push_byte(HEAD_UE_RECEIVED).unwrap(); - reader.push_byte(0x41).unwrap(); - reader.push_byte(0x19).unwrap(); reader.push_byte(0xb2).unwrap(); reader.push_byte(0x04).unwrap(); - assert_eq!(reader.ue_received_bytes(), 0x41_19_b2_f7); // 0xf7 = 0x04 + 0xf3 + assert_eq!(reader.ue_received_bytes(), 0xb2_f7); // 0xf7 = 0x04 + 0xf3 reader.push_byte(HEAD_UE_RECEIVED).unwrap(); reader.push_byte(231).unwrap(); - reader.push_byte(34).unwrap(); - reader.push_byte(154).unwrap(); - assert_eq!(reader.ue_received_bytes(), 0x41_19_b2_f7); + assert_eq!(reader.ue_received_bytes(), 0xb2_f7); } #[test] @@ -223,9 +221,7 @@ fn mixed_push_byte() { let mut reader = MessageReader::new(); reader.push_byte(HEAD_UE_RECEIVED).unwrap(); reader.push_byte(0).unwrap(); - reader.push_byte(0).unwrap(); - reader.push_byte(0).unwrap(); - reader.push_byte(243).unwrap(); + reader.push_byte(0xf3).unwrap(); reader.push_byte(HEAD_UE_MESSAGE).unwrap(); reader.push_byte(0).unwrap(); reader.push_byte(0).unwrap(); @@ -235,11 +231,9 @@ fn mixed_push_byte() { reader.push_byte(b'o').unwrap(); reader.push_byte(b'!').unwrap(); reader.push_byte(HEAD_UE_RECEIVED).unwrap(); - reader.push_byte(65).unwrap(); - reader.push_byte(25).unwrap(); - reader.push_byte(178).unwrap(); - reader.push_byte(4).unwrap(); - assert_eq!(reader.ue_received_bytes(), 1092203255); + reader.push_byte(0xb2).unwrap(); + reader.push_byte(0x04).unwrap(); + assert_eq!(reader.ue_received_bytes(), 0xb2_f7); // 0xf7 = 0x04 + 0xf3 assert_eq!(reader.pop().unwrap(), "Yo!"); assert_eq!(reader.pop(), None); } @@ -251,9 +245,7 @@ fn pushing_many_bytes_at_once() { .push(&[ HEAD_UE_RECEIVED, 0, - 0, - 0, - 243, + 0xf3, HEAD_UE_MESSAGE, 0, 0, @@ -263,13 +255,11 @@ fn pushing_many_bytes_at_once() { b'o', b'!', HEAD_UE_RECEIVED, - 65, - 25, - 178, - 4, + 0xb2, + 0x04, ]) .unwrap(); - assert_eq!(reader.ue_received_bytes(), 1092203255); + assert_eq!(reader.ue_received_bytes(), 0xb2_f7); assert_eq!(reader.pop().unwrap(), "Yo!"); assert_eq!(reader.pop(), None); } @@ -279,9 +269,7 @@ fn generates_error_invalid_head() { let mut reader = MessageReader::new(); reader.push_byte(HEAD_UE_RECEIVED).unwrap(); reader.push_byte(0).unwrap(); - reader.push_byte(0).unwrap(); - reader.push_byte(0).unwrap(); - reader.push_byte(243).unwrap(); + reader.push_byte(0xf3).unwrap(); assert!(!reader.is_broken()); reader .push_byte(25) From 5ce511c5a72224898c5c20d82807152d1833fcf8 Mon Sep 17 00:00:00 2001 From: Anton Tarasenko Date: Fri, 23 Jul 2021 01:50:47 +0700 Subject: [PATCH 6/8] Refactor `main.rs` to use `if let` construction --- src/main.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 604053c..7f15ba3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,8 +7,7 @@ fn main() { let args: Vec = env::args().collect(); let filename = &args[1]; let config = unreal_config::load_file(Path::new(filename)); - match config { - Ok(config) => print!("{}", config), - _ => (), + if let Ok(config) = config { + print!("{}", config); } } From 3f660f54d5476cb9db6bd495526f91ca4fe25d5f Mon Sep 17 00:00:00 2001 From: Anton Tarasenko Date: Fri, 23 Jul 2021 02:01:17 +0700 Subject: [PATCH 7/8] Remove `EXPECTED_LIMIT_TO_UE_MESSAGES` constant --- src/link/mod.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/link/mod.rs b/src/link/mod.rs index 9cb8637..9bc53c5 100644 --- a/src/link/mod.rs +++ b/src/link/mod.rs @@ -18,9 +18,6 @@ const HEAD_UE_MESSAGE: u8 = 42; // Maximum allowed size of JSON message sent from ue-server. const MAX_UE_MESSAGE_LENGTH: usize = 25 * 1024 * 1024; -// We do not expect to receive more that this much messages at once from ue-server -const EXPECTED_LIMIT_TO_UE_MESSAGES: usize = 100; - custom_error! { pub ReadingStreamError InvalidHead{input: u8} = "Invalid byte used as a HEAD: {input}", MessageTooLong{length: usize} = "Message to receive is too long: {length}", @@ -67,7 +64,8 @@ impl MessageReader { current_message_length: 0, // Will be recreated with `with_capacity` in `push_byte()` current_message: Vec::new(), - read_messages: VecDeque::with_capacity(EXPECTED_LIMIT_TO_UE_MESSAGES), + // This value should be more than enough for typical use + read_messages: VecDeque::with_capacity(100), ue_received_bytes: 0, } } From b187041d9e053989957f20df3f8589dd7165eb33 Mon Sep 17 00:00:00 2001 From: Anton Tarasenko Date: Fri, 23 Jul 2021 02:02:05 +0700 Subject: [PATCH 8/8] Move documentation for `MessageReader` --- src/link/mod.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/link/mod.rs b/src/link/mod.rs index 9bc53c5..511473d 100644 --- a/src/link/mod.rs +++ b/src/link/mod.rs @@ -32,17 +32,6 @@ enum ReadingState { Payload, } -pub struct MessageReader { - is_broken: bool, - reading_state: ReadingState, - read_bytes: usize, - length_buffer: [u8; 4], - current_message_length: usize, - current_message: Vec, - read_messages: VecDeque, - ue_received_bytes: u64, -} - /// For converting byte stream that is expected from the ue-server into actual messages. /// Expected format is a sequence of either: /// 1. [HEAD_UE_RECEIVED: marker byte | 1 byte] @@ -54,6 +43,17 @@ pub struct MessageReader { /// never recovers from it. /// Use either `push_byte()` or `push()` to input byte stream from ue-server and `pop()` to /// retrieve resulting messages. +pub struct MessageReader { + is_broken: bool, + reading_state: ReadingState, + read_bytes: usize, + length_buffer: [u8; 4], + current_message_length: usize, + current_message: Vec, + read_messages: VecDeque, + ue_received_bytes: u64, +} + impl MessageReader { pub fn new() -> MessageReader { MessageReader {