
Time for action – serialization of a custom structure
Let's perform another small exercise by implementing functions that are required to use QDataStream
to serialize the same simple structure that contains the player information that we used for text streaming:
struct Player { QString name; qint64 experience; QPoint position; char direction; };
For this, two functions need to be implemented, both returning a QDataStream
reference that was taken earlier as an argument to the call. Apart from the stream itself, the serialization operator accepts a constant reference to the class that is being saved. The most simple implementation just streams each member into the stream and returns the stream afterwards:
QDataStream& operator<<(QDataStream &stream, const Player &p) { stream << p.name; stream << p.experience; stream << p.position; stream << p.direction; return stream; }
Complementary to this, deserializing is done by implementing a redirection operator that accepts a mutable reference to the structure that is filled by data that is read from the stream:
QDataStream& operator>>(QDataStream &stream, Player &p) { stream >> p.name; stream >> p.experience; stream >> p.position; stream >> p.direction; return stream; }
Again, at the end, the stream itself is returned.
What just happened?
We provided two standalone functions that define redirection operators for the Player
class to and from a QDataStream
instance. This lets your class be serialized and deserialized using mechanisms offered and used by Qt.
XML streams
XML has become one of the most popular standards that is used to store hierarchical data. Despite its verbosity and difficulty to read by human eye, it is used in virtually any domain where data persistency is required, as it is very easy to read by machines. Qt provides support for reading and writing XML documents in two modules. First, the QtXml
module provides access using the Document Object Model (DOM) standard with classes such as QDomDocument
, QDomElement
, and others. We will not discuss this approach here, as now the recommended approach is to use streaming classes from the QtCore
module. One of the downsides of QDomDocument
is that it requires us to load the whole XML tree into the memory before parsing it. In some situations, this is compensated for by the ease of use of the DOM approach as compared to a streamed approach, so you can consider using it if you feel you have found the right task for it.
Tip
If you want to use the DOM access to XML in Qt, remember to enable the QtXml
module in your applications by adding a QT += xml
line in the project configuration files.
As already said, we will focus on the stream approach implemented by the QXmlStreamReader
and QXmlStreamWriter
classes.