[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?


  • Moderators

    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
    44

    but 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!



  • No problem.

    I had the same question marks really when looking at the doc. Maybe somebody else can explain this behavior (or bug), because I've only been working with Qt for a week now.



  • I submitted it as a possible bug. Lets see what they say.



  • @JvdGlind -

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



  • A yes, sounds logical when they say it like that :). Thanks for posing the feedback here.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.