Deserializing QByteArray with known QMetaType::Type into QVariant

Viewed 175

I have a QByteArray containing the raw data of a variable.
The QMetaType::Type describing the variable is known.

I want to deserialize this variable into a QVariant

With the following inputs :

QByteArray bytes; // Consider it initialized
QMetaType::Type type; // Same

My attempts so far do not work:

QVariant var{bytes};
var.convert(type); // Does not work, apparently QVariant expects bytes to be a string representation of the variable
QDataStream ds(bytes, QIODevice::ReadOnly);
QVariant var;
ds >> var; // Does not work because bytes does not come from the serialization of a QVariant (especially, it lacks type information)

I cannot change my inputs or output types :

  • The inputs must be of type QByteArray and QMetaType::Type.
  • The output must be of type QVariant

Example :

//Inputs
QByteArray bytes = { 0x12, 0x34, 0x56, 0x78 };
QMetaType::Type type = QMetaType::UInt; // Suppose the size of unsigned int is 4 bytes (could be 2)
// Note: this is an example, in pratice I have to manage many types, including double

//Expected output:
QVariant var = deserialize(bytes, type);
// var.type() == QMetaType::UInt
// var.toUInt() == 305419896 (== 0x12345678)
2 Answers

Facing the same problem, I got around constructing the QVariant from a QByteArray directly through its data() method using the provided type id:

QByteArray bytes; // Consider it initialized
QMetaType::Type type; // Same
QVariant result(type.id(),bytes.data());

If the construction fails, you will end up with an invalid QVariant, but so far, for my types, it worked well.

You can write to an unsigned int and then convert it to QVariant:

    const char data[] = { 0x12, 0x34, 0x56, 0x78 };
    QByteArray bytes { QByteArray::fromRawData( data, 4) };

    QDataStream s {&bytes, QIODevice::ReadOnly};
    //write out the data to uint
    unsigned int x{};
    s >> x;

    //create a Qvariant from it
    QVariant var{x};

    qDebug () << "x: " << x;                       //305419896
    qDebug () << "variant: " << var;               //QVariant(uint, 305419896)
    qDebug () << "variant uint: " << var.toUInt(); //305419896

Alternatively you can also directly construct a QVariant:

    auto v = QVariant(bytes.toHex().toUInt());
    //auto v = QVariant(bytes.toUInt());            //this will not work
    qDebug () << "Bytes to uint; " << v.toUInt(); //305419896
Related