Reputation: 1173
I'm working on a little project for college, and I need to model transmission over network, and to impment and visualize different sorts of error correction algorithms. My improvized packet consists of one quint8: I need to convert it into a bit array, like QBitArray, append a check bit to it, trasfer it over UDP, check the success of transmission with the check bit, and then construct quint8 out of it. Once again, it's not a practical but educational task, so don't suggest me to use real algoriths like CRC...
So my question is: how do I convert any data type (in this case quint8) into QBitArray? I mean any data in computer is a bit array, but how do I access it is the question.
Thanks, Dmitri.
Upvotes: 4
Views: 9083
Reputation: 8447
Lets see if we can get it correct
template < class T >
static QBitArray toQBit ( const T &obj ) {
int const bitsInByte= 8;
int const bytsInObject= sizeof(T);
const quint8 *data = static_cast<const quint8*>(&obj) ;
QBitArray result(bytsInObject*bitsInByte);
for ( int byte=0; byte<bytsInObject ; ++byte ) {
for ( int bit=0; bit<bitsInByte; ++bit ) {
result.setBit ( byte*bitsInByte + bit, data[byte] & (1<<bit) ) ;
}
}
return result;
}
void Foo () {
Bar b ;
QBitArray qb = toQBit ( b ) ;
}
Upvotes: 6
Reputation: 12413
I don't see any point in declaring template function and then casting its argument to uint8. Solution for types that can be promoted to unsigned long
#include <bitset>
template <typename T>
QBitArray toQBit(T val) {
std::bitset<sizeof(T) * 8> bs(val);
QBitArray result(bs.size());
for (int ii = 0; ii < bs.size(); ++ii) {
result.setBit(ii, bs.test(ii));
}
return result;
}
There is no way to generically convert any data type to bit array. Especially if your data type contains pointers you probably want to transfer the pointee not the pointer. So any complex type should be treated separately. And be aware about different endiannes (little-endian and big-endian) in different architectures. I think that std::bitset is safe according to this problem, but for example casting a pointer to struct to a char array and storing its bits may not be safe.
Upvotes: 0
Reputation: 1424
qint8 is actually signed char. So you can treat your objs as a char array.
template < class T >
QBitArray toQBit ( T &obj ) {
int len = sizeof(obj) * 8 ;
qint8 *data = (qint8*)(&obj) ;
QBitArray result ;
for ( int i=0; i< sizeof(data); ++i ) {
for ( int j=0; j<8; ++j ) {
result.setBit ( i*8 + j, data[i] & (1<<j) ) ;
}
}
return result;
}
void Foo () {
Bar b ;
QBitArray qb = toQBit ( b ) ;
}
Upvotes: 1