-
-
Notifications
You must be signed in to change notification settings - Fork 54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Selecting bit order #134
Comments
Interesting! I did not think of this. Currently Deku assumes and works with Most Significant Bit (MSB) where this format seems to be LSB. You could do some bit arithmetic to make this work but would be much more hacky then to put the fields in reverse order.... This is something I'd like to support in the future. |
This was something I came across while playing around with risc-v. Either you parse as MSB, or have a I like the global read from LSB better. |
Hi! We have finally encountered in-the-wild the exact reason I wrote
I think this can be handled by using the struct-level Let's try threading a struct-level |
Thanks @myrrlyn! I may be able to experiment a bit with this tomorrow, If I understand correctly, you mean passing a Msb0 or Lsb0 to the codegen? This is exactly how I'd like to approach it, something like: #[deku(bit_order = "lsb")]
struct MyStruct {
... The main issue I'm facing now is the way I'm consuming bits. I'm using If there's a better method to use let me know! For example: fn main() {
let data = vec![0x88u8, 0x41];
let bits = data.view_bits::<Lsb0>();
dbg!(&bits); // [0b00010001, 0b10000010]
// we consume --^^
// we want to consume --^^
let (left, right) = bits.split_at(2);
dbg!(&left); // [0b00] <-- we want 0b01 here (0b10 would also work w/ reversing)
dbg!(&right); // [0b00010001, 0b10000010]
} I have two alternative ideas:
|
I've been looking around at the implementation and stated goals and I think I'm settling on the notion of passing |
@myrrlyn I went down the generic route, I put an example
|
is this example working? it gives me the following error:
|
Nope it panics! That's right. The goal is to not make it panic... :) |
just lost few hours debugging my parsing code, and noticed this issue. it would be good idea to at least put in the docs that bit order is currently only msb. |
Sorry about that. Would using a 'reader' attribute help you out here? The data is given as Msb, but could be massaged to your liking. |
i think i will just cut the dependency and write parsing code myself |
Hi, i was wondering if there is still interest in moving this issue forwards? Matching the bit ordering with the documentation I'm referencing would be very helpful.
This seems promising. Is it possible to apply a custom |
Yes, if anyone would like to work on this issue I'd gladly review a PR
This isn't possible no, but may be an interesting addition. |
I've been poking at the bit_order branch recently, it basically seems down to assumptions that Msb bit order is being used. On the write side, I was able to produce correct looking behaviour by swapping out instances of pub trait BitOrderEndian: bitvec::order::BitOrder {
const PREFERRED_ENDIAN: Endian;
}
impl BitOrderEndian for bitvec::order::Msb0 {
const PREFERRED_ENDIAN: Endian = Endian::Big;
}
impl BitOrderEndian for bitvec::order::Lsb0 {
const PREFERRED_ENDIAN: Endian = Endian::Little;
}
fn extract_bits<B: BitOrderEndian>(s: &BitSlice<B, u8>, remaining: usize) -> &BitSlice<B, u8> {
if B::PREFERRED_ENDIAN == Endian::Big {
&s[s.len() - remaining..]
} else {
&s[..remaining]
}
} I don't know if there's a way to restructure this so we don't need to explicitly work with the bit slice endian. My test case has been to write 3 5 bit integers in a row, 0b00001, 0b00011, and 0b00111, and confirm they produce the result (in bytes) On the read side, at a glance it looks like the issues have to do with padding, because commenting out the following padding loop caused the ieee example to pass: for _ in 0..pad {
bits.insert(index, false);
} we might be able to put that behind an if statement of "using Msb0", i guess? but it's possible there's behavior I'm missing because Lsb0 is not currently rigorously tested. |
As a side note, we could probably use the methods on the BitField trait from bitvec to simplify the implementation. I'm assuming there's some reason why it doesn't seem to be in use, as it seems to have come into existance before deku. |
I don't know the implications as far as this issue, but #352 changes the read API quite a bit if you are working on this issue. |
I pushed https://github.com/sharksforarms/deku/tree/impl-reader-bit-order that is based on that MR and does an (vastly untested) good job of supporting the idea of I'll need this to correctly parse without hacks a squashfs v3 image, so expect some amount of push from myself to get this API done. (I'm not sure I care as much about
|
If interested, I pushed my read-only changes to an MR: #367 |
I wanted to write a IEEE 802.11 frame parser, and I found that the bit order is not matched. So I have to define fields in reversed order.
I want to define fields in right order, so I can make less mistakes.
Here is the code:
The text was updated successfully, but these errors were encountered: