1 | // Copyright (C) 2022 The Qt Company Ltd. |
2 | // Copyright (C) 2019 Alexey Edelev <semlanik@gmail.com> |
3 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
4 | |
5 | #include <QtProtobuf/qabstractprotobufserializer.h> |
6 | |
7 | #include <QtProtobuf/qprotobufmessage.h> |
8 | #include <QtProtobuf/qprotobufpropertyordering.h> |
9 | |
10 | #include <QtProtobuf/private/qtprotobufserializerhelpers_p.h> |
11 | |
12 | QT_BEGIN_NAMESPACE |
13 | |
14 | /*! |
15 | \class QAbstractProtobufSerializer |
16 | \inmodule QtProtobuf |
17 | \since 6.5 |
18 | \brief The QAbstractProtobufSerializer class is interface that represents |
19 | basic functions for serialization/deserialization. |
20 | \reentrant |
21 | |
22 | The QProtobufSerializer class registers serializers/deserializers for |
23 | classes implementing a protobuf message, inheriting \l QProtobufMessage. These |
24 | classes are generated automatically, based on a \c{.proto} file, using the CMake |
25 | function \l qt_add_protobuf or by running |
26 | \l {The qtprotobufgen Tool} {qtprotobufgen} directly. |
27 | |
28 | This class should be used as a base for specific serializers. The handlers |
29 | property contains all message-specific serializers and should be used while |
30 | serialization/deserialization. Inherited classes should reimplement scope of |
31 | virtual methods that used by registered message |
32 | serialization/deserialization functions. |
33 | */ |
34 | |
35 | /*! |
36 | \enum QAbstractProtobufSerializer::Error |
37 | \since 6.8 |
38 | |
39 | This enum contains possible errors that can occur during deserialization. |
40 | When an error occurs, call lastErrorString() to get a |
41 | human-readable error message. |
42 | |
43 | \value None No error occurred. |
44 | \value InvalidHeader Something went wrong while attempting to |
45 | decode a header in the message. |
46 | \value UnknownType While serializing or deserializing a |
47 | message, no deserializer was found |
48 | for a message field. |
49 | \value UnexpectedEndOfStream While deserializing a message, the |
50 | stream ended unexpectedly. |
51 | \value InvalidFormat The data has invalid format. For example |
52 | the JSON value doesn't match the field type. |
53 | */ |
54 | |
55 | /*! |
56 | \fn QAbstractProtobufSerializer::Error QAbstractProtobufSerializer::lastError() const |
57 | \since 6.8 |
58 | |
59 | Returns the last error for the serializer instance. |
60 | |
61 | \sa lastErrorString() |
62 | */ |
63 | |
64 | /*! |
65 | \fn QString QAbstractProtobufSerializer::lastErrorString() const |
66 | \since 6.8 |
67 | |
68 | Returns the last error string for the serializer instance. |
69 | |
70 | \sa lastError() |
71 | */ |
72 | |
73 | /*! |
74 | Destroys this QAbstractProtobufSerializer. |
75 | */ |
76 | QAbstractProtobufSerializer::~QAbstractProtobufSerializer() = default; |
77 | |
78 | /*! |
79 | \fn QByteArray QAbstractProtobufSerializer::serializeMessage(const QProtobufMessage *message) const |
80 | |
81 | This is called by serialize() to serialize a registered Protobuf \a message. |
82 | \a message must not be \nullptr. |
83 | Returns a QByteArray containing the serialized message. |
84 | */ |
85 | |
86 | /*! |
87 | \fn bool QAbstractProtobufSerializer::deserializeMessage(QProtobufMessage *message, |
88 | QByteArrayView data) const |
89 | |
90 | This is called by deserialize() to deserialize a registered Protobuf |
91 | \a message from a QByteArrayView \a data. \a message can be |
92 | assumed to not be \nullptr. |
93 | Returns \c true if deserialization was successful, otherwise \c false. |
94 | */ |
95 | |
96 | /*! |
97 | Serializes a registered Protobuf message \a message into a QByteArray. |
98 | \a message must not be \nullptr. |
99 | |
100 | \sa deserialize() |
101 | */ |
102 | QByteArray QAbstractProtobufSerializer::serialize(const QProtobufMessage *message) const |
103 | { |
104 | Q_ASSERT(message != nullptr && message->propertyOrdering() != nullptr |
105 | && message->propertyOrdering()->data != nullptr); |
106 | return serializeMessage(message); |
107 | } |
108 | |
109 | /*! |
110 | Deserializes a registered Protobuf message \a message from a QByteArray |
111 | \a data. \a message must not be \nullptr. |
112 | Returns \c true if deserialization was successful, otherwise \c false. |
113 | |
114 | Unexpected/unknown properties in the \a data are skipped. |
115 | |
116 | \sa serialize() |
117 | */ |
118 | bool QAbstractProtobufSerializer::deserialize(QProtobufMessage *message, QByteArrayView data) const |
119 | { |
120 | Q_ASSERT(message != nullptr && message->propertyOrdering() != nullptr |
121 | && message->propertyOrdering()->data != nullptr); |
122 | // Wipe the message by reconstructing it in place. |
123 | const auto mtype = QtProtobufSerializerHelpers::messageMetaObject(message)->metaType(); |
124 | mtype.destruct(data: message); |
125 | mtype.construct(where: message); |
126 | return deserializeMessage(message, data); |
127 | } |
128 | |
129 | QT_END_NAMESPACE |
130 | |