I think the code posted by Salem may be incorrect.
Code:
#include <stdio.h>
#include <limits.h>
int getBits ( char *buff, int *bitpos, int numbits ) {
int byte = *bitpos / CHAR_BIT;
int bit = *bitpos % CHAR_BIT;
int mask = (1<<numbits)-1;
int word = buff[byte] | (buff[byte+1]<<8);
*bitpos += numbits;
return ( word >> bit ) & mask;
}
void test(const char *buff)
{
int bitpos=0;
printf( "3=%x\n", getBits(buff,&bitpos,3) );
printf( "4=%x\n", getBits(buff,&bitpos,4) );
printf( "5=%x\n", getBits(buff,&bitpos,5) );
printf( "3=%x\n", getBits(buff,&bitpos,3) );
printf( "4=%x\n", getBits(buff,&bitpos,4) );
printf( "5=%x\n", getBits(buff,&bitpos,5) );
}
int main(void)
{
/* LSB 0001:1110-0000:0001-1119:0000 MSB */
/* 3334:4445-5555:3334-4445:5555 */
const char buf1[] = { 0x78, 0x80, 0x07 };
/* LSB 0101:0101-1010:1010-0101:0101 MSB */
/* 3334:4445-5555:3334-4445:5555 */
const char buf2[] = { 0xAA, 0x55, 0xAA };
/* LSB 1010:1010-0101:0101-1010:1010 MSB */
/* 3334:4445-5555:3334-4445:5555 */
const char buf3[] = { 0x55, 0xAA, 0x55 };
test(buf1);
puts("---");
test(buf2);
puts("---");
test(buf3);
return 0;
}
/* my (annotated) output
3=0
4=f
5=0
3=0
4=f
5=0
---
3=2
4=5
5=1f <<< incorrect, should be 0xB
3=5
4=4
5=15
---
3=5
4=a
5=14
3=2
4=f <<< incorrect, should be 0xB
5=a
*/
I haven't come up with a better solution yet, I just wanted to point this out. Also, should the 8 in the following have been CHAR_BIT?
Code:
int word = buff[byte] | (buff[byte+1]<<8);