Encoding&Decoding
This commit is contained in:
parent
0c773fbf0c
commit
f0b9a1a272
31
example_connect.bin
Normal file
31
example_connect.bin
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
CONNECT
|
||||||
|
Hex:
|
||||||
|
10 10 00 04 4d 51 54 54 05 02 00 3c 03 21 00 14
|
||||||
|
00 00
|
||||||
|
|
||||||
|
Bin:
|
||||||
|
TYPE LEN PROTOCOL NAME
|
||||||
|
0001 0000 0001 0000 0000 0000 0000 0100 0100 1101 0101 0001
|
||||||
|
PROTOCOL NAME VERSION FLAGS KEEP ALIVE
|
||||||
|
0101 0100 0101 0100 0000 0101 0000 0010 0000 0000 0011 1100
|
||||||
|
PROP LEN . PROPERTIES . CLIENT ID LEN
|
||||||
|
0000 0011 0010 0001 0000 0000 0001 0100 0000 0000 0000 0000
|
||||||
|
|
||||||
|
|
||||||
|
PUBLISH
|
||||||
|
30 18 00 0a 74 65 73 74 2f 74 6f 70 69 63 00 68
|
||||||
|
65 6c 6c 6f 20 77 6f 72 6c 64
|
||||||
|
|
||||||
|
0011 0000 0001 1000 0000 0000 0000 1010 0111 0100 0110 0101
|
||||||
|
0111 0011 0111 0100 0010 1111 0111 0100 0110 1111 0111 0000
|
||||||
|
0110 1001 0110 0011 0000 0000 0110 1000 0110 0101 0110 1100
|
||||||
|
0110 1100 0110 1111 0010 0000 0111 0111 0110 1111 0111 0010
|
||||||
|
0110 1100 0110 0100
|
||||||
|
|
||||||
|
Variable int
|
||||||
|
- LS 7 bitu jsou data
|
||||||
|
- MS bit urcuje, jestli nasleduje dalsi byte
|
||||||
|
b3 01 = 179
|
||||||
|
1001 0011 0000 0001
|
||||||
|
|
||||||
|
00000000 1 0001 0011
|
1
src/encoding/mod.rs
Normal file
1
src/encoding/mod.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub mod variable_byte_integer;
|
84
src/encoding/variable_byte_integer.rs
Normal file
84
src/encoding/variable_byte_integer.rs
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
#![crate_name = "doc"]
|
||||||
|
/// VariableByteIntegerEncoder and VariableByteIntegerDecoder are implemented based on
|
||||||
|
/// pseudo code which is introduced in MQTT version 5.0 OASIS standard accesible from
|
||||||
|
/// https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901107
|
||||||
|
|
||||||
|
/// Variable byte integer encoder structure is help structure which implements function used to
|
||||||
|
/// encode integer into MQTT variable byte integer format. This format is mainly used to encode
|
||||||
|
/// lenghts stored in a packet.
|
||||||
|
pub struct VariableByteIntegerEncoder;
|
||||||
|
/// Variable byte integers error enumeration is used by both encoder and decoder for
|
||||||
|
/// error notification.
|
||||||
|
pub enum VariableByteIntegerError {
|
||||||
|
EncodingError,
|
||||||
|
DecodingError
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
impl VariableByteIntegerEncoder {
|
||||||
|
/// Encode function takes as parameter integer as u32 type and encodes
|
||||||
|
/// this integer into maximal 4 Bytes. MSb of each Byte is controll bit.
|
||||||
|
/// This bit is saying if there is continuing Byte in stream or not, this way
|
||||||
|
/// we can effectively use 1 to 4 Bytes based in integer len.
|
||||||
|
pub fn encode(mut target: u32) -> Result<[u8; 4], VariableByteIntegerError> {
|
||||||
|
// General known informations from OASIS
|
||||||
|
const MAX_ENCODABLE: u32 = 268435455;
|
||||||
|
const MOD: u32 = 128;
|
||||||
|
if target > MAX_ENCODABLE {
|
||||||
|
log::error!("Maximal value of integer for encoding was exceeded");
|
||||||
|
return Err(VariableByteIntegerError::EncodingError);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut res: [u8; 4] = [0; 4];
|
||||||
|
let mut encoded_byte: u8;
|
||||||
|
let mut i: usize = 0;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
encoded_byte = (target % MOD) as u8;
|
||||||
|
target = target / 128;
|
||||||
|
if target > 0 {
|
||||||
|
encoded_byte = encoded_byte | 128;
|
||||||
|
}
|
||||||
|
res[i] = encoded_byte;
|
||||||
|
i = i + 1;
|
||||||
|
if target <= 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Ok(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Variable byte integer decoder structure is help structure which implements function used to
|
||||||
|
/// decode message lenghts in MQTT packet and other parts encoded into variable byte integer.
|
||||||
|
pub struct VariableByteIntegerDecoder;
|
||||||
|
|
||||||
|
|
||||||
|
impl VariableByteIntegerDecoder {
|
||||||
|
/// Decode function takes as paramater encoded integer represented
|
||||||
|
/// as array of 4 unsigned numbers of exactly 1 Byte each -> 4 Bytes maximal
|
||||||
|
/// same as maximal amount of bytes for variable byte encoding in MQTT.
|
||||||
|
pub fn decode(encoded: [u8; 4]) -> Result<u32, VariableByteIntegerError> {
|
||||||
|
let mut multiplier: u32 = 1;
|
||||||
|
let mut ret: u32 = 0;
|
||||||
|
|
||||||
|
let mut encoded_byte: u8;
|
||||||
|
let mut i: usize = 0;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
encoded_byte = encoded[i];
|
||||||
|
i = i + 1;
|
||||||
|
ret = ret + ((encoded_byte & 127) as u32 * multiplier) as u32;
|
||||||
|
if multiplier > 128 * 128 * 128 {
|
||||||
|
return Err(VariableByteIntegerError::DecodingError);
|
||||||
|
}
|
||||||
|
multiplier = multiplier * 128;
|
||||||
|
if (encoded_byte & 128) == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(ret);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user