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