tags:

views:

649

answers:

3

Hi! 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.

+1  A: 

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 ) ;
}
yoco
The program will crash ... there are at least 2 bugs in your code.
TimW
+3  A: 

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 ) ;
}
TimW
Thanks, this is what I wanted. Typo at line 6: quint8 instead of qint8.
Dmitri
you are welcom, typo is fixed
TimW
A: 

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.

Tadeusz Kopec