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/qprotobufserializerbase_p.h> |
5 | |
6 | #include <QtProtobuf/private/qprotobufregistration_p.h> |
7 | #include <QtProtobuf/private/qtprotobufdefs_p.h> |
8 | #include <QtProtobuf/private/qtprotobuflogging_p.h> |
9 | #include <QtProtobuf/private/qtprotobufserializerhelpers_p.h> |
10 | |
11 | #include <QtProtobuf/qprotobufmessage.h> |
12 | #include <QtProtobuf/qprotobufpropertyordering.h> |
13 | #include <QtProtobuf/qprotobufrepeatediterator.h> |
14 | #include <QtProtobuf/qtprotobuftypes.h> |
15 | |
16 | QT_BEGIN_NAMESPACE |
17 | |
18 | QProtobufSerializerBase::QProtobufSerializerBase() = default; |
19 | QProtobufSerializerBase::~QProtobufSerializerBase() = default; |
20 | |
21 | void QProtobufSerializerBase::serializeMessage(const QProtobufMessage *message) |
22 | { |
23 | Q_ASSERT(message != nullptr); |
24 | |
25 | const auto *ordering = message->propertyOrdering(); |
26 | Q_ASSERT(ordering != nullptr); |
27 | |
28 | for (int index = 0; index < ordering->fieldCount(); ++index) { |
29 | int fieldNumber = ordering->fieldNumber(index); |
30 | Q_ASSERT_X(fieldNumber <= ProtobufFieldNumMax && fieldNumber >= ProtobufFieldNumMin, "" , |
31 | "Protobuf field number is out of range" ); |
32 | QtProtobufPrivate::QProtobufFieldInfo fieldInfo(*ordering, index); |
33 | QVariant value = QtProtobufSerializerHelpers::messageProperty(message, fieldInfo); |
34 | QMetaType metaType = value.metaType(); |
35 | |
36 | // Empty value |
37 | if (metaType.id() == QMetaType::UnknownType || value.isNull()) |
38 | continue; |
39 | |
40 | if (metaType.flags().testFlag(flag: QMetaType::IsPointer)) { |
41 | serializeMessageField(message: value.value<QProtobufMessage *>(), fieldInfo); |
42 | continue; |
43 | } |
44 | |
45 | if (value.canView(targetType: QMetaType::fromType<QProtobufRepeatedIterator>())) { |
46 | QProtobufRepeatedIterator propertyIt = value.view<QProtobufRepeatedIterator>(); |
47 | while (propertyIt.hasNext()) |
48 | serializeMessageField(message: propertyIt.next(), fieldInfo); |
49 | continue; |
50 | } |
51 | |
52 | QtProtobufPrivate::FieldFlags flags = fieldInfo.fieldFlags(); |
53 | // Convert enums to something known by scalar type serializers |
54 | if (flags.testFlag(flag: QtProtobufPrivate::FieldFlag::Enum)) { |
55 | if (!serializeEnum(value, fieldInfo)) |
56 | qProtoWarning() << metaType << " is not registered as protobuf enum" ; |
57 | continue; |
58 | } |
59 | |
60 | if (serializeScalarField(value, fieldInfo)) |
61 | continue; |
62 | |
63 | auto handler = QtProtobufPrivate::findHandler(type: metaType); |
64 | if (!handler.serializer) { |
65 | qProtoWarning("No serializer found for type %s" , value.typeName()); |
66 | continue; |
67 | } |
68 | |
69 | handler.serializer([this](const QProtobufMessage *message, |
70 | const QtProtobufPrivate::QProtobufFieldInfo |
71 | &fieldInfo) { serializeMessageField(message, fieldInfo); }, |
72 | value.constData(), fieldInfo); |
73 | } |
74 | } |
75 | |
76 | void QProtobufSerializerBase::serializeMessageField(const QProtobufMessage *message, |
77 | const QtProtobufPrivate::QProtobufFieldInfo |
78 | &fieldInfo) |
79 | { |
80 | serializeMessageFieldBegin(); |
81 | serializeMessage(message); |
82 | serializeMessageFieldEnd(message, fieldInfo); |
83 | } |
84 | |
85 | QT_END_NAMESPACE |
86 | |