Closed wcampbell0x2a closed 3 months ago
I'm facing problem here:
Using Hex: 8BF3DC7B9438984278B85E
#[derive(DekuRead, Debug, PartialEq)]
#[deku(endian = "little", bit_order = "lsb")]
pub struct TestStruct {
#[deku(bits = 4)]
a: u16,
#[deku(bits = 11)]
b: u16,
#[deku(bits = 13)]
c: u16,
}
A and B are correct (11 and 1848), but C translates to 6108, but it should be 6073 instead.
Here is also test for deku bit_order.rs. When added it fails with message:
thread 'test_bit_order_little' panicked at tests/bit_order.rs:383:5:
assertion `left == right` failed
left: BitOrderLittle { value_a: 11, value_b: 1848, value_c: 6108, value_d: 327, value_e: 226, value_f: 96, value_g: 133, value_h: 120, value_i: 56, value_j: 189 }
right: BitOrderLittle { value_a: 11, value_b: 1848, value_c: 6073, value_d: 327, value_e: 226, value_f: 96, value_g: 133, value_h: 120, value_i: 56, value_j: 189 }
Seems every other value is handled correctly, but the value_c has some weird problem. I have validated multiple times that the 6073 is correct value, so the test is valid.
#[derive(Debug, DekuRead, DekuWrite, PartialEq)]
#[deku(endian = "little", bit_order = "lsb")]
pub struct BitOrderLittle {
#[deku(bits = 4)]
value_a: u16,
#[deku(bits = 11)]
value_b: u16,
#[deku(bits = 13)]
value_c: u16,
#[deku(bits = 10)]
value_d: u16,
#[deku(bits = 8)]
value_e: u16,
#[deku(bits = 9)]
value_f: u16,
#[deku(bits = 9)]
value_g: u16,
#[deku(bits = 8)]
value_h: u16,
#[deku(bits = 7)]
value_i: u16,
#[deku(bits = 9)]
value_j: u16,
}
#[test]
fn test_bit_order_little() {
let data = vec![
0x8B, 0xF3, 0xDC, 0x7B, 0x94, 0x38, 0x98, 0x42, 0x78, 0xB8, 0x5E,
];
let bit_order_little = BitOrderLittle::try_from(data.as_ref()).unwrap();
assert_eq!(
bit_order_little,
BitOrderLittle {
value_a: 11,
value_b: 1848,
value_c: 6073,
value_d: 327,
value_e: 226,
value_f: 96,
value_g: 133,
value_h: 120,
value_i: 56,
value_j: 189,
}
);
let bytes = bit_order_little.to_bytes().unwrap();
assert_eq_hex!(bytes, data);
}
Found the bug in reader.rs:
match order {
Order::Lsb0 => {
let (rest, used) = rest.split_at(rest.len() - bits_left);
ret.extend_from_bitslice(used);
ret.extend_from_bitslice(&self.leftover);
if let Some(front_bits) = front_bits {
ret.extend_from_bitslice(front_bits);
}
self.leftover = rest.to_bitvec();
println!("read_bits: ret: {}", ret);
}
ret.extend_from_bitslice(&self.leftover);
should be below
if let Some(front_bits) = front_bits {
ret.extend_from_bitslice(front_bits);
}
Working code:
Order::Lsb0 => {
let (rest, used) = rest.split_at(rest.len() - bits_left);
ret.extend_from_bitslice(used);
if let Some(front_bits) = front_bits {
ret.extend_from_bitslice(front_bits);
}
ret.extend_from_bitslice(&self.leftover);
self.leftover = rest.to_bitvec();
println!("read_bits: ret: {}", ret);
}
You can find the fix and related test from here: https://github.com/tpisto/deku/tree/impl-reader-bit-order2
New problem - even with the fix I did for the previous error:
With data: 0xE8, 0x25, 0xF4
#[deku(endian = "little", bit_order = "lsb")]
pub struct Test {
#[deku(bits = 1)]
field_a: bool,
#[deku(bits = 23)]
field_b: u32,
}
field_b should be 8000244, but instead deku parses it as 1243764
Thanks for testing this and finding bugs!
New problem - even with the fix I did for the previous error:
With data: 0xE8, 0x25, 0xF4
#[deku(endian = "little", bit_order = "lsb")] pub struct Test { #[deku(bits = 1)] field_a: bool, #[deku(bits = 23)] field_b: u32, }
field_b should be 8000244, but instead deku parses it as 1243764
Just so I understand the problem. The following is the current behavior:
#[derive(Debug, DekuRead, DekuWrite, PartialEq)]
#[deku(endian = "little", bit_order = "lsb")]
pub struct Test {
#[deku(bits = 1)]
field_a: bool,
#[deku(bits = 23)]
field_b: u32,
}
// |||| ||| <-
let data = vec![0b1111_1110, 0b1111_0000, 0b1111_0000];
let bit_order_little = Test::try_from(data.as_ref()).unwrap();
assert_eq_hex!(
bit_order_little,
Test {
field_a: false,
// ||| |||| <-
field_b: 0b111_1000_0111_1000_0111_1111,
}
);
Where do those bits that I outlined fall in the correct assertion?
New problem - even with the fix I did for the previous error: With data: 0xE8, 0x25, 0xF4
#[deku(endian = "little", bit_order = "lsb")] pub struct Test { #[deku(bits = 1)] field_a: bool, #[deku(bits = 23)] field_b: u32, }
field_b should be 8000244, but instead deku parses it as 1243764
Just so I understand the problem. The following is the current behavior:
#[derive(Debug, DekuRead, DekuWrite, PartialEq)] #[deku(endian = "little", bit_order = "lsb")] pub struct Test { #[deku(bits = 1)] field_a: bool, #[deku(bits = 23)] field_b: u32, } // |||| ||| <- let data = vec![0b1111_1110, 0b1111_0000, 0b1111_0000]; let bit_order_little = Test::try_from(data.as_ref()).unwrap(); assert_eq_hex!( bit_order_little, Test { field_a: false, // ||| |||| <- field_b: 0b111_1000_0111_1000_0111_1111, } );
Where do those bits that I outlined fall in the correct assertion?
@tpisto could you elaborate? Thanks
I think the bit_order setting is not working in conjunction with padding bits yet. Consider this testcase:
#[derive(DekuRead, DekuWrite, Debug)]
#[deku(bit_order = "lsb")]
struct DekuTest {
pad: u8,
#[deku(bits=6, pad_bits_after = "10")]
flag: u16,
sent: u8,
}
#[test]
fn dekutest() -> Result<(), DekuError> {
let data = vec![0x13, 0x75, 0x0, 0xFF];
let (_, dt) = DekuTest::from_bytes((&data, 0))?;
let to_bytes = dt.to_bytes()?;
println!("{:?}", data);
println!("{:?}", to_bytes);
Ok(())
}
Output is
[19, 117, 0, 255]
[19, 0, 53, 255]
Although as far as I can tell the value in dt.flag is correct, so reading works, but writing back doesn't.
Is anyone working on this?
Is anyone working on this?
Not currently. I needs a fun rebase on top of current master.
Closing in favor of rebased https://github.com/sharksforarms/deku/pull/468
I think the bit_order setting is not working in conjunction with padding bits yet. Consider this testcase:
#[derive(DekuRead, DekuWrite, Debug)] #[deku(bit_order = "lsb")] struct DekuTest { pad: u8, #[deku(bits=6, pad_bits_after = "10")] flag: u16, sent: u8, } #[test] fn dekutest() -> Result<(), DekuError> { let data = vec![0x13, 0x75, 0x0, 0xFF]; let (_, dt) = DekuTest::from_bytes((&data, 0))?; let to_bytes = dt.to_bytes()?; println!("{:?}", data); println!("{:?}", to_bytes); Ok(()) }
Output is
[19, 117, 0, 255] [19, 0, 53, 255]
Although as far as I can tell the value in dt.flag is correct, so reading works, but writing back doesn't.
this is fixed in https://github.com/sharksforarms/deku/pull/468
Something like this:
See tests/bit_order.rs in this MR for more examples.