Closed Dentrax closed 2 years ago
At first glance, a bool
only reads in a u8
. Not at my computer, but I think this is correct.
const BUFFER: &[u8] = &[
0x01, // bool - foo
0x00, 0x00, 0x00, 0x05, // u32 -bar
0x00, 0x00, 0x00, 0x07, // u32 -baz
0x00, 0x00, // u16 -qux
0x00, 0x09, 0x00, 0x00, 0x00,
];
Actually my BUFFER represents a UDP packet. That's why I put 4 bytes for each line. I should not edit this; instead, i should find a way out to parse the buffer into struct without lose 4 byte variable alignment.
There is a very WIP project here for some UDP packet handling: https://github.com/sharksforarms/hatchet/blob/master/src/layer/udp/mod.rs
@Dentrax sorry for the delay. Here's an example below using the pad
attributes and a 4 byte bool. Also is it possible your endian-ness is little?
Also you're making assumptions around floats, floats are stored very differently in memory. For example, 7_f32
See IEEE754
https://www.h-schmidt.net/FloatConverter/IEEE754.html
Float example:
#[derive(Debug, DekuRead, DekuWrite, PartialEq)]
pub struct Test(f32);
fn main() {
let t = Test(7_f32);
assert_eq!(vec![0x00, 0x00, 0xe0, 0x40], t.to_bytes().unwrap());
assert_eq!(Test(7_f32), Test::try_from(t.to_bytes().unwrap().as_ref()).unwrap());
}
Original example
use deku::prelude::*;
#[derive(Debug, PartialEq, DekuRead, DekuWrite)]
#[deku(endian = "little")]
pub struct Packet {
#[deku(bytes = "1", pad_bytes_after = "3")]
pub foo: bool,
// #[deku(bytes = "4")] // optional, u32 is 4 bytes
pub bar: u32,
#[deku(bytes = "2", pad_bytes_after = "2")]
pub baz: u32,
// #[deku(bytes = "2")] // optional, u16 is 4 bytes
pub qux: u16,
}
fn main() {
// represents a UDP packet
// each line represents different variable on struct
const BUFFER: &[u8] = &[
0x01, 0x00, 0x00, 0x00, // bool - foo
0x05, 0x00, 0x00, 0x00, // u32 - bar
0x07, 0x00, 0x00, 0x00, // f32 - baz
0x09, 0x00, 0x00, 0x00, // u16 - qux
];
let (_, val) = Packet::from_bytes((BUFFER.as_ref(), 0)).unwrap();
assert_eq!(val.foo, true); // BUFFER[0..4], expected: true, got: true
assert_eq!(val.bar, 5); // BUFFER[4..8], expected: 5, got: 5
assert_eq!(val.baz, 7); // BUFFER[8..12], expected: 7, got: 1e-44
assert_eq!(val.qux, 9); // BUFFER[12..16], expected: 9, got: 0
}
Let me know if you have further questions! Closing for now.
My full working code is the following:
Simply, I want to achieve the following scenario using
deku
:Problems
4 bytes
(32 bit) intou16
I'm getting the following error:
This is expected. But what I want here is that it should read 16 bits anyway, and the remaining 16 bits should be filled with
0
. By doing so, I'm able to continue to read 4 bytes from the buffer, each time.Using
#[deku(bits = "16")]
breaks packet order, since each variable consumes 4 bytes on a UDP packet. That's why I have to read32
bit for each time.float
returns incorrect valueFor example,
val.baz
returns1e-44
. But I expect7
instead. Because of:0x07, 0x00, 0x00, 0x00
What would your advices? Thanks in advance!