How can I display a QByteArray in a TextArea?

167 Views Asked by At

I'm trying to make an encryption/decryption tool for some configuration files that allows for in-place editing of file contents (via a GUI). The encryption/decryption process is working fine, but I've run into an issue displaying the content of the file for editing.

The file being decrypted contains hex values that represent an integer value (4 bytes), followed by a null terminated string. Example of this file could be the following (int value of 1 and string value of Test).

"010000005465737400"

The decrypted contents are stored into a QByteArray that is then displayed using a TextArea element. The problem is the TextArea stops displaying text when a 0x00 value is reached. I expected it to have displayed a 0 instead of stopping.

Is there a way to display the byte array properly?

1

There are 1 best solutions below

0
Stephen Quan On

In the following, I implement testData() to generate an ArrayBuffer with your 9 bytes. Then I implement byteArraytoHexString() which uses byteLength to iterate through the data and convert it to a hex string:

import QtQuick
import QtQuick.Controls
Page {
    Frame {
        width: parent.width
        TextEdit {
            text: arrayBufferToHexString(testData())
        }
    }

    function testData() {
        let codes = [
             0x01, 0x00, 0x00, 0x00,
             0x54, 0x65, 0x73, 0x74,
             0x00
        ];
        return codesToArrayByteArray(codes);
    }

    function codesToArrayByteArray(codes) {
        let byteArray = new ArrayBuffer(codes.length);
        for (let i = 0; i < codes.length; i++)
             byteArray[i] = codes[i];
        return byteArray;
    }

    function arrayBufferToHexString(byteArray) {
        let result = [ ];
        for (let i = 0; i < byteArray.byteLength; i++)
             result.push(byteArray[i].toString(16).padStart(2, "0"));
        return result.join("");
    }
}

You can Try it Online!

I suspect the issue you're having is you treat the QByteArray as a string not an ArrayBuffer. Definitely, if it's converted to a string, then, the 0x00 byte may be considered as a NUL terminator and will prematurely terminate the data.

Because of your specific use case, you definitely want to avoid any string operation since the raw data must not be treated as a string.

Since you mentioned QByteArray, you would have C++ at your disposal.

I would highly recommend that you implement QByteArray to hex-string and hex-string back to QByteArray in C++ but expose these as Q_INVOKABLE methods in QML, e.g.

Q_INVOKABLE QString byteArrayToHexString(const QByteArray& buffer)
{
    return QString::fromUtf8(byteArray.toHex());
}
Q_INVOKABLE QByteArray hexStringToByteArray(const QString& hexString)
{
    returun QByteArray::fromHex(hexString.toUtf8());
}

If you do that, then it would enable QML to do the conversions in C++.