I need to extract content from a byte array (std::vector) to bitsets. The content could be straddling two bytes.
Here is my unit test:
std::vector<uint8_t> val = { 0xAB, 0xCD, 0xEF }; // is 101010111100110111101111
std::bitset<4> a = extractToBitSet<4>( val, 0 ); // should be 0x0A: 1010
std::bitset<8> bc = extractToBitSet<8>( val, 4 ); // should be 0xBC: 10111100
std::bitset<12> def = extractToBitSet<12>( val, 12 ); // should be 0x0DEF: 110111101111
CPPUNIT_ASSERT( a.to_string() == "1010" );
CPPUNIT_ASSERT( bc.to_string() == "10111100" );
CPPUNIT_ASSERT( def.to_string() == "110111101111" );
unsigned long aVal = a.to_ulong();
unsigned long bcVal = bc.to_ulong();
unsigned long defVal = def.to_ulong();
CPPUNIT_ASSERT( aVal == 0x0A );
CPPUNIT_ASSERT( bcVal == 0xBC );
CPPUNIT_ASSERT( defVal == 0x0DEF );
I came up with this solution:
template<size_t _Count> void reverseBitSet( std::bitset<_Count>& bitset )
{
bool val;
for ( size_t pos = 0; pos < _Count/2; ++pos )
{
val = bitset[pos];
bitset[pos] = bitset[_Count-pos-1];
bitset[_Count-pos-1] = val;
}
}
template<size_t _Count> std::bitset<_Count> extractToBitSet( const std::vector<uint8_t>& data, size_t offset )
{
std::bitset<_Count> res;
size_t pos = 0;
uint8_t tempVal;
std::bitset<8> tempBitSet;
while ( pos < _Count )
{
tempVal = data[ (offset + pos)/8 ];
tempBitSet = tempVal;
reverseBitSet( tempBitSet );
res[pos] = tempBitSet[(offset + pos)%8];
++pos;
}
reverseBitSet( res );
return res;
}
It works (my test pass) but it seems very unefficient with all those temporary bitsets being created + many reverse operations.
Is there a more elegant way to do that?
Why all the reversing? You could just explicitly set each bit as you go based on the specific operation you're performing. Just the one loop:
template <size_t N>
std::bitset<N> extract(std::vector<uint8_t> const& vs, size_t offset) {
std::bitset<N> res;
for (size_t i = 0; i < N; ++i) {
size_t full_off = offset + i;
auto& byte = vs[full_off / 8];
auto bit = byte & (1 << (7 - (full_off % 8)));
res.set(N-i-1, bit);
}
return res;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With