diff --git a/src/protobuf/CMakeLists.txt b/src/protobuf/CMakeLists.txt index 3ef598da..884a9e04 100644 --- a/src/protobuf/CMakeLists.txt +++ b/src/protobuf/CMakeLists.txt @@ -3,6 +3,7 @@ qt_internal_add_module(Protobuf SOURCES + protobuffieldpresencechecker_p.h qtprotobufglobal.h qabstractprotobufserializer.cpp qabstractprotobufserializer.h qprotobufjsonserializer.cpp qprotobufjsonserializer.h diff --git a/src/protobuf/protobuffieldpresencechecker_p.h b/src/protobuf/protobuffieldpresencechecker_p.h new file mode 100644 index 00000000..f83a0bb8 --- /dev/null +++ b/src/protobuf/protobuffieldpresencechecker_p.h @@ -0,0 +1,80 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef PROTOBUFFIELDPRESENCECHECKER_P_H +#define PROTOBUFFIELDPRESENCECHECKER_P_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include + +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +namespace ProtobufFieldPresenceChecker +{ + template + using HasIsEmpty = decltype(&T::isEmpty); + template + using has_is_empty_method = qxp::is_detected; + + template + constexpr inline bool IsProtobufTrivialScalarValueType = false; + template <> + constexpr inline bool IsProtobufTrivialScalarValueType = true; + template <> + constexpr inline bool IsProtobufTrivialScalarValueType = true; + template <> + constexpr inline bool IsProtobufTrivialScalarValueType = true; + template <> + constexpr inline bool IsProtobufTrivialScalarValueType = true; + template <> + constexpr inline bool IsProtobufTrivialScalarValueType = true; + template <> + constexpr inline bool IsProtobufTrivialScalarValueType = true; + template <> + constexpr inline bool IsProtobufTrivialScalarValueType = true; + template <> + constexpr inline bool IsProtobufTrivialScalarValueType = true; + template <> + constexpr inline bool IsProtobufTrivialScalarValueType = true; + template <> + constexpr inline bool IsProtobufTrivialScalarValueType = true; + template <> + constexpr inline bool IsProtobufTrivialScalarValueType = true; + template <> + constexpr inline bool IsProtobufTrivialScalarValueType = true; + template <> + constexpr inline bool IsProtobufTrivialScalarValueType = true; + + using Function = bool (*)(const QVariant &); + + template , bool> = true> + static bool isPresent(const QVariant &value) + { + return value.value() != T{}; + } + + template ::value, bool> = true> + static bool isPresent(const QVariant &value) + { + return !value.value().isEmpty(); + } +} + + +QT_END_NAMESPACE + +#endif // PROTOBUFFIELDPRESENCECHECKER_P_H diff --git a/src/protobuf/qprotobufjsonserializer.cpp b/src/protobuf/qprotobufjsonserializer.cpp index 9372e8a7..4b687212 100644 --- a/src/protobuf/qprotobufjsonserializer.cpp +++ b/src/protobuf/qprotobufjsonserializer.cpp @@ -3,6 +3,7 @@ #include +#include #include #include #include @@ -105,7 +106,7 @@ public: Serializer serializer; // deserializer assigned to class Deserializer deserializer; - QProtobufSerializerPrivate::IsPresentChecker isPresent; + ProtobufFieldPresenceChecker::Function isPresent; }; template @@ -113,7 +114,7 @@ public: { return { QProtobufJsonSerializerPrivate::serializeCommon, QProtobufJsonSerializerPrivate::deserializeCommon, - QProtobufSerializerPrivate::isPresent }; + ProtobufFieldPresenceChecker::isPresent }; } template @@ -121,7 +122,7 @@ public: { return { QProtobufJsonSerializerPrivate::serializeList, QProtobufJsonSerializerPrivate::deserializeList, - QProtobufSerializerPrivate::isPresent }; + ProtobufFieldPresenceChecker::isPresent }; } template(), \ - QProtobufSerializerPrivate::serializeWrapper< \ - Type, QProtobufSerializerPrivate::serializeBasic>, \ - QProtobufSerializerPrivate::deserializeBasic, \ - QProtobufSerializerPrivate::isPresent, WireType \ - } -#define QT_CONSTRUCT_PROTOBUF_LIST_SERIALIZATION_HANDLER(ListType, Type) \ - { \ - QMetaType::fromType(), \ - QProtobufSerializerPrivate::serializeWrapper< \ - ListType, QProtobufSerializerPrivate::serializeListType>, \ - QProtobufSerializerPrivate::deserializeList, \ - QProtobufSerializerPrivate::isPresent, \ - QtProtobuf::WireTypes::LengthDelimited \ - } +#define QT_CONSTRUCT_PROTOBUF_SERIALIZATION_HANDLER(Type, WireType) \ + { QMetaType::fromType(), \ + QProtobufSerializerPrivate::serializeWrapper< \ + Type, QProtobufSerializerPrivate::serializeBasic>, \ + QProtobufSerializerPrivate::deserializeBasic, \ + ProtobufFieldPresenceChecker::isPresent, WireType } +#define QT_CONSTRUCT_PROTOBUF_LIST_SERIALIZATION_HANDLER(ListType, Type) \ + { QMetaType::fromType(), \ + QProtobufSerializerPrivate::serializeWrapper< \ + ListType, QProtobufSerializerPrivate::serializeListType>, \ + QProtobufSerializerPrivate::deserializeList, \ + ProtobufFieldPresenceChecker::isPresent, QtProtobuf::WireTypes::LengthDelimited } #define QT_CONSTRUCT_PROTOBUF_NON_PACKED_LIST_SERIALIZATION_HANDLER(ListType, Type, WireType) \ -{ \ -QMetaType::fromType(), \ - QProtobufSerializerPrivate::serializeNonPackedWrapper< \ - ListType, QProtobufSerializerPrivate::serializeNonPackedList>, \ - QProtobufSerializerPrivate::deserializeNonPackedList, \ - QProtobufSerializerPrivate::isPresent, WireType \ -} + { QMetaType::fromType(), \ + QProtobufSerializerPrivate::serializeNonPackedWrapper< \ + ListType, QProtobufSerializerPrivate::serializeNonPackedList>, \ + QProtobufSerializerPrivate::deserializeNonPackedList, \ + ProtobufFieldPresenceChecker::isPresent, WireType } constexpr SerializerRegistryType<30> IntegratedTypesSerializers = { { QT_CONSTRUCT_PROTOBUF_SERIALIZATION_HANDLER(float, QtProtobuf::WireTypes::Fixed32), diff --git a/src/protobuf/qprotobufserializer_p.h b/src/protobuf/qprotobufserializer_p.h index 6e429a9f..162ad3a4 100644 --- a/src/protobuf/qprotobufserializer_p.h +++ b/src/protobuf/qprotobufserializer_p.h @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -131,7 +132,6 @@ public: // Deserializer is interface function for deserialize method using Deserializer = bool (*)(QProtobufSelfcheckIterator &, QVariant &); // Function checks if value in QVariant is considered to be non-ignorable. - using IsPresentChecker = bool (*)(const QVariant &); // SerializationHandlers contains set of objects that required for class // serializaion/deserialization @@ -140,22 +140,10 @@ public: QMetaType metaType; Serializer serializer; // serializer assigned to class Deserializer deserializer; // deserializer assigned to class - IsPresentChecker isPresent; // checks if contains non-ignorable value + ProtobufFieldPresenceChecker::Function isPresent; // checks if contains non-ignorable value QtProtobuf::WireTypes wireType; // Serialization WireType }; - template::value || IsInt::value, int> = 0> - static bool isPresent(const QVariant &value) - { - return value.value() != 0; - } - - template::value && !IsInt::value, int> = 0> - static bool isPresent(const QVariant &value) - { - return !value.value().isEmpty(); - } - QProtobufSerializerPrivate() = default; ~QProtobufSerializerPrivate() = default; // ###########################################################################