I'm writing a method that receives an instance of bytes::Bytes
representing a Type/Length/Value data structure where byte 0 is the type, the next 4 the length and the remaining the value. I implemented a unit test that is behaving a very unexpected way.
Given the method:
fn split_into_packets(packet: &Bytes) -> Vec<Bytes> {
let mut packets: Vec<Bytes> = Vec::new();
let mut begin: usize = 1;
while begin < packet.len() {
let slice = &packet[1..5];
print!("0: {} ", slice[0]);
print!("1: {} ", slice[1]);
print!("2: {} ", slice[2]);
println!("3: {}", slice[3]);
let size = u32::from_be_bytes(pop(slice));
println!("{}", size);
}
return packets;
}
And the test:
let mut bytes = BytesMut::with_capacity(330);
bytes.extend_from_slice(b"R\x52\x00\x00\x00\x08\x00");
let packets = split_into_packets(&bytes.freeze());
I see the following on my console:
0: 82 1: 0 2: 0 3: 0
I expected it to be:
0: 0 1: 0 2: 0 3: 82
What's going on? What am I missing?
fn split_into_packets(packet: &Bytes) -> Vec<Bytes> { // paket = "R\x52\x00\x00\x00\x08\x00"
let mut packets: Vec<Bytes> = Vec::new();
let mut begin: usize = 1;
while begin < packet.len() {
let slice = &packet[1..5]; // slice = "\x52\x00\x00\x00"
print!("0: {} ", slice[0]); // "\x52\x00\x00\x00"
^^^^
| |
+--+--- this is slice[0] = 0x52 = 82 (in decimal)
print!("1: {} ", slice[1]); // "\x52\x00\x00\x00"
^^^^
| |
+--+--- this is slice[1] = 0x0 = 0 (in decimal)
print!("2: {} ", slice[2]); // "\x52\x00\x00\x00"
^^^^
| |
+--+--- this is slice[2] = 0x0 = 0 (in decimal)
println!("3: {}", slice[3]); // "\x52\x00\x00\x00"
^^^^
| |
+--+--- this is slice[3] = 0x0 = 0 (in decimal)
let size = u32::from_be_bytes(pop(slice));
println!("{}", size);
}
return packets;
}
I hope the above explains why you get 82, 0, 0, 0
when printing the bytes one after another.
So, onto the next thing: How do we convert 4 bytes to an u32
: To do that there are two possibilities that differ in how they interpret the bytes:
from_be_bytes
: Converts bytes to u32
in big-endian: u32::from_be_bytes([0x12, 0x34, 0x56, 0x78])==0x12345678
from_le_bytes
: Converts bytes to u32
in little-endian: u32::from_le_bytes([0x78, 0x56, 0x34, 0x12])==0x12345678
For endianess, you can e.g. consult the respective wikipedia page.