Reading bits at an offset

P

pedagani

Problem: read 'nBits' (where 0< nbits <= 32) from a buffer
'buffer[1024]' at a byte position 'pos' with a *bit* offset value of
'bitOffset'. Below is the code that does that (not tested for errors),
but was wondering if there is any better way of implementing the same.
Thank you.
-KK

//Step 1 - read the rest of the bits in the first byte
std::bitset< 8 > firstByte(buffer[pos]);
for ( int i = 0; i < bitOffset ; i++ )
firstByte = 0;
this->val = T (firstByte.to_ulong() << nBits);
int nBitsReadSoFar = (8 - bitOffset);

if ( nBits < nBitsReadSoFar ) //throw away extra bits
{
val >>= (nBitsReadSoFar - nBits);
nBitsReadSoFar = nBits;
return val;
}

//step 2: read integral number of bytes over which the bits are spread
int nIntegralBytes = (nBits - nBitsReadSoFar)/8;
unsigned long int acc = 0;
for ( int i = 0; i < nIntegralBytes; i++ )
{
acc |= ( buffer[pos + 1 + i] << ( (nIntegralBytes -1 - i) *8) );
nBitsReadSoFar += 8;
}
acc <<= nBits - nBitsReadSoFar;


//step 3: read rest of bits in the last byte
std::bitset< 8 > lastByte(buffer[pos + nIntegralBytes + 1]);
for ( int i = (nBits - nBitsReadSoFar); i < 8 ; i++ )
lastByte=0;
lastByte >>= (8 - (nBits - nBitsReadSoFar) );

//step 4 - club all the pieces of bitsets into one
val = ((firstByte.to_ulong() << nBits)| acc ) | lastByte.to_ulong();
return val;
 
P

pedagani

Problem: read 'nBits' (where 0< nbits <= 32) from a buffer
'buffer[1024]' at a byte position 'pos' with a *bit* offset value of
'bitOffset'. Below is the code that does that (not tested for errors),
but was wondering if there is any better way of implementing the same.
Thank you.
-KK

//Step 1 - read the rest of the bits in the first byte
std::bitset< 8 > firstByte(buffer[pos]);
for ( int i = 0; i < bitOffset ; i++ )
firstByte = 0;
this->val = T (firstByte.to_ulong() << nBits);
int nBitsReadSoFar = (8 - bitOffset);

if ( nBits < nBitsReadSoFar ) //throw away extra bits
{
val >>= (nBitsReadSoFar - nBits);
nBitsReadSoFar = nBits;
return val;
}

//step 2: read integral number of bytes over which the bits are spread
int nIntegralBytes = (nBits - nBitsReadSoFar)/8;
unsigned long int acc = 0;
for ( int i = 0; i < nIntegralBytes; i++ )
{
acc |= ( buffer[pos + 1 + i] << ( (nIntegralBytes -1 - i) *8) );
nBitsReadSoFar += 8;
}
acc <<= nBits - nBitsReadSoFar;


//step 3: read rest of bits in the last byte
std::bitset< 8 > lastByte(buffer[pos + nIntegralBytes + 1]);
for ( int i = (nBits - nBitsReadSoFar); i < 8 ; i++ )
lastByte=0;
lastByte >>= (8 - (nBits - nBitsReadSoFar) );

//step 4 - club all the pieces of bitsets into one
val = ((firstByte.to_ulong() << nBits)| acc ) | lastByte.to_ulong();
return val;

the fourth line in the code should have been
val =(firstByte.to_ulong() << nBits);
instead of
this->val = T (firstByte.to_ulong() << nBits);
 
P

pedagani

My colleague has found the solution for me: here I'm posting it, just
for archives
*not a tested code*
On windows platform use
__int64 acc=0;
for( int i = 0; i < 5; i++ )
{
__int64 tmp = buffer[ pos + i ] << ( (7 - i) *8 );
acc |= tmp;
}
acc <<= bitOffset;
acc >>= (64- nBits);
val = unsigned long int (acc);
for UNIX replacing __int64 with long long should help I guess
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top