Saturday, May 24, 2014

How-To: Convert struct in and from a QByteArray

V1.2
Hello!

Recently I wrote a post about a better way of performing type casting in C++ when needing the use of the problematic reinterpret_cast. Now I woud like to write some comments about another "casting", namely between a struct and a QByteArray.

Conversion using QDataStream

A conversion from a struct to a QByteArray can be usefull when somebody, for example, handles some data inside a struct and want to send it through a interface that works with QByteArray such as QIODevice. At the other side of the system, the received QByteArray may be needed to be converted back to a defined struct for proper handling.

In accordance to some references, the proper way of doing this is by constructing serialization and de-serialization methods specifically for doing such a job using QDataStream.

Here is a example for a serialization method:

QByteArray serialize()
{
    QByteArray byteArray;

    QDataStream stream(&byteArray, QIODevice::WriteOnly);
    stream.setVersion(QDataStream::Qt_4_5);

    stream << status_change_id
           << result_code
           << reserved[0]
           << reserved[1]
           << reserved[2];

    return byteArray;
}

And here how to deserialize some data:

void deserialize(const QByteArray& byteArray)
{
    QDataStream stream(byteArray);
    stream.setVersion(QDataStream::Qt_4_5);

    stream >> status_change_id
           >> result_code
           >> reserved[0]
           >> reserved[1]
           >> reserved[2];
}

Other options

Another option (now exclusivaly about converting from a QByteArray to a struct) is doing a cast of the QByteArray to a pointer of void and then static-casting to the desired struct, either in a const or non-const way:

void convertToStruct(const QByteArray& byteArray)
{
    //constData() used because const is desired; otherwise, prefer data() don't forgetting deep copy issues
    const void* poTemp = (const void*)byteArray.constData();
    const MyStruct* poStruct = static_cast< const MyStruct* >(poTemp);
}

Conclusion

In this article we saw how to do proper casting between a struct and a QByteArray, something that may come in handy many times when working with more advanced applications. About the usage of QDataStream for doing this work, I'ld suggest a reading on this forum thread where I had a discussion about the usage of QDataStream for such context. Another interesting reading would be this other thread where I discussed about other methods of doing this work and some other, more generalized suggestions were discussed.


God bless you!
Have a nice day!

References

No comments:

Post a Comment