[SOLVED] Conversion of QByteArray to QString
-
I'm working on an interface between an NetBurner module and my PC and I'm running into an issue or possible bug? I receive a UDP datagram from the NEtburner unit and store it into a QByteArray called "buffer" and proceed to truncate the first 112 bytes to align the start of the MAC address with byte 0 of the QByteArray. I then proceed to convert the MAC address to a QString as follows:
@ QByteArray buffer;
buffer.resize(udpSocket->pendingDatagramSize()); qDebug() << "Datagram Size" << udpSocket->pendingDatagramSize(); QHostAddress sender; quint16 senderPort; udpSocket->readDatagram(buffer.data(), buffer.size(), &sender, &senderPort); qDebug() << "Datagram ID: " << buffer.toHex().toUpper(); QString nburn_data; nburn_data.append(separator); buffer.remove(0,112); qDebug() << "Truncated Datagram: " << buffer.toHex().toUpper(); nburn_data.append("MAC Address: "); for (int i = 0; i < 6; i++) { nburn_data.append(QString::fromUtf8(buffer.left(1).toHex().toUpper(), buffer.left(1).size())); nburn_data.append(QString(":")); buffer.remove(0,1); qDebug() << "Truncated Datagram: " << buffer.toHex().toUpper(); } qDebug() << "Truncated Datagram: " << buffer.toHex().toUpper();@
(It's sloppy, and I'm sure there's a better way to do this, but I'm still new and haven't figured it all out yet... )
The issue is this - it truncates the data correctly, but it's not converting the data correctly. IF I convert the first 4 bytes of the original datagram, it converts correctly and I get the "NETB" that I'm expecting, and even the following byte "R" converts correctly. For some reason, when I convert the byte array after truncating 112 bytes, it doesn't convert correctly. I get the upper nibble of each byte only. Can anyone explain why this happens?
-
Why not use something like this:
@
QByteArray buffer;QString result(buffer.toHex());
result = result.mid(112);
@ -
I've tried that already. So the incoming datagram is a mix of char and int data. I have a map of the data and where it should start. Byte 112 starts char data representing the MAC address. I setup qDebug() to output every time it truncates the data:
@qDebug() << "Datagram info: " << datagram.toHex().toUpper();@
So for a MAC address of 00:03:F4:C6:DA:44 in the incoming datagram, qDebug shows me this result after each truncate:
0003F4C6DA44
03F4C6DA44
F4C6DA44
C6DA44
DA44
44but when I convert the data as above, I get this:
0:0:F:C:D:4
Somehow, it's only reading the upper nibble of the byte.
-
So I tried to recreate your problem, but used left(2) instead of left(1) and got this result:
@"0003f4c6da44"
Truncated Datagram: "03F4C6DA44"
Truncated Datagram: "F4C6DA44"
Truncated Datagram: "C6DA44"
Truncated Datagram: "DA44"
Truncated Datagram: "44"
Truncated Datagram: ""
"00:03:F4:C6:DA:4:"
@code:
@#include <QByteArray>
#include <QDebug>int main(int argc, char *argv[])
{
Q_UNUSED(argc);
Q_UNUSED(argv);QByteArray buffer; buffer.append((char)0x00); buffer.append((char)0x03); buffer.append((char)0xF4); buffer.append((char)0xC6); buffer.append((char)0xDA); buffer.append((char)0x44); qDebug() << buffer.toHex(); QString nburn_data; for (int i = 0; i < 6; i++) { nburn_data.append(QString::fromUtf8(buffer.left(2).toHex().toUpper(), buffer.left(2).size())); nburn_data.append(QString(":")); buffer.remove(0,1); qDebug() << "Truncated Datagram: " << buffer.toHex().toUpper(); } qDebug() << nburn_data; return 0;
}@
-
I am honestly not sure why that works... my understanding of
@QByteArray QByteArray::left(int len) const@
from "this description":http://qt-project.org/doc/qt-5/qbytearray.html#left is exactly what its one sentence description says: "Returns a byte array that contains the leftmost len bytes of this byte array" - It says len is the number of BYTES... so how is it reading the upper 4 bits only? confusing...
The MAC address I'm reading is only 6 bytes. Every time I truncate it, I remove the left most byte, and I do this six times. Yet I'm reading 2 bytes each time I do it? Does anyone by chance have a better understanding of how this works? I'd like to understand this better to avoid another goof-up like this. in the future.
JvdGlind, your solution worked, thank you very much for taking a moment to look it over!
-
I submitted it as a possible bug. Lets see what they say.
-
Response from the bug report:
"First of all, the size() of a string of 1 character is 1. So buffer.left(1).size() is pointless, you already know it's 1.
Second, if you know you're appending one character to the QString, you should use the QString::append overload that appends a single QChar. It's more efficient.
Third, you're using QString::fromUtf8 on data that you know to be Latin 1 only, due to use of QByteArray::toHex. Hex digits are always Latin 1. You should use QString::fromLatin1 for more efficiency.
Up to here, everything is just performance enhancement suggestions. The next one is probably the source of your problem:
You called QString::fromUtf8 with the toHex of one byte (which is two characters) and a size of 1. That means you only always append one character."
So I now see that the reason it your method worked is because in viewing the output of the data buffer, I was actually looking at the actual characters and not the hex value? Good to know for the future lol. Thanks again for the help!!