Skip to content
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

Why does to_bytes() reverse the bits? #31

Open
marcianx opened this issue Nov 29, 2015 · 4 comments
Open

Why does to_bytes() reverse the bits? #31

marcianx opened this issue Nov 29, 2015 · 4 comments

Comments

@marcianx
Copy link

I was looking for an efficient way to get a &[u8] from the BitVec to write the bits out to file (when the memory layout is little-endian). I was thinking of adding an as_bytes() view, but I noticed that to_bytes() flips the bits within each byte so that the as_bytes() I want would be inconsistent with it. And from_bytes() does the same flip (which made my tests in the code I'm writing fail confusingly).

So

  1. Why was the current version implemented as such?
  2. Can we expose a byte slice view or an iterator that views the bytes in little-bit-endian format?
@Gankra
Copy link
Contributor

Gankra commented Dec 1, 2015

This is pretty out of cache for me, but I seem to recall that having the bits in that order makes other operations much more straight-forward. Maybe @huonw remembers?

@huonw
Copy link

huonw commented Dec 1, 2015

I don't remember at all. I suspect it may be because these functions where designed for tests/literals, where writing 0b00100001 to correspond to setting the bits at index 2 and 7 looks slightly nicer (i.e. written like that, it reads left-to-right).

@marcianx
Copy link
Author

marcianx commented Dec 2, 2015

Thanks for the feedback, huonw and soon-to-be Dr. Gankro (as I gather from #20). ;)

As mentioned above I was kinda hoping to have a &[u8] view into the data for I/O. I wrote down some issues in bit-vec for what I was trying to do:

  • The from_bytes() and to_bytes() implementations reverse the bits of the input so that the bits appear in reverse order from what is needed.
  • One could use BitVec<u8> and use the block iterators, but
    • This specialization is currently missing useful helpers that are implemented only for BitVec<u32> which is the default. Replacing the u32-specific ::new with a generic one is backward incompatible, making the call ambiguous.
    • The function to access the underlying vector as a mut slice (actually, a mut Vec) is unsafe and intended only for the sister BitSet data structure, meaning that the user must ensure invariants specific to the implementation (in this case, unused bits need to be 0s).

Really, the last point is because I wanted to load the data with a single
reader.read_exact(mut_slice);
safely without worrying about meeting internal invariants.

So then I did the overundulgent thing (typically excusable for someone trying to learn a language) and reimplemented the data structure as a temporary measure to address all the above. Wooof!
I effectively just copied the Vec API. In any case, I would much rather use a "standard" solution like yours instead of my own, so if you have any thoughts on whether it makes sense to incorporate any patterns into bit-vec without breaking backward compatibility (or willingly breaking it), I would be happy to do so.

@pczarn
Copy link
Contributor

pczarn commented Dec 4, 2020

I agree with Huon.

Should we add elaborative functions such as from_bytes_le, from_bytes_be?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants