1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <QtProtobuf/private/qprotobufdeserializerbase_p.h>
5
6#include <QtProtobuf/private/qprotobufregistration_p.h>
7#include <QtProtobuf/private/qtprotobuflogging_p.h>
8#include <QtProtobuf/private/qtprotobufserializerhelpers_p.h>
9
10QT_BEGIN_NAMESPACE
11
12QProtobufDeserializerBase::QProtobufDeserializerBase()
13 = default;
14
15QProtobufDeserializerBase::~QProtobufDeserializerBase()
16 = default;
17
18bool QProtobufDeserializerBase::deserializeMessageField(QProtobufMessage *message)
19{
20 Q_ASSERT(message != nullptr);
21
22 auto prevCachedRepeatedIterator = std::move(m_cachedRepeatedIterator);
23 auto prevCachedPropertyValue = m_cachedPropertyValue;
24 auto prevCachedIndex = m_cachedIndex;
25 clearCachedValue();
26 bool result = deserializeMessage(message);
27 m_cachedPropertyValue = prevCachedPropertyValue;
28 m_cachedIndex = prevCachedIndex;
29 m_cachedRepeatedIterator = std::move(prevCachedRepeatedIterator);
30
31 return result;
32}
33
34bool QProtobufDeserializerBase::deserializeMessage(QProtobufMessage *message)
35{
36 Q_ASSERT(message != nullptr);
37
38 const auto *ordering = message->propertyOrdering();
39 for (int fieldIndex = nextFieldIndex(message); fieldIndex >= 0;
40 fieldIndex = nextFieldIndex(message)) {
41 QtProtobufPrivate::QProtobufFieldInfo fieldInfo(*ordering, fieldIndex);
42 if (m_cachedIndex != fieldIndex) {
43 if (!storeCachedValue(message)) {
44 setError(error: QAbstractProtobufSerializer::Error::InvalidFormat,
45 errorString: "Unable to store the property in message");
46 return false;
47 }
48
49 m_cachedPropertyValue = QtProtobufSerializerHelpers::messageProperty(message, fieldInfo,
50 allowInitialize: true);
51 m_cachedIndex = fieldIndex;
52 }
53
54 QMetaType metaType = m_cachedPropertyValue.metaType();
55 if (metaType.flags().testFlag(flag: QMetaType::IsPointer)) {
56 if (!deserializeMessageField(message: m_cachedPropertyValue.value<QProtobufMessage *>()))
57 return false;
58
59 continue;
60 }
61
62 const auto fieldFlags = fieldInfo.fieldFlags();
63 if ((fieldFlags.testFlags(flags: RepeatedMessageFlags)
64 || fieldFlags.testFlags(flags: { QtProtobufPrivate::FieldFlag::Map }))
65 && m_cachedPropertyValue.canView(targetType: QMetaType::fromType<QProtobufRepeatedIterator>())) {
66 if (!m_cachedRepeatedIterator.isValid())
67 m_cachedRepeatedIterator = m_cachedPropertyValue.view<QProtobufRepeatedIterator>();
68
69 if (!deserializeMessageField(message: m_cachedRepeatedIterator.addNext()))
70 return false;
71
72 m_cachedRepeatedIterator.push();
73 continue;
74 }
75
76 if (fieldFlags.testFlag(flag: QtProtobufPrivate::FieldFlag::Enum)) {
77 if (!deserializeEnum(value&: m_cachedPropertyValue, fieldInfo)) {
78 setError(error: QAbstractProtobufSerializer::Error::UnknownType,
79 errorString: "Unable to covert enum field to compatible serialization format");
80 return false;
81 }
82 continue;
83 }
84
85 if (deserializeScalarField(value&: m_cachedPropertyValue, fieldInfo)) {
86 if (!m_cachedPropertyValue.isValid())
87 return false;
88
89 continue;
90 }
91
92 auto handler = QtProtobufPrivate::findHandler(type: metaType);
93 if (!handler.deserializer) {
94 qProtoWarning() << "No deserializer for type" << metaType.name();
95 setError(error: QAbstractProtobufSerializer::Error::UnknownType,
96 errorString: QString::fromUtf8(utf8: "No deserializer is registered for type %1")
97 .arg(a: QString::fromUtf8(utf8: metaType.name())));
98 return false;
99 }
100
101 handler.deserializer([this](QProtobufMessage *
102 message) { return this->deserializeMessageField(message); },
103 m_cachedPropertyValue.data());
104 }
105
106 if (!storeCachedValue(message)) {
107 setError(error: QAbstractProtobufSerializer::Error::InvalidFormat,
108 errorString: "Unable to store the property in message");
109 return false;
110 }
111
112 return true;
113}
114
115bool QProtobufDeserializerBase::storeCachedValue(QProtobufMessage *message)
116{
117 bool ok = true;
118 if (m_cachedIndex >= 0 && !m_cachedPropertyValue.isNull()) {
119 const auto *ordering = message->propertyOrdering();
120 QtProtobufPrivate::QProtobufFieldInfo fieldInfo(*ordering, m_cachedIndex);
121 ok = QtProtobufSerializerHelpers::setMessageProperty(message, fieldInfo,
122 value: m_cachedPropertyValue);
123
124 clearCachedValue();
125 }
126 return ok;
127}
128
129void QProtobufDeserializerBase::clearCachedValue()
130{
131 m_cachedPropertyValue.clear();
132 m_cachedIndex = -1;
133 m_cachedRepeatedIterator = {};
134}
135
136QT_END_NAMESPACE
137

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of qtgrpc/src/protobuf/qprotobufdeserializerbase.cpp