I need to read and write numerical values of specified bit-length (not necessarily multiples of 8) at a specified bit-offset in a memory buffer, the most-significant bit first.
For example, writing the value of 5 at offset 6 and bit-length 4:
before: 11111111 11111111
bits: ^^ ^^
after: 11111101 01111111
So the functions I'm looking for may be defined like this:
unsigned get_bits (unsigned char *buffer, int offset, int bit_size);
void set_bits (unsigned char *buffer, int offset, int bit_size,
unsigned value);
And example usage:
set_bits (buffer, 6, 4, 5);
unsigned v = get_bits (buffer, 6, 4);
assert (v == 5);
The functions will be used to read/write a small number of values in a relatively big buffer (filtering network traffic of high volume), so I discarded (perhaps wrongly) using std::bitset
.
Are there any existing libraries which could be used to achieve/simplify this task? Any suggestions regarding implementing it?
Bit-fiddling is seldom easy. Here's a complete working example of how to do what you want.
The big problem here is reading and writing blocks of numbers across byte boundaries. Problems are always easier if you break them into bite-size chunks, if you'll pardon the pun.
Firstly I created a class like std::bitset that can wrap a user-defined buffer. It lets us fiddle with individual bits in a big buffer of binary data.
Then I wrote some functions to get and set blocks of bits from the buffer, MSB first.
And a test harness:
To compile, just dump all this in one file and compile. Output of test run:
Let me know if you find it useful, or if you have any problems with it.