Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QtEndian



  • I receive raw data from a ble sensor in a QByteArray (5 bytes).
    Byte 0 is a flag, byte 1 and 2is a quint16 value, so is byte 3 and 4, data is in little endian format.

    I create a pointer to a quint8 array, and then extract the values with qFromLittleEndian

    ```
    

    auto data = reinterpret_cast<const quint8 *>(arrayValue.constData());

    quint8 flag = *data;
    quint16 valueOne = qFromLittleEndian<quint16>(data[1]);
    quint16 valueTwo = qFromLittleEndian<quint16>(data[3]);

    What happens is that only the first byte taken into account, see the example code:
    
    

    #include <QCoreApplication>
    #include <QtEndian>

    #include <iostream>

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);

    char byteData[]{'\x02', '\x02', '\01', '\xfc', '\x13'};
    
    QByteArray arrayValue = QByteArray::fromRawData(byteData, sizeof(byteData));
    auto data = reinterpret_cast<const quint8 *>(arrayValue.constData());
    
    quint8 flag = *data;
    quint16 valueOne = qFromLittleEndian<quint16>(data[1]);
    quint16 valueTwo = qFromLittleEndian<quint16>(data[3]);
    
    std::cout << "Receceived raw data in a QByteArray from a ble sensor." << std::endl << "Byte 0 is a flag, byte 1 and 2 is a quint16 value, so is byte 3 and 4" << std::endl;
    std::cout << "Data is in littleEndian so the values should read, flag = " << char(2) << ", valueOne = 258 and valueTwo = 5116" << std::endl << std::endl;
    
    std::cout << "flag: " << flag << " // valueOne: " << valueOne << " // valueTwo: " << valueTwo << std::endl;
    
    std::cout << "As  one can see, only the first byte (being the lsb) is used by qFromLittleEndian" << std::endl << std::endl;
    
    std::cout << "Is this expected behaviour from 'T qFromLittleEndian(const void *src)' and should I do: valueOne = data[2] * 256 + data[1];.\r\n"
                 "Am I missing something or is this a bug?, SomeOne?" << std::endl << std::endl;
    valueOne = data[2] * 256 + data[1];
    valueTwo = data[4] * 256 + data[3];
    
    
    std::cout << "flag: " << flag << " // valueOne: " << valueOne << " // valueTwo: " << valueTwo << std::endl;
    
    
    
    return a.exec();
    

    }

    Anyone any suggestion?
    Thanks in advance.

  • Moderators

    quint16 valueOne = qFromLittleEndian<quint16>(data[1]);
    quint16 valueTwo = qFromLittleEndian<quint16>(data[3]);
    

    So what you do is give qFromLittleEndian 8 bits and expect it to read the next 8 bits automatically? That's not how it works. You need to provide the whole 16 bits, for example:

    quint16 valueOne = qFromLittleEndian<quint16>(arrayValue.mid(1,2).data());
    

    Or easier, using QDataStream:

    QDataStream stream(arrayValue);
    stream.setByteOrder(QDataStream::LittleEndian);
    quint8 flag;
    quint16 valueOne;
    quint16 valueTwo;
    
    stream >> flag;
    stream >> valueOne;
    stream >> valueTwo;
    

    Edit: corrected some small typos.



  • Thanks for the solutions.
    I just realised that I should have given the pointer with an offset and not just the 8 bits.



  • @ThMars said in QtEndian:

    Thanks for the solutions.

    is your issue solved then? if so please don't forget to mark your post as such! Thanks.


Log in to reply