diff --git a/src/protobuf/CMakeLists.txt b/src/protobuf/CMakeLists.txt index cf094c22..d3efdc00 100644 --- a/src/protobuf/CMakeLists.txt +++ b/src/protobuf/CMakeLists.txt @@ -9,7 +9,7 @@ qt_internal_add_module(Protobuf qprotobufmessage.cpp qprotobufmessage.h qprotobufmessage_p.h qprotobuflazymessagepointer.h qprotobufobject.h - qprotobufselfcheckiterator.h + qprotobufselfcheckiterator_p.h qprotobufserializer.cpp qprotobufserializer.h qprotobufserializer_p.h qprotobufjsonserializer.cpp qprotobufjsonserializer.h qtprotobuflogging.cpp qtprotobuflogging_p.h diff --git a/src/protobuf/qabstractprotobufserializer.h b/src/protobuf/qabstractprotobufserializer.h index cc8b6f20..9cbdb8d4 100644 --- a/src/protobuf/qabstractprotobufserializer.h +++ b/src/protobuf/qabstractprotobufserializer.h @@ -13,9 +13,12 @@ QT_BEGIN_NAMESPACE +namespace QtProtobuf { +class Any; +} + class Q_PROTOBUF_EXPORT QAbstractProtobufSerializer { - public: enum DeserializationError { NoError, @@ -69,6 +72,8 @@ private: bool doDeserialize(QProtobufMessage *message, const QtProtobufPrivate::QProtobufPropertyOrdering &ordering, QByteArrayView data) const; + + friend class QtProtobuf::Any; }; QT_END_NAMESPACE diff --git a/src/protobuf/qprotobufbaseserializer.cpp b/src/protobuf/qprotobufbaseserializer.cpp index 8cea8c20..942d7e61 100644 --- a/src/protobuf/qprotobufbaseserializer.cpp +++ b/src/protobuf/qprotobufbaseserializer.cpp @@ -27,12 +27,7 @@ QT_BEGIN_NAMESPACE */ /*! - Destroys this QProtobufBaseSerializer. -*/ -QProtobufBaseSerializer::~QProtobufBaseSerializer() = default; - -/*! - \fn QByteArray QProtobufBaseSerializer::serializeObject(const QProtobufMessage *message, + \fn void QProtobufBaseSerializer::serializeObject(const QProtobufMessage *message, const QtProtobufPrivate::QProtobufPropertyOrdering &ordering, const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo) const @@ -40,19 +35,115 @@ QProtobufBaseSerializer::~QProtobufBaseSerializer() = default; with defined \a ordering and \a fieldInfo, that is recognized like an object, into a QByteArray. \a message must not be \nullptr. - \sa deserializeObject() + You should not call this function directly. + + \sa QProtobufBaseSerializer::deserializeObject() */ /*! \fn bool QProtobufBaseSerializer::deserializeObject(QProtobufMessage *message, - const QtProtobufPrivate::QProtobufPropertyOrdering &ordering, - QtProtobufPrivate::QProtobufSelfcheckIterator &it) const + const QtProtobufPrivate::QProtobufPropertyOrdering &ordering) const This function deserializes a registered Protobuf message \a message - with defined \a ordering from the \a it iterator. \a message must not be \nullptr. + with defined \a ordering. \a message must not be \nullptr. Returns \c true if deserialization was successful, otherwise \c false. - \sa serializeObject() + You should not call this function directly. + + \sa QProtobufBaseSerializer::serializeObject() +*/ + +/*! + \fn void QProtobufBaseSerializer::serializeListObject(const QProtobufMessage *message, + const QtProtobufPrivate::QProtobufPropertyOrdering &ordering, + const QtProtobufPrivate::QProtobufPropertyOrderingInfo + &fieldInfo) const + + This function serializes \a message as part of a list of messages one by one + with \a ordering and \a fieldInfo. + + You should not call this function directly. + + \sa QProtobufBaseSerializer::deserializeListObject() +*/ + +/*! + \fn bool QProtobufBaseSerializer::deserializeListObject(QProtobufMessage *message, + const QtProtobufPrivate::QProtobufPropertyOrdering &ordering) const + + This function deserializes an \a message from byte stream as part of list property, with + the associated message \a ordering from a wire. + Returns \c true if deserialization was successful, otherwise \c false. + + You should not call this function directly. + + \sa QProtobufBaseSerializer::serializeListObject() +*/ + +/*! + \fn void QProtobufBaseSerializer::serializeMapPair(const QVariant &key, const QVariant &value, + const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo) const + + This function serializes pair of \a key and \a value, that belong as a protobuf map record, + according to \a fieldInfo. + + You should not call this function directly. + + \sa QProtobufBaseSerializer::deserializeMapPair() +*/ + +/*! + \fn bool QProtobufBaseSerializer::deserializeMapPair(QVariant &key, QVariant &value) const + This function deserializes a pair of \a key and \a value from a wire. + Returns \c true if deserialization was successful, otherwise \c false. + + You should not call this function directly. + + \sa QProtobufBaseSerializer::serializeMapPair() +*/ + +/*! + \fn void QProtobufBaseSerializer::serializeEnum(QtProtobuf::int64 value, + const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo) const + + This function serializes \a value from enum associated with property \a fieldInfo. + + You should not call this function directly. + + \sa QProtobufBaseSerializer::deserializeEnum() +*/ + +/*! + \fn bool QProtobufBaseSerializer::deserializeEnum(QtProtobuf::int64 &value) const + + This function deserializes an enum \a value from a wire. + Returns \c true if deserialization was successful, otherwise \c false. + + You should not call this function directly. + + \sa QProtobufBaseSerializer::serializeEnum() +*/ + +/*! + \fn void QProtobufBaseSerializer::serializeEnumList(const QList &value, + const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo) const + + This function serializes a list, \a value, for enum list associated with property \a fieldInfo. + + You should not call this function directly. + + \sa QProtobufBaseSerializer::deserializeEnumList() +*/ + +/*! + \fn bool QProtobufSerializer::deserializeEnumList(QList &value) const + + This function deserializes a list of enum \a value from a wire. + Returns \c true if deserialization was successful, otherwise \c false. + + You should not call this function directly. + + \sa QProtobufBaseSerializer::serializeEnumList() */ /*! diff --git a/src/protobuf/qprotobufbaseserializer.h b/src/protobuf/qprotobufbaseserializer.h index aee26da8..b9f248ef 100644 --- a/src/protobuf/qprotobufbaseserializer.h +++ b/src/protobuf/qprotobufbaseserializer.h @@ -5,7 +5,6 @@ #define QPROTOBUFSBASEERIALIZER_H #include -#include #include #include @@ -16,58 +15,44 @@ QT_BEGIN_NAMESPACE class Q_PROTOBUF_EXPORT QProtobufBaseSerializer: public QAbstractProtobufSerializer { - public: - enum Status { - Serialized = 0, - SerializationInProgress, - SerializationError - }; - - virtual ~QProtobufBaseSerializer(); - - virtual QByteArray + virtual void serializeObject(const QProtobufMessage *message, const QtProtobufPrivate::QProtobufPropertyOrdering &ordering, const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo) const = 0; - virtual bool deserializeObject(QProtobufMessage *message, - const QtProtobufPrivate::QProtobufPropertyOrdering &ordering, - QtProtobufPrivate::QProtobufSelfcheckIterator &it) const = 0; + virtual bool + deserializeObject(QProtobufMessage *message, + const QtProtobufPrivate::QProtobufPropertyOrdering &ordering) const = 0; - virtual QByteArray - serializeListObject(const QList &messageList, - const QtProtobufPrivate::QProtobufPropertyOrdering &ordering, - const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo) const = 0; - virtual Status + virtual void serializeListObject(const QProtobufMessage *message, + const QtProtobufPrivate::QProtobufPropertyOrdering &ordering, + const QtProtobufPrivate::QProtobufPropertyOrderingInfo + &fieldInfo) const = 0; + virtual bool deserializeListObject(QProtobufMessage *message, - const QtProtobufPrivate::QProtobufPropertyOrdering &ordering, - QtProtobufPrivate::QProtobufSelfcheckIterator &it) const = 0; + const QtProtobufPrivate::QProtobufPropertyOrdering &ordering) const = 0; - virtual QByteArray - serializeMapPair(const QList> &list, + virtual void + serializeMapPair(const QVariant &key, const QVariant &value, const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo) const = 0; - virtual Status deserializeMapPair(QVariant &key, QVariant &value, - QtProtobufPrivate::QProtobufSelfcheckIterator &it) const = 0; + virtual bool deserializeMapPair(QVariant &key, QVariant &value) const = 0; - virtual QByteArray + virtual void serializeEnum(QtProtobuf::int64 value, const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo) const = 0; - virtual QByteArray + virtual void serializeEnumList(const QList &value, const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo) const = 0; - virtual bool deserializeEnum(QtProtobuf::int64 &value, - QtProtobufPrivate::QProtobufSelfcheckIterator &it) const = 0; - virtual bool - deserializeEnumList(QList &value, - QtProtobufPrivate::QProtobufSelfcheckIterator &it) const = 0; + + virtual bool deserializeEnum(QtProtobuf::int64 &value) const = 0; + virtual bool deserializeEnumList(QList &value) const = 0; }; namespace QtProtobufPrivate { using Serializer = void (*)(const QProtobufBaseSerializer *, const QVariant &, - const QProtobufPropertyOrderingInfo &, QByteArray &); -using Deserializer = void (*)(const QProtobufBaseSerializer *, QProtobufSelfcheckIterator &, - QVariant &); + const QProtobufPropertyOrderingInfo &); +using Deserializer = void (*)(const QProtobufBaseSerializer *, QVariant &); /*! \private @@ -87,50 +72,44 @@ extern Q_PROTOBUF_EXPORT void registerHandler(QMetaType type, const Serializatio \private \brief default serializer template for type T that inherits from QProtobufMessage */ -template::value, int> = 0> void serializeObject(const QProtobufBaseSerializer *serializer, const QVariant &value, - const QProtobufPropertyOrderingInfo &fieldInfo, QByteArray &buffer) + const QProtobufPropertyOrderingInfo &fieldInfo) { Q_ASSERT_X(serializer != nullptr, "QProtobufBaseSerializer", "Serializer is null"); - buffer.append(serializer->serializeObject(value.value(), T::propertyOrdering, fieldInfo)); + serializer->serializeObject(value.value(), T::propertyOrdering, fieldInfo); } /*! \private \brief default serializer template for list of type T objects that inherits from QProtobufMessage */ -template::value, int> = 0> void serializeList(const QProtobufBaseSerializer *serializer, const QVariant &listValue, - const QProtobufPropertyOrderingInfo &fieldInfo, QByteArray &buffer) + const QProtobufPropertyOrderingInfo &fieldInfo) { - Q_ASSERT_X(serializer != nullptr, "QProtobufBaseSerializer", "Serializer is null"); - QList objList = listValue.value>(); - QList messageList; - for (const auto &value : objList) - messageList.append(&value); - buffer.append(serializer->serializeListObject(messageList, V::propertyOrdering, fieldInfo)); + Q_ASSERT_X(serializer != nullptr, "QProtobufSerializer", "Serializer is null"); + for (const auto &value : listValue.value>()) { + serializer->serializeListObject(&value, V::propertyOrdering, fieldInfo); + } } /*! \private \brief default serializer template for map of key K, value V */ -template::value, int> = 0> void serializeMap(const QProtobufBaseSerializer *serializer, const QVariant &value, - const QProtobufPropertyOrderingInfo &fieldInfo, QByteArray &buffer) + const QProtobufPropertyOrderingInfo &fieldInfo) { - Q_ASSERT_X(serializer != nullptr, "QProtobufBaseSerializer", "Serializer is null"); - QHash original = value.value>(); - QList> variantContainer; - for (const auto &[k, v] : original.asKeyValueRange()) { - variantContainer.append(qMakePair(QVariant::fromValue(k), - QVariant::fromValue(v))); + Q_ASSERT_X(serializer != nullptr, "QProtobufSerializer", "Serializer is null"); + for (const auto &[k, v] : value.value>().asKeyValueRange()) { + serializer->serializeMapPair(QVariant::fromValue(k), QVariant::fromValue(v), + fieldInfo); } - buffer.append(serializer->serializeMapPair(variantContainer, fieldInfo)); - } /*! @@ -138,58 +117,53 @@ void serializeMap(const QProtobufBaseSerializer *serializer, const QVariant &val \brief default serializer template for map of type key K, value V. Specialization for V that inherits from QProtobufMessage */ -template::value, int> = 0> void serializeMap(const QProtobufBaseSerializer *serializer, const QVariant &value, - const QProtobufPropertyOrderingInfo &fieldInfo, QByteArray &buffer) + const QProtobufPropertyOrderingInfo &fieldInfo) { - Q_ASSERT_X(serializer != nullptr, "QProtobufBaseSerializer", "Serializer is null"); - QHash original = value.value>(); - QList> variantContainer; - for (const auto &[k, v] : original.asKeyValueRange()) { - variantContainer.append(qMakePair(QVariant::fromValue(k), - QVariant::fromValue(&v))); - + Q_ASSERT_X(serializer != nullptr, "QProtobufSerializer", "Serializer is null"); + for (const auto &[k, v] : value.value>().asKeyValueRange()) { + serializer->serializeMapPair(QVariant::fromValue(k), QVariant::fromValue(&v), + fieldInfo); } - buffer.append(serializer->serializeMapPair(variantContainer, fieldInfo)); } /*! \private \brief default serializer template for enum types */ -template::value, int> = 0> +template ::value, int> = 0> void serializeEnum(const QProtobufBaseSerializer *serializer, const QVariant &value, - const QProtobufPropertyOrderingInfo &fieldInfo, QByteArray &buffer) + const QProtobufPropertyOrderingInfo &fieldInfo) { Q_ASSERT_X(serializer != nullptr, "QProtobufBaseSerializer", "Serializer is null"); - buffer.append(serializer->serializeEnum(QtProtobuf::int64(value.value()), fieldInfo)); + serializer->serializeEnum(QtProtobuf::int64(value.value()), fieldInfo); } /*! \private \brief default serializer template for enum list types */ -template::value, int> = 0> +template ::value, int> = 0> void serializeEnumList(const QProtobufBaseSerializer *serializer, const QVariant &value, - const QProtobufPropertyOrderingInfo &fieldInfo, QByteArray &buffer) + const QProtobufPropertyOrderingInfo &fieldInfo) { Q_ASSERT_X(serializer != nullptr, "QProtobufBaseSerializer", "Serializer is null"); QList intList; for (auto enumValue : value.value>()) { intList.append(QtProtobuf::int64(enumValue)); } - buffer.append(serializer->serializeEnumList(intList, fieldInfo)); + serializer->serializeEnumList(intList, fieldInfo); } /*! \private \brief default deserializer template for type T that inherits from QProtobufMessage */ -template::value, int> = 0> -void deserializeObject(const QProtobufBaseSerializer *serializer, QProtobufSelfcheckIterator &it, - QVariant &to) +void deserializeObject(const QProtobufBaseSerializer *serializer, QVariant &to) { Q_ASSERT_X(serializer != nullptr, "QProtobufBaseSerializer", "Serializer is null"); Q_ASSERT_X(to.isNull() || to.metaType() == QMetaType::fromType(), @@ -201,28 +175,24 @@ void deserializeObject(const QProtobufBaseSerializer *serializer, QProtobufSelfc value = new T; to = QVariant::fromValue(value); } - serializer->deserializeObject(value, T::propertyOrdering, it); + serializer->deserializeObject(value, T::propertyOrdering); } /*! \private \brief default deserializer template for list of type T objects that inherits from QProtobufMessage */ -template::value, int> = 0> -void deserializeList(const QProtobufBaseSerializer *serializer, QProtobufSelfcheckIterator &it, - QVariant &previous) +void deserializeList(const QProtobufBaseSerializer *serializer, QVariant &previous) { Q_ASSERT_X(serializer != nullptr, "QProtobufBaseSerializer", "Serializer is null"); V newValue; - QProtobufBaseSerializer::Status result = QProtobufBaseSerializer::SerializationError; - do { - result = serializer->deserializeListObject(&newValue, V::propertyOrdering, it); - QList list = previous.value>(); - list.append(newValue); - previous.setValue(list); - } while (result == QProtobufBaseSerializer::SerializationInProgress); + serializer->deserializeListObject(&newValue, V::propertyOrdering); + QList list = previous.value>(); + list.append(newValue); + previous.setValue(list); } /*! @@ -230,10 +200,9 @@ void deserializeList(const QProtobufBaseSerializer *serializer, QProtobufSelfche * \brief default deserializer template for map of key K, value V */ -template::value, int> = 0> -void deserializeMap(const QProtobufBaseSerializer *serializer, QProtobufSelfcheckIterator &it, - QVariant &previous) +void deserializeMap(const QProtobufBaseSerializer *serializer, QVariant &previous) { Q_ASSERT_X(serializer != nullptr, "QProtobufBaseSerializer", "Serializer is null"); @@ -241,7 +210,7 @@ void deserializeMap(const QProtobufBaseSerializer *serializer, QProtobufSelfchec QVariant key = QVariant::fromValue(K()); QVariant value = QVariant::fromValue(V()); - if (serializer->deserializeMapPair(key, value, it) == QProtobufBaseSerializer::Serialized) { + if (serializer->deserializeMapPair(key, value)) { out[key.value()] = value.value(); previous = QVariant::fromValue>(out); } @@ -253,10 +222,9 @@ void deserializeMap(const QProtobufBaseSerializer *serializer, QProtobufSelfchec \brief default deserializer template for map of type key K, value V. Specialization for V that inherits from QProtobufMessage */ -template::value, int> = 0> -void deserializeMap(const QProtobufBaseSerializer *serializer, QProtobufSelfcheckIterator &it, - QVariant &previous) +void deserializeMap(const QProtobufBaseSerializer *serializer, QVariant &previous) { Q_ASSERT_X(serializer != nullptr, "QProtobufBaseSerializer", "Serializer is null"); @@ -264,7 +232,7 @@ void deserializeMap(const QProtobufBaseSerializer *serializer, QProtobufSelfchec QVariant key = QVariant::fromValue(K()); QVariant value = QVariant::fromValue(nullptr); - if (serializer->deserializeMapPair(key, value, it) == QProtobufBaseSerializer::Serialized) { + if (serializer->deserializeMapPair(key, value)) { const auto valuePtr = value.value(); out[key.value()] = valuePtr ? *valuePtr : V(); previous = QVariant::fromValue>(out); @@ -276,13 +244,12 @@ void deserializeMap(const QProtobufBaseSerializer *serializer, QProtobufSelfchec * \brief default deserializer template for enum type T */ -template::value, int> = 0> -void deserializeEnum(const QProtobufBaseSerializer *serializer, QProtobufSelfcheckIterator &it, - QVariant &to) +template ::value, int> = 0> +void deserializeEnum(const QProtobufBaseSerializer *serializer, QVariant &to) { Q_ASSERT_X(serializer != nullptr, "QProtobufBaseSerializer", "Serializer is null"); QtProtobuf::int64 intValue; - if (serializer->deserializeEnum(intValue, it)) + if (serializer->deserializeEnum(intValue)) to = QVariant::fromValue(static_cast(intValue._t)); } @@ -291,13 +258,12 @@ void deserializeEnum(const QProtobufBaseSerializer *serializer, QProtobufSelfche * \brief default deserializer template for enumList type T */ -template::value, int> = 0> -void deserializeEnumList(const QProtobufBaseSerializer *serializer, QProtobufSelfcheckIterator &it, - QVariant &previous) +template ::value, int> = 0> +void deserializeEnumList(const QProtobufBaseSerializer *serializer, QVariant &previous) { Q_ASSERT_X(serializer != nullptr, "QProtobufBaseSerializer", "Serializer is null"); QList intList; - if (!serializer->deserializeEnumList(intList, it)) + if (!serializer->deserializeEnumList(intList)) return; QList enumList = previous.value>(); for (auto intValue : intList) diff --git a/src/protobuf/qprotobufjsonserializer.cpp b/src/protobuf/qprotobufjsonserializer.cpp index 0488faf4..52319e46 100644 --- a/src/protobuf/qprotobufjsonserializer.cpp +++ b/src/protobuf/qprotobufjsonserializer.cpp @@ -54,7 +54,7 @@ class QProtobufJsonSerializerPrivate final Q_DISABLE_COPY_MOVE(QProtobufJsonSerializerPrivate) public: - using Serializer = std::function; + using Serializer = std::function; using Deserializer = std::function; struct SerializationHandlers { @@ -67,126 +67,115 @@ public: // TBD Replace std::unordered_map to QHash using SerializerRegistry = std::unordered_map; - static QByteArray serializeFloat(const QVariant &propertyValue) + template + static QJsonValue serializeVarint(const QVariant &propertyValue) { - bool ok = false; - float value = propertyValue.toFloat(&ok); - if (!ok || qIsNaN(value)) { - return QByteArray("NaN"); - } - return QByteArray::number(value, 'g', 7); + return QJsonValue(qint64(propertyValue.value())); } - static QByteArray serializeDouble(const QVariant &propertyValue) + template + static QJsonValue serializeInt64Int(const QVariant &propertyValue) { - bool ok = false; - double value = propertyValue.toDouble(&ok); - if (!ok || qIsNaN(value)) { - return QByteArray("NaN"); - } - return QByteArray::number(value, 'g', 14); + return QJsonValue(QString::number(propertyValue.value())); } - static QByteArray serializeString(const QVariant &propertyValue) + static QJsonValue serializeFloat(const QVariant &propertyValue) { - return '"' + propertyValue.toString().toUtf8() + '"'; + // TODO: this is weak approach to no have some precision loss. Not sure why this happens, + // should be converted without the conversion to string. + return QJsonValue(QString::number(propertyValue.toFloat()).toDouble()); } - static QByteArray serializeBytes(const QVariant &propertyValue) { - return QByteArray("\"") + propertyValue.toByteArray().toBase64() + "\""; + static QJsonValue serializeDouble(const QVariant &propertyValue) + { + return QJsonValue(propertyValue.toDouble()); } - template - static QByteArray serializeList(const QVariant &propertyValue) + static QJsonValue serializeString(const QVariant &propertyValue) { + return QJsonValue(propertyValue.toString()); + } + + static QJsonValue serializeBytes(const QVariant &propertyValue) + { + return QJsonValue(QString::fromUtf8(propertyValue.toByteArray().toBase64())); + } + + template + static QJsonValue serializeList(const QVariant &propertyValue) + { + QJsonArray arr; L listValue = propertyValue.value(); - QByteArray result("["); - for (auto value : listValue) { - result += QByteArray::number(value) + ","; + for (const auto &value : listValue) { + arr.append(QJsonValue(qint64(value))); } - //Remove trailing `,` - if (listValue.size() > 0) { - result.chop(1); - } - result += "]"; - return result; + return QJsonValue(arr); } - static QByteArray serializeBoolList(const QVariant &propertyValue) + template + static QJsonValue serializeInt64bitList(const QVariant &propertyValue) { + QJsonArray arr; + L listValue = propertyValue.value(); + for (const auto &value : listValue) { + arr.append(QJsonValue(QString::number(value))); + } + return QJsonValue(arr); + } + + static QJsonValue serializeBoolList(const QVariant &propertyValue) + { + QJsonArray arr; QtProtobuf::boolList listValue = propertyValue.value(); - QByteArray result("["); - for (auto value : listValue) { - if (value) - result += QByteArray("true,"); - else - result += QByteArray("false,"); + for (const auto &value : listValue) { + arr.append(QJsonValue(value)); } - if (listValue.size() > 0) { - result.chop(1); - } - result += "]"; - return result; + return QJsonValue(arr); } - static QByteArray serializeFloatList(const QVariant &propertyValue) + static QJsonValue serializeFloatList(const QVariant &propertyValue) { + QJsonArray arr; QtProtobuf::floatList listValue = propertyValue.value(); - QByteArray result("["); - for (auto value : listValue) { - if (qIsNaN(value)) - return QByteArray("NaN"); - result += QByteArray::number(value, 'g', 7) + ","; + + for (const auto &value : listValue) { + // TODO: this is weak approach to not have some precision loss. Not sure why this + // happens, should be converted without the conversion to string. + arr.append(QJsonValue(QString::number(value).toDouble())); } - if (listValue.size() > 0) { - result.chop(1); - } - result += "]"; - return result; + return QJsonValue(arr); } - static QByteArray serializeStringList(const QVariant &propertyValue) + static QJsonValue serializeStringList(const QVariant &propertyValue) { + QJsonArray arr; QStringList listValue = propertyValue.value(); - QByteArray result("["); - for (auto value : listValue) { - result += QByteArray("\"") + value.toUtf8() + "\","; + for (const auto &value : listValue) { + arr.append(QJsonValue(value)); } - if (listValue.size() > 0) { - result.chop(1); - } - result += "]"; - return result; + + return QJsonValue(arr); } - static QByteArray serializeBytesList(const QVariant &propertyValue) + static QJsonValue serializeBytesList(const QVariant &propertyValue) { QByteArrayList listValue = propertyValue.value(); - QByteArray result("["); - for (auto value : listValue) { - result += QByteArray("\"") + value.toBase64() + "\","; + QJsonArray arr; + for (const auto &value : listValue) { + arr.append(QJsonValue(QString::fromUtf8(value.toBase64()))); } - if (listValue.size() > 0) { - result.chop(1); - } - result += "]"; - return result; + + return QJsonValue(arr); } - static QByteArray serializeDoubleList(const QVariant &propertyValue) + static QJsonValue serializeDoubleList(const QVariant &propertyValue) { QtProtobuf::doubleList listValue = propertyValue.value(); - QByteArray result("["); - for (auto value : listValue) { - if (qIsNaN(value)) - return QByteArray("NaN"); - result += QByteArray::number(value, 'g', 14) + ","; + QJsonArray arr; + for (const auto &value : listValue) { + arr.append(QJsonValue(value)); } - if (listValue.size() > 0) { - result.chop(1); - } - result += "]"; - return result; + return QJsonValue(arr); } QProtobufJsonSerializerPrivate(QProtobufJsonSerializer *q) @@ -194,26 +183,38 @@ public: { // TBD Change to assigning the result of a lambda to a static variable if (handlers.empty()) { - handlers[qMetaTypeId()] - = {{}, QProtobufJsonSerializerPrivate::deserializeInt32}; - handlers[qMetaTypeId()] - = {{}, QProtobufJsonSerializerPrivate::deserializeInt32}; + handlers[qMetaTypeId()] = { + QProtobufJsonSerializerPrivate::serializeVarint, + QProtobufJsonSerializerPrivate::deserializeInt32 + }; + handlers[qMetaTypeId()] = { + QProtobufJsonSerializerPrivate::serializeVarint, + QProtobufJsonSerializerPrivate::deserializeInt32 + }; handlers[qMetaTypeId()] = {{}, QProtobufJsonSerializerPrivate::deserializeInt32}; handlers[qMetaTypeId()] - = {{}, QProtobufJsonSerializerPrivate::deserializeInt64}; - handlers[qMetaTypeId()] - = {{}, QProtobufJsonSerializerPrivate::deserializeInt64}; - handlers[qMetaTypeId()] - = {{}, QProtobufJsonSerializerPrivate::deserializeInt64}; + = {serializeInt64Int, QProtobufJsonSerializerPrivate::deserializeInt64}; + handlers[qMetaTypeId()] = { + serializeInt64Int, + QProtobufJsonSerializerPrivate::deserializeInt64 + }; + handlers[qMetaTypeId()] = { + serializeInt64Int, + QProtobufJsonSerializerPrivate::deserializeInt64 + }; handlers[qMetaTypeId()] = {{}, QProtobufJsonSerializerPrivate::deserializeUInt32}; - handlers[qMetaTypeId()] - = {{}, QProtobufJsonSerializerPrivate::deserializeUInt32}; + handlers[qMetaTypeId()] = { + QProtobufJsonSerializerPrivate::serializeVarint, + QProtobufJsonSerializerPrivate::deserializeUInt32 + }; handlers[qMetaTypeId()] - = {{}, QProtobufJsonSerializerPrivate::deserializeUInt64}; - handlers[qMetaTypeId()] - = {{}, QProtobufJsonSerializerPrivate::deserializeUInt64}; + = {serializeInt64Int, QProtobufJsonSerializerPrivate::deserializeUInt64}; + handlers[qMetaTypeId()] = { + serializeInt64Int, + QProtobufJsonSerializerPrivate::deserializeUInt64 + }; handlers[qMetaTypeId()] = {{}, QProtobufJsonSerializerPrivate::deserializeBool}; handlers[QMetaType::Float] = {QProtobufJsonSerializerPrivate::serializeFloat, @@ -232,33 +233,38 @@ public: handlers[qMetaTypeId()] = {QProtobufJsonSerializerPrivate::serializeList, QProtobufJsonSerializerPrivate::deserializeList}; - handlers[qMetaTypeId()] - = {QProtobufJsonSerializerPrivate::serializeList, - QProtobufJsonSerializerPrivate::deserializeList}; + handlers[qMetaTypeId()] = { + QProtobufJsonSerializerPrivate::serializeInt64bitList, + QProtobufJsonSerializerPrivate::deserializeList + }; handlers[qMetaTypeId()] = {QProtobufJsonSerializerPrivate::serializeList, QProtobufJsonSerializerPrivate::deserializeList}; - handlers[qMetaTypeId()] - = {QProtobufJsonSerializerPrivate::serializeList, - QProtobufJsonSerializerPrivate::deserializeList}; + handlers[qMetaTypeId()] = { + QProtobufJsonSerializerPrivate::serializeInt64bitList, + QProtobufJsonSerializerPrivate::deserializeList + }; handlers[qMetaTypeId()] = {QProtobufJsonSerializerPrivate::serializeList, QProtobufJsonSerializerPrivate::deserializeList}; - handlers[qMetaTypeId()] - = {QProtobufJsonSerializerPrivate::serializeList, - QProtobufJsonSerializerPrivate::deserializeList}; + handlers[qMetaTypeId()] = { + QProtobufJsonSerializerPrivate::serializeInt64bitList, + QProtobufJsonSerializerPrivate::deserializeList + }; handlers[qMetaTypeId()] = {QProtobufJsonSerializerPrivate::serializeList, QProtobufJsonSerializerPrivate::deserializeList}; - handlers[qMetaTypeId()] - = {QProtobufJsonSerializerPrivate::serializeList, - QProtobufJsonSerializerPrivate::deserializeList}; + handlers[qMetaTypeId()] = { + QProtobufJsonSerializerPrivate::serializeInt64bitList, + QProtobufJsonSerializerPrivate::deserializeList + }; handlers[qMetaTypeId()] = {QProtobufJsonSerializerPrivate::serializeList, QProtobufJsonSerializerPrivate::deserializeList}; - handlers[qMetaTypeId()] - = {QProtobufJsonSerializerPrivate::serializeList, - QProtobufJsonSerializerPrivate::deserializeList}; + handlers[qMetaTypeId()] = { + QProtobufJsonSerializerPrivate::serializeInt64bitList, + QProtobufJsonSerializerPrivate::deserializeList + }; handlers[qMetaTypeId()] = {QProtobufJsonSerializerPrivate::serializeFloatList, QProtobufJsonSerializerPrivate::deserializeList}; @@ -275,42 +281,31 @@ public: } ~QProtobufJsonSerializerPrivate() = default; - QByteArray serializeValue(const QVariant &propertyValue, - const QProtobufPropertyOrderingInfo &fieldInfo) + void serializeProperty(const QVariant &propertyValue, + const QProtobufPropertyOrderingInfo &fieldInfo) { - QByteArray buffer; QMetaType metaType = propertyValue.metaType(); auto userType = propertyValue.userType(); - if (metaType.id() == QMetaType::UnknownType) { - return {}; - } + if (metaType.id() == QMetaType::UnknownType) + return; + auto handler = QtProtobufPrivate::findHandler(metaType); if (handler.serializer) { - handler.serializer(qPtr, propertyValue, fieldInfo, buffer); + handler.serializer(qPtr, propertyValue, fieldInfo); } else { + QJsonObject activeObject = activeValue.toObject(); auto handler = handlers.find(userType); - if (handler != handlers.end() && handler->second.serializer) { - buffer += handler->second.serializer(propertyValue); - } else { - buffer += propertyValue.toString().toUtf8(); - } + activeObject.insert(fieldInfo.getJsonName().toString(), + handler != handlers.end() && handler->second.serializer + ? handler->second.serializer(propertyValue) + : QJsonValue::fromVariant(propertyValue)); + activeValue = activeObject; } - return buffer; } - QByteArray serializeProperty(const QVariant &propertyValue, - const QProtobufPropertyOrderingInfo &fieldInfo) + void serializeObject(const QProtobufMessage *message, const QProtobufPropertyOrdering &ordering) { - return QByteArray("\"") - + QByteArrayView(fieldInfo.getJsonName()) - + QByteArray("\":") + serializeValue(propertyValue, fieldInfo); - } - - QByteArray serializeObject(const QProtobufMessage *message, - const QProtobufPropertyOrdering &ordering) - { - QByteArray result = "{"; // if a message is not initialized, just return empty { } if (message) { for (int index = 0; index < ordering.fieldCount(); ++index) { @@ -320,13 +315,9 @@ public: "fieldIndex is out of range"); QProtobufPropertyOrderingInfo fieldInfo(ordering, index); QVariant propertyValue = message->property(fieldInfo); - result.append(serializeProperty(propertyValue, fieldInfo)); - result.append(","); + serializeProperty(propertyValue, fieldInfo); } - result.chop(1); } - result.append("}"); - return result; } static QVariant deserializeInt32(const QJsonValue &value, bool &ok) @@ -442,47 +433,31 @@ public: return QVariant::fromValue(list); } - QVariant deserializeValue(const QMetaType &metaType, - QProtobufSelfcheckIterator &it, - const QJsonValue &value, - bool &ok) + QVariant deserializeValue(QVariant propertyData, bool &ok) { - QVariant result; - auto handler = QtProtobufPrivate::findHandler(metaType); + auto handler = QtProtobufPrivate::findHandler(propertyData.metaType()); if (handler.deserializer) { - handler.deserializer(qPtr, it, result); - ok = result.isValid(); + handler.deserializer(qPtr, propertyData); + ok = propertyData.isValid(); } else { - auto handler = handlers.find(metaType.id()); + int userType = propertyData.userType(); + auto handler = handlers.find(propertyData.userType()); if (handler != handlers.end() && handler->second.deserializer) { - result = handler->second.deserializer(value, ok); + propertyData = handler->second.deserializer(activeValue, ok); + activeValue = {}; } else { - QString error = QString::fromUtf8("No deserializer is registered for value %1") - .arg(QString::fromUtf8(metaType.name())); - setDeserializationError( - QAbstractProtobufSerializer::NoDeserializerError, - QCoreApplication::translate("QtProtobuf", - error.toUtf8().data())); + setDeserializationError(QAbstractProtobufSerializer::NoDeserializerError, + QCoreApplication:: + translate("QtProtobuf", + "No deserializer is registered for type %1").arg(userType)); } } - return result; + return propertyData; } - bool deserializeObject(QProtobufMessage *message, - const QProtobufPropertyOrdering &ordering, - QByteArrayView data) + bool deserializeObject(QProtobufMessage *message, const QProtobufPropertyOrdering &ordering) { - auto it = QProtobufSelfcheckIterator::fromView(data); - Q_ASSERT(it.isValid() && it.bytesLeft() > 0); - bool ok = false; - // TBD Try fromJson(QBAView) instead of current variant - QJsonDocument document - = QJsonDocument::fromJson(QByteArray(data.data(), static_cast(data.size()))); - - if (!document.isObject()) - return false; - std::map msgContainer; // map for (int index = 0; index < ordering.fieldCount(); ++index) { int fieldIndex = ordering.getFieldNumber(index); @@ -492,35 +467,33 @@ public: msgContainer.insert(std::pair(key, fieldInfo)); } - QByteArray object; + if (!activeValue.isObject()) { + return false; + } + QJsonObject activeObject = activeValue.toObject(); // Go through QJSON doc and find keys that are presented in msgContainer - QJsonObject obj = document.object(); - for (auto &key : obj.keys()) { - QJsonValue jsonValue = obj.value(key); - auto iter = msgContainer.find(key); + for (auto &key : activeObject.keys()) { + std::map::iterator iter = msgContainer + .find(key); if (iter != msgContainer.end()) { QVariant newPropertyValue = message->property(iter->second); - // Complex message case; move iterator to the deserializing array - if (jsonValue.isArray()) { - QJsonArray array = jsonValue.toArray(); - object = QJsonDocument(array).toJson(); - it = QProtobufSelfcheckIterator::fromView(object); + auto store = activeValue; + activeValue = activeObject.value(key); + while (!activeValue.isNull()) { + newPropertyValue = deserializeValue(newPropertyValue, ok); } - // Complex message case; move iterator to the deserializing object - if (jsonValue.isObject()) { - object = QJsonDocument(jsonValue.toObject()).toJson(); - it = QProtobufSelfcheckIterator::fromView(object); - } - newPropertyValue = deserializeValue(newPropertyValue.metaType(), - it, - jsonValue, - ok); + activeValue = store; + if (ok) { - message->setProperty(iter->second, std::move(newPropertyValue)); + message->setProperty(iter->second, newPropertyValue); } } } + // Once all keys are deserialized we assume that activeValue is empty, nothing left + // to deserialize + activeValue = {}; + return ok; } @@ -543,7 +516,7 @@ public: QAbstractProtobufSerializer::DeserializationError deserializationError = QAbstractProtobufSerializer::NoDeserializerError; QString deserializationErrorString; - QJsonArray activeArray; + QJsonValue activeValue; private: static SerializerRegistry handlers; @@ -580,7 +553,12 @@ QByteArray QProtobufJsonSerializer::serializeMessage(const QProtobufMessage *message, const QProtobufPropertyOrdering &ordering) const { - return d_ptr->serializeObject(message, ordering); + d_ptr->activeValue = QJsonObject(); + d_ptr->serializeObject(message, ordering); + QJsonDocument doc; + doc.setObject(d_ptr->activeValue.toObject()); + d_ptr->activeValue = QJsonObject(); + return doc.toJson(QJsonDocument::Compact); } bool QProtobufJsonSerializer::deserializeMessage(QProtobufMessage *message, @@ -588,92 +566,83 @@ bool QProtobufJsonSerializer::deserializeMessage(QProtobufMessage *message, QByteArrayView data) const { d_ptr->clearError(); - auto it = QProtobufSelfcheckIterator::fromView(data); - if (!d_ptr->deserializeObject(message, ordering, data)) + QJsonParseError err; + auto document = QJsonDocument::fromJson(data.toByteArray(), &err); + if (err.error != QJsonParseError::NoError) return false; - if (!it.isValid()) - d_ptr->setUnexpectedEndOfStreamError(); - return it.isValid(); + if (!document.isObject()) + return false; + + d_ptr->activeValue = document.object(); + + return d_ptr->deserializeObject(message, ordering); } -QByteArray -QProtobufJsonSerializer::serializeObject(const QProtobufMessage *message, - const QProtobufPropertyOrdering &ordering, - const QProtobufPropertyOrderingInfo &fieldInfo) const +void QProtobufJsonSerializer::serializeObject(const QProtobufMessage *message, + const QProtobufPropertyOrdering &ordering, + const QProtobufPropertyOrderingInfo &fieldInfo) const { Q_UNUSED(fieldInfo); - return serializeMessage(message, ordering); + auto store = d_ptr->activeValue.toObject(); + d_ptr->activeValue = QJsonObject(); + d_ptr->serializeObject(message, ordering); + store.insert(fieldInfo.getJsonName().toString(), d_ptr->activeValue); + d_ptr->activeValue = store; } -QByteArray -QProtobufJsonSerializer::serializeListObject(const QList &messageList, - const QProtobufPropertyOrdering &ordering, - const QProtobufPropertyOrderingInfo &fieldInfo) const +void QProtobufJsonSerializer::serializeListObject(const QProtobufMessage *message, + const QProtobufPropertyOrdering &ordering, + const QProtobufPropertyOrderingInfo &fieldInfo) + const { - QByteArray result("["); - for (auto message : messageList) { - result.append(serializeObject(message, ordering, fieldInfo) + ","); - } - if (messageList.size() > 0) { - result.chop(1); - } - result.append("]"); - return result; + auto fieldName = fieldInfo.getJsonName().toString(); + auto store = d_ptr->activeValue.toObject(); + QJsonArray newArrayVal = store.value(fieldName).toArray(); + d_ptr->activeValue = {}; + d_ptr->serializeObject(message, ordering); + newArrayVal.append(d_ptr->activeValue); + store.insert(fieldName, newArrayVal); + d_ptr->activeValue = store; } bool QProtobufJsonSerializer::deserializeObject(QProtobufMessage *message, - const QProtobufPropertyOrdering &ordering, - QProtobufSelfcheckIterator &it) const + const QProtobufPropertyOrdering &ordering) const { - return deserializeMessage(message, ordering, it.data()); + return d_ptr->deserializeObject(message, ordering); } -QProtobufBaseSerializer::Status -QProtobufJsonSerializer::deserializeListObject(QProtobufMessage *message, - const QProtobufPropertyOrdering &ordering, - QProtobufSelfcheckIterator &it) const +bool QProtobufJsonSerializer::deserializeListObject(QProtobufMessage *message, + const QProtobufPropertyOrdering &ordering) const { - if (d_ptr->activeArray.empty()) { - QJsonDocument doc = QJsonDocument::fromJson(QByteArray(it.data(), it.bytesLeft())); - if (doc.isArray()) - d_ptr->activeArray = doc.array(); - else - return QProtobufBaseSerializer::SerializationError; + QJsonArray array = d_ptr->activeValue.toArray(); + if (array.isEmpty()) { + d_ptr->activeValue = {}; + return false; } - // doc.array() is empty - if (d_ptr->activeArray.empty()) - return QProtobufBaseSerializer::SerializationError; - - const QJsonValue &element = d_ptr->activeArray.takeAt(0); - if (element.isObject()) { - auto newIt - = QProtobufSelfcheckIterator::fromView(QJsonDocument(element.toObject()).toJson()); - bool result = deserializeObject(message, ordering, newIt); - - if (!d_ptr->activeArray.empty()) { - return QProtobufBaseSerializer::SerializationInProgress; - } else { - return result ? QProtobufBaseSerializer::Serialized - : QProtobufBaseSerializer::SerializationError; - } + auto val = array.takeAt(0); + bool result = false; + if (val.isObject()) { + d_ptr->activeValue = val; + deserializeObject(message, ordering); + result = true; } - return QProtobufBaseSerializer::SerializationError; -} + if (!array.isEmpty()) + d_ptr->activeValue = array; + else + d_ptr->activeValue = {}; -QByteArray QProtobufJsonSerializer::serializeMapPair(const QList> &list, - const QProtobufPropertyOrderingInfo &fieldInfo - ) const -{ - Q_UNUSED(fieldInfo); - QByteArray result; - for (auto element: list) { - const QVariant &key = element.first; - qProtoWarning() << "Map pair serialization will be done soon:" << key << element.second; - } return result; } +void QProtobufJsonSerializer::serializeMapPair(const QVariant &key, const QVariant &value, + const QProtobufPropertyOrderingInfo &fieldInfo) const +{ + Q_UNUSED(fieldInfo); + QByteArray result; + qProtoWarning() << "Map pair serialization will be done soon:" << key << value; +} + QT_END_NAMESPACE diff --git a/src/protobuf/qprotobufjsonserializer.h b/src/protobuf/qprotobufjsonserializer.h index 20e576ad..d4d9dcae 100644 --- a/src/protobuf/qprotobufjsonserializer.h +++ b/src/protobuf/qprotobufjsonserializer.h @@ -10,6 +10,8 @@ #include +#include + QT_BEGIN_NAMESPACE class QProtobufJsonSerializerPrivate; @@ -24,6 +26,7 @@ public: QAbstractProtobufSerializer::DeserializationError deserializationError() const override; QString deserializationErrorString() const override; +private: QByteArray serializeMessage(const QProtobufMessage *message, const QtProtobufPrivate::QProtobufPropertyOrdering &ordering ) const override; @@ -32,74 +35,59 @@ public: const QtProtobufPrivate::QProtobufPropertyOrdering &ordering, QByteArrayView data) const override; - QByteArray serializeObject(const QProtobufMessage *message, - const QtProtobufPrivate::QProtobufPropertyOrdering &ordering, - const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo - ) const override; - bool deserializeObject(QProtobufMessage *message, - const QtProtobufPrivate::QProtobufPropertyOrdering &ordering, - QtProtobufPrivate::QProtobufSelfcheckIterator &it) const override; + void serializeObject(const QProtobufMessage *message, + const QtProtobufPrivate::QProtobufPropertyOrdering &ordering, + const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo) + const override; + bool + deserializeObject(QProtobufMessage *message, + const QtProtobufPrivate::QProtobufPropertyOrdering &ordering) const override; - QByteArray - serializeListObject(const QList &messageList, - const QtProtobufPrivate::QProtobufPropertyOrdering &ordering, - const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo - ) const override; + void serializeListObject(const QProtobufMessage *message, + const QtProtobufPrivate::QProtobufPropertyOrdering &ordering, + const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo) + const override; - QProtobufBaseSerializer::Status - deserializeListObject(QProtobufMessage *message, - const QtProtobufPrivate::QProtobufPropertyOrdering &ordering, - QtProtobufPrivate::QProtobufSelfcheckIterator &it) const override; + bool deserializeListObject(QProtobufMessage *message, + const QtProtobufPrivate::QProtobufPropertyOrdering &ordering) + const override; - QByteArray - serializeMapPair(const QList> &list, - const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo - ) const override; + void serializeMapPair(const QVariant &key, const QVariant &value, + const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo) + const override; - QProtobufBaseSerializer::Status - deserializeMapPair(QVariant &key, QVariant &value, - QtProtobufPrivate::QProtobufSelfcheckIterator &it) const override + bool deserializeMapPair(QVariant &key, QVariant &value) const override { Q_UNUSED(key); Q_UNUSED(value); - Q_UNUSED(it); - return QProtobufBaseSerializer::SerializationError; + return false; } - QByteArray + void serializeEnum(QtProtobuf::int64 value, const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo) const override { Q_UNUSED(value); Q_UNUSED(fieldInfo); - return QByteArray(); } - QByteArray - serializeEnumList(const QList &value, - const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo - ) const override + void serializeEnumList(const QList &value, + const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo) + const override { Q_UNUSED(value); Q_UNUSED(fieldInfo); - return QByteArray(); } - Q_REQUIRED_RESULT - bool deserializeEnum(QtProtobuf::int64 &value, - QtProtobufPrivate::QProtobufSelfcheckIterator &it) const override + bool deserializeEnum(QtProtobuf::int64 &value) const override { Q_UNUSED(value); - Q_UNUSED(it); return false; } - Q_REQUIRED_RESULT bool - deserializeEnumList(QList &value, - QtProtobufPrivate::QProtobufSelfcheckIterator &it) const override + bool deserializeEnumList(QList &value) const override { Q_UNUSED(value); - Q_UNUSED(it); return false; } diff --git a/src/protobuf/qprotobufselfcheckiterator.h b/src/protobuf/qprotobufselfcheckiterator_p.h similarity index 90% rename from src/protobuf/qprotobufselfcheckiterator.h rename to src/protobuf/qprotobufselfcheckiterator_p.h index 94707aac..257276a4 100644 --- a/src/protobuf/qprotobufselfcheckiterator.h +++ b/src/protobuf/qprotobufselfcheckiterator_p.h @@ -2,11 +2,22 @@ // Copyright (C) 2019 Alexey Edelev // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only -#ifndef QPROTOBUFSELFCHECKITERATOR_H -#define QPROTOBUFSELFCHECKITERATOR_H +#ifndef QPROTOBUFSELFCHECKITERATOR_P_H +#define QPROTOBUFSELFCHECKITERATOR_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 @@ -14,7 +25,6 @@ QT_BEGIN_NAMESPACE -namespace QtProtobufPrivate { class QProtobufSelfcheckIterator { public: @@ -24,6 +34,8 @@ public: using pointer = QByteArray::pointer; using reference = QByteArray::reference; + QProtobufSelfcheckIterator() = default; + static QProtobufSelfcheckIterator fromView(QByteArrayView container) { QProtobufSelfcheckIterator iter(container); @@ -104,8 +116,7 @@ public: private: explicit QProtobufSelfcheckIterator(QByteArrayView container) - : m_containerBegin(container.begin()), - m_containerEnd(container.end()), + : m_containerBegin(container.begin()), m_containerEnd(container.end()), m_it(container.begin()) { } @@ -162,8 +173,7 @@ inline QProtobufSelfcheckIterator operator-(const QProtobufSelfcheckIterator &it copy -= length; return copy; } -} // namespace QtProtobufPrivate QT_END_NAMESPACE -#endif // QPROTOBUFSELFCHECKITERATOR_H +#endif // QPROTOBUFSELFCHECKITERATOR_P_H diff --git a/src/protobuf/qprotobufserializer.cpp b/src/protobuf/qprotobufserializer.cpp index f1e2e9d4..5bb1187c 100644 --- a/src/protobuf/qprotobufserializer.cpp +++ b/src/protobuf/qprotobufserializer.cpp @@ -256,33 +256,33 @@ QProtobufSerializer::QProtobufSerializer() : d_ptr(new QProtobufSerializerPrivat */ QProtobufSerializer::~QProtobufSerializer() = default; -/*! - This is called by serialize() to serialize a registered Protobuf message - \a message with \a ordering. \a message must not be - \nullptr. - Returns a QByteArray containing the serialized message. -*/ QByteArray QProtobufSerializer::serializeMessage( const QProtobufMessage *message, const QtProtobufPrivate::QProtobufPropertyOrdering &ordering) const { - QByteArray result; + d_ptr->result = {}; + d_ptr->serializeMessage(message, ordering); + return d_ptr->result; +} + +void QProtobufSerializerPrivate::serializeMessage(const QProtobufMessage *message, + const QtProtobufPrivate::QProtobufPropertyOrdering + &ordering) +{ for (int index = 0; index < ordering.fieldCount(); ++index) { int fieldIndex = ordering.getFieldNumber(index); Q_ASSERT_X(fieldIndex < 536870912 && fieldIndex > 0, "", "fieldIndex is out of range"); QProtobufPropertyOrderingInfo fieldInfo(ordering, index); QVariant propertyValue = message->property(fieldInfo); - result.append(d_ptr->serializeProperty(propertyValue, fieldInfo)); + serializeProperty(propertyValue, fieldInfo); } - if (d_ptr->preserveUnknownFields) { + if (preserveUnknownFields) { // Restore any unknown fields we have stored away: const QProtobufMessagePrivate *messagePrivate = QProtobufMessagePrivate::get(message); for (const auto &fields : messagePrivate->unknownEntries) result += fields.join(); } - - return result; } void QProtobufSerializerPrivate::setUnexpectedEndOfStreamError() @@ -297,197 +297,131 @@ void QProtobufSerializerPrivate::clearError() deserializationErrorString.clear(); } -/*! - This is called by deserialize() to deserialize a registered Protobuf message - \a message with \a ordering, from a QByteArrayView \a data. \a message - can be assumed to not be \nullptr. - Returns \c true if deserialization was successful, otherwise \c false. -*/ bool QProtobufSerializer::deserializeMessage( QProtobufMessage *message, const QtProtobufPrivate::QProtobufPropertyOrdering &ordering, QByteArrayView data) const { d_ptr->clearError(); - auto it = QProtobufSelfcheckIterator::fromView(data); - while (it.isValid() && it != data.end()) { - if (!d_ptr->deserializeProperty(message, ordering, it)) + d_ptr->it = QProtobufSelfcheckIterator::fromView(data); + while (d_ptr->it.isValid() && d_ptr->it != data.end()) { + if (!d_ptr->deserializeProperty(message, ordering)) return false; } - if (!it.isValid()) + if (!d_ptr->it.isValid()) d_ptr->setUnexpectedEndOfStreamError(); - return it.isValid(); + return d_ptr->it.isValid(); } -/*! - Serialize an \a message with \a ordering and \a fieldInfo. - Returns a QByteArray containing the serialized message. - - You should not call this function directly. -*/ -QByteArray -QProtobufSerializer::serializeObject(const QProtobufMessage *message, - const QtProtobufPrivate::QProtobufPropertyOrdering &ordering, - const QProtobufPropertyOrderingInfo &fieldInfo) const +void QProtobufSerializer::serializeObject(const QProtobufMessage *message, + const QtProtobufPrivate::QProtobufPropertyOrdering + &ordering, + const QProtobufPropertyOrderingInfo &fieldInfo) const { - QByteArray result = QProtobufSerializerPrivate::prependLengthDelimitedSize( - serializeMessage(message, ordering)); - result.prepend(QProtobufSerializerPrivate::encodeHeader( - fieldInfo.getFieldNumber(), QtProtobuf::WireTypes::LengthDelimited)); - return result; + auto store = d_ptr->result; + d_ptr->result = {}; + d_ptr->serializeMessage(message, ordering); + store.append(QProtobufSerializerPrivate::encodeHeader(fieldInfo.getFieldNumber(), + QtProtobuf::WireTypes::LengthDelimited)); + store.append(QProtobufSerializerPrivate::serializeVarintCommon(d_ptr->result.size())); + store.append(d_ptr->result); + d_ptr->result = store; } -/*! - Deserialize an \a message with \a ordering from a QProtobufSelfcheckIterator - \a it. Returns \c true if deserialization was successful, otherwise - \c false. - - You should not call this function directly. -*/ bool QProtobufSerializer::deserializeObject(QProtobufMessage *message, - const QtProtobufPrivate::QProtobufPropertyOrdering &ordering, - QProtobufSelfcheckIterator &it) const + const QtProtobufPrivate::QProtobufPropertyOrdering + &ordering) const { - if (it.bytesLeft() == 0) { + if (d_ptr->it.bytesLeft() == 0) { d_ptr->setUnexpectedEndOfStreamError(); return false; } - std::optional array = QProtobufSerializerPrivate::deserializeLengthDelimited(it); + std::optional + array = QProtobufSerializerPrivate::deserializeLengthDelimited(d_ptr->it); if (!array) { d_ptr->setUnexpectedEndOfStreamError(); return false; } - return deserializeMessage(message, ordering, array.value()); -} - -/*! - This function is called to serialize \a messageList as a list of messages one by one - with \a ordering and \a fieldInfo. - - You should not call this function directly. -*/ -QByteArray QProtobufSerializer::serializeListObject( - const QList &messageList, - const QtProtobufPrivate::QProtobufPropertyOrdering &ordering, - const QProtobufPropertyOrderingInfo &fieldInfo) const -{ - QByteArray result; - for (const auto &message : messageList) - result.append(serializeObject(message, ordering, fieldInfo)); + auto store = d_ptr->it; + bool result = deserializeMessage(message, ordering, array.value()); + d_ptr->it = store; return result; } -/*! - This function deserializes an \a message from byte stream as part of list property, with - \a ordering from a QProtobufSelfcheckIterator \a it. - Returns \c Serialized if deserialization was successful, - otherwise \c SerializationError. - - You should not call this function directly. -*/ -QProtobufBaseSerializer::Status QProtobufSerializer::deserializeListObject(QProtobufMessage *message, - const QtProtobufPrivate::QProtobufPropertyOrdering &ordering, - QProtobufSelfcheckIterator &it) const -{ - if (deserializeObject(message, ordering, it)) - return QProtobufBaseSerializer::Serialized; - else - return QProtobufBaseSerializer::SerializationError; -} - -/*! - This function serializes \a list of pairs, each pair has a key and a value with - \a fieldInfo to a QByteArray - - You should not call this function directly. -*/ -QByteArray -QProtobufSerializer::serializeMapPair(const QList> &list, - const QProtobufPropertyOrderingInfo &fieldInfo) const -{ - QByteArray result; - for (const auto &element : list) { - const QVariant &key = element.first; - auto keyHandler = findIntegratedTypeHandler(key.metaType(), false); - Q_ASSERT_X(keyHandler, "QProtobufSerializer", "Map key is not an integrated type."); - - result.append(QProtobufSerializerPrivate::encodeHeader( - fieldInfo.getFieldNumber(), QtProtobuf::WireTypes::LengthDelimited)); - - result.append(QProtobufSerializerPrivate::prependLengthDelimitedSize( - keyHandler->serializer( - key, QProtobufSerializerPrivate::encodeHeader(1, keyHandler->wireType)) - + d_ptr->serializeProperty(element.second, fieldInfo.infoForMapValue()))); - } - return result; -} - -/*! - This function deserializes QMap pair of \a key and \a value from a - QProtobufSelfcheckIterator \a it. - Returns \c Serialized if deserialization was successful, - otherwise \c SerializationError. - - You should not call this function directly. -*/ -QProtobufBaseSerializer::Status QProtobufSerializer::deserializeMapPair(QVariant &key, QVariant &value, QProtobufSelfcheckIterator &it) const -{ - if (d_ptr->deserializeMapPair(key, value, it)) - return QProtobufBaseSerializer::Serialized; - else - return QProtobufBaseSerializer::SerializationError; -} - -/*! - This function serializes \a value as a QByteArray for enum associated with - property \a fieldInfo. - - You should not call this function directly. -*/ -QByteArray QProtobufSerializer::serializeEnum(QtProtobuf::int64 value, +void QProtobufSerializer::serializeListObject(const QProtobufMessage *message, + const QtProtobufPrivate::QProtobufPropertyOrdering + &ordering, const QProtobufPropertyOrderingInfo &fieldInfo) const +{ + serializeObject(message, ordering, fieldInfo); +} + +bool QProtobufSerializer::deserializeListObject(QProtobufMessage *message, + const QtProtobufPrivate::QProtobufPropertyOrdering + &ordering) const +{ + return deserializeObject(message, ordering); +} + +void QProtobufSerializer::serializeMapPair(const QVariant &key, const QVariant &value, + const QProtobufPropertyOrderingInfo &fieldInfo) const +{ + auto keyHandler = findIntegratedTypeHandler(key.metaType(), false); + Q_ASSERT_X(keyHandler, "QProtobufSerializer", "Map key is not an integrated type."); + auto store = d_ptr->result; + d_ptr->result = {}; + d_ptr->result + .append(keyHandler + ->serializer(key, + QProtobufSerializerPrivate::encodeHeader(1, + keyHandler->wireType))); + d_ptr->serializeProperty(value, fieldInfo.infoForMapValue()); + store.append(QProtobufSerializerPrivate::encodeHeader(fieldInfo.getFieldNumber(), + QtProtobuf::WireTypes::LengthDelimited)); + store.append(QProtobufSerializerPrivate::serializeVarintCommon(d_ptr->result.size())); + store.append(d_ptr->result); + d_ptr->result = store; +} + +bool QProtobufSerializer::deserializeMapPair(QVariant &key, QVariant &value) const +{ + return d_ptr->deserializeMapPair(key, value); +} + +void QProtobufSerializer::serializeEnum(QtProtobuf::int64 value, + const QProtobufPropertyOrderingInfo &fieldInfo) const { if (value == 0 && !isOneofOrOptionalField(fieldInfo)) - return {}; + return; QtProtobuf::WireTypes type = QtProtobuf::WireTypes::Varint; int fieldNumber = fieldInfo.getFieldNumber(); - return QProtobufSerializerPrivate::encodeHeader(fieldNumber, type) - + QProtobufSerializerPrivate::serializeBasic(value); + d_ptr->result.append(QProtobufSerializerPrivate::encodeHeader(fieldNumber, type) + + QProtobufSerializerPrivate::serializeBasic(value)); } -/*! - This function serializes a list, \a value, as a QByteArray for enum - associated with property \a fieldInfo. - - You should not call this function directly. -*/ -QByteArray -QProtobufSerializer::serializeEnumList(const QList &value, - const QProtobufPropertyOrderingInfo &fieldInfo) const +void QProtobufSerializer::serializeEnumList(const QList &value, + const QProtobufPropertyOrderingInfo &fieldInfo) const { - if (value.isEmpty()) { - return {}; - } + if (value.isEmpty()) + return; auto header = QProtobufSerializerPrivate::encodeHeader(fieldInfo.getFieldNumber(), QtProtobuf::WireTypes::LengthDelimited); if (fieldInfo.getFieldFlags() & QtProtobufPrivate::NonPacked) - return QProtobufSerializerPrivate::serializeNonPackedList(value, header); - - return header + QProtobufSerializerPrivate::serializeListType(value); + d_ptr->result + .append(QProtobufSerializerPrivate::serializeNonPackedList(value, + header)); + else + d_ptr->result + .append(header + + QProtobufSerializerPrivate::serializeListType(value)); } -/*! - This function deserializes an enum \a value from a QProtobufSelfcheckIterator \a it. - Returns \c true if deserialization was successful, otherwise \c false. - - You should not call this function directly. -*/ -bool QProtobufSerializer::deserializeEnum(QtProtobuf::int64 &value, QProtobufSelfcheckIterator &it) const +bool QProtobufSerializer::deserializeEnum(QtProtobuf::int64 &value) const { QVariant variantValue; - if (!QProtobufSerializerPrivate::deserializeBasic(it, variantValue)) { + if (!QProtobufSerializerPrivate::deserializeBasic(d_ptr->it, variantValue)) { d_ptr->setUnexpectedEndOfStreamError(); return false; } @@ -495,16 +429,10 @@ bool QProtobufSerializer::deserializeEnum(QtProtobuf::int64 &value, QProtobufSel return true; } -/*! - This function deserializes a list of enum \a value from a QProtobufSelfcheckIterator \a it. - Returns \c true if deserialization was successful, otherwise \c false. - - You should not call this function directly. -*/ -bool QProtobufSerializer::deserializeEnumList(QList &value, QProtobufSelfcheckIterator &it) const +bool QProtobufSerializer::deserializeEnumList(QList &value) const { QVariant variantValue; - if (!QProtobufSerializerPrivate::deserializeList(it, variantValue)) { + if (!QProtobufSerializerPrivate::deserializeList(d_ptr->it, variantValue)) { d_ptr->setUnexpectedEndOfStreamError(); return false; } @@ -517,6 +445,7 @@ QProtobufSerializerPrivate::QProtobufSerializerPrivate(QProtobufSerializer *q) : } /*! + \internal Encode a property field index and its type into output bytes. Header byte @@ -537,13 +466,13 @@ QByteArray QProtobufSerializerPrivate::encodeHeader(int fieldIndex, } /*! + \internal Decode a property field index and its serialization type from input bytes Iterator: that points to header with encoded field index and serialization type fieldIndex: Decoded index of a property in parent object wireType: Decoded serialization type used for the property with index - * - \return true if both decoded wireType and fieldIndex have "allowed" values and false, otherwise + Return true if both decoded wireType and fieldIndex have "allowed" values and false, otherwise */ bool QProtobufSerializerPrivate::decodeHeader(QProtobufSelfcheckIterator &it, int &fieldIndex, @@ -610,9 +539,8 @@ qsizetype QProtobufSerializerPrivate::skipSerializedFieldBytes(QProtobufSelfchec return std::distance(initialIt, QByteArray::const_iterator(it)); } -QByteArray -QProtobufSerializerPrivate::serializeProperty(const QVariant &propertyValue, - const QProtobufPropertyOrderingInfo &fieldInfo) +void QProtobufSerializerPrivate::serializeProperty(const QVariant &propertyValue, + const QProtobufPropertyOrderingInfo &fieldInfo) { QMetaType metaType = propertyValue.metaType(); @@ -621,7 +549,7 @@ QProtobufSerializerPrivate::serializeProperty(const QVariant &propertyValue, if (metaType.id() == QMetaType::UnknownType || propertyValue.isNull()) { // Empty value - return {}; + return; } auto basicHandler = findIntegratedTypeHandler( @@ -629,29 +557,26 @@ QProtobufSerializerPrivate::serializeProperty(const QVariant &propertyValue, if (basicHandler) { bool serializeUninitialized = isOneofOrOptionalField(fieldInfo); if (!basicHandler->isPresent(propertyValue) && !serializeUninitialized) { - return {}; + return; } QByteArray header = QProtobufSerializerPrivate::encodeHeader(fieldInfo.getFieldNumber(), basicHandler->wireType); - return basicHandler->serializer(propertyValue, header); + result.append(basicHandler->serializer(propertyValue, header)); + return; } auto handler = QtProtobufPrivate::findHandler(metaType); if (!handler.serializer) { qProtoWarning() << "No serializer for type" << propertyValue.typeName(); - return {}; + return; } - QByteArray result; - handler.serializer(q_ptr, propertyValue, fieldInfo, result); - - return result; + handler.serializer(q_ptr, propertyValue, fieldInfo); } -bool QProtobufSerializerPrivate::deserializeProperty( - QProtobufMessage *message, - const QtProtobufPrivate::QProtobufPropertyOrdering &ordering, - QProtobufSelfcheckIterator &it) +bool QProtobufSerializerPrivate:: + deserializeProperty(QProtobufMessage *message, + const QtProtobufPrivate::QProtobufPropertyOrdering &ordering) { Q_ASSERT(it.isValid() && it.bytesLeft() > 0); //Each iteration we expect iterator is setup to beginning of next chunk @@ -739,13 +664,13 @@ bool QProtobufSerializerPrivate::deserializeProperty( QCoreApplication::translate("QtProtobuf", error.toUtf8().data())); return false; } - handler.deserializer(q_ptr, it, newPropertyValue); + handler.deserializer(q_ptr, newPropertyValue); } return message->setProperty(fieldInfo, std::move(newPropertyValue)); } -bool QProtobufSerializerPrivate::deserializeMapPair(QVariant &key, QVariant &value, QProtobufSelfcheckIterator &it) +bool QProtobufSerializerPrivate::deserializeMapPair(QVariant &key, QVariant &value) { int mapIndex = 0; QtProtobuf::WireTypes type = QtProtobuf::WireTypes::Unknown; @@ -797,7 +722,7 @@ bool QProtobufSerializerPrivate::deserializeMapPair(QVariant &key, QVariant &val .arg(QLatin1String(value.typeName()))); return false; } - handler.deserializer(q_ptr, it, value); + handler.deserializer(q_ptr, value); } } } diff --git a/src/protobuf/qprotobufserializer.h b/src/protobuf/qprotobufserializer.h index 703255e3..83e26d4d 100644 --- a/src/protobuf/qprotobufserializer.h +++ b/src/protobuf/qprotobufserializer.h @@ -14,10 +14,6 @@ QT_BEGIN_NAMESPACE -namespace QtProtobufPrivate { -class QProtobufSelfcheckIterator; -} // namespace QtProtobufPrivate - class QProtobufMessage; class QProtobufSerializerPrivate; class Q_PROTOBUF_EXPORT QProtobufSerializer : public QProtobufBaseSerializer @@ -30,6 +26,8 @@ public: QProtobufSerializer::DeserializationError deserializationError() const override; QString deserializationErrorString() const override; + void shouldPreserveUnknownFields(bool preserveUnknownFields); +private: QByteArray serializeMessage(const QProtobufMessage *message, const QtProtobufPrivate::QProtobufPropertyOrdering &ordering @@ -38,50 +36,36 @@ public: const QtProtobufPrivate::QProtobufPropertyOrdering &ordering, QByteArrayView data) const override; - QByteArray - serializeObject(const QProtobufMessage *message, - const QtProtobufPrivate::QProtobufPropertyOrdering &ordering, - const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo - ) const override; - bool deserializeObject(QProtobufMessage *message, - const QtProtobufPrivate::QProtobufPropertyOrdering &ordering, - QtProtobufPrivate::QProtobufSelfcheckIterator &it) const override; + void serializeObject(const QProtobufMessage *message, + const QtProtobufPrivate::QProtobufPropertyOrdering &ordering, + const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo) + const override; + bool + deserializeObject(QProtobufMessage *message, + const QtProtobufPrivate::QProtobufPropertyOrdering &ordering) const override; - QByteArray - serializeListObject(const QList &messageList, - const QtProtobufPrivate::QProtobufPropertyOrdering &ordering, - const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo - ) const override; - QProtobufBaseSerializer::Status deserializeListObject(QProtobufMessage *message, - const QtProtobufPrivate::QProtobufPropertyOrdering &ordering, - QtProtobufPrivate::QProtobufSelfcheckIterator &it - ) const override; + void serializeListObject(const QProtobufMessage *message, + const QtProtobufPrivate::QProtobufPropertyOrdering &ordering, + const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo) + const override; + bool deserializeListObject(QProtobufMessage *message, + const QtProtobufPrivate::QProtobufPropertyOrdering &ordering) + const override; - QByteArray - serializeMapPair(const QList > &list, - const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo - ) const override; - QProtobufBaseSerializer::Status deserializeMapPair(QVariant &key, QVariant &value, - QtProtobufPrivate::QProtobufSelfcheckIterator &it - ) const override; + void serializeMapPair(const QVariant &key, const QVariant &value, + const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo) + const override; + bool deserializeMapPair(QVariant &key, QVariant &value) const override; - QByteArray + void serializeEnum(QtProtobuf::int64 value, - const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo - ) const override; - QByteArray - serializeEnumList(const QList &value, - const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo - ) const override; + const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo) const override; + void serializeEnumList(const QList &value, + const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo) + const override; - Q_REQUIRED_RESULT - bool deserializeEnum(QtProtobuf::int64 &value, - QtProtobufPrivate::QProtobufSelfcheckIterator &it) const override; - Q_REQUIRED_RESULT bool - deserializeEnumList(QList &value, - QtProtobufPrivate::QProtobufSelfcheckIterator &it) const override; - - void shouldPreserveUnknownFields(bool preserveUnknownFields); + bool deserializeEnum(QtProtobuf::int64 &value) const override; + bool deserializeEnumList(QList &value) const override; private: std::unique_ptr d_ptr; }; diff --git a/src/protobuf/qprotobufserializer_p.h b/src/protobuf/qprotobufserializer_p.h index 78329a34..5aaa2692 100644 --- a/src/protobuf/qprotobufserializer_p.h +++ b/src/protobuf/qprotobufserializer_p.h @@ -23,19 +23,17 @@ #include #include -#include -#include -#include +#include #include #include +#include +#include #include #include QT_BEGIN_NAMESPACE -using QtProtobufPrivate::QProtobufSelfcheckIterator; - class QProtobufSerializerPrivate { // The below type trait structures help to determine the required encoding method for protobuf @@ -500,12 +498,14 @@ public: static void skipVarint(QProtobufSelfcheckIterator &it); static void skipLengthDelimited(QProtobufSelfcheckIterator &it); - QByteArray serializeProperty(const QVariant &propertyValue, - const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo); + void serializeMessage(const QProtobufMessage *message, + const QtProtobufPrivate::QProtobufPropertyOrdering &ordering); + + void serializeProperty(const QVariant &propertyValue, + const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo); Q_REQUIRED_RESULT bool deserializeProperty(QProtobufMessage *message, - const QtProtobufPrivate::QProtobufPropertyOrdering &ordering, - QProtobufSelfcheckIterator &it); + const QtProtobufPrivate::QProtobufPropertyOrdering &ordering); void setDeserializationError(QAbstractProtobufSerializer::DeserializationError error, const QString &errorString); @@ -513,12 +513,15 @@ public: void setUnexpectedEndOfStreamError(); Q_REQUIRED_RESULT - bool deserializeMapPair(QVariant &key, QVariant &value, QProtobufSelfcheckIterator &it); + bool deserializeMapPair(QVariant &key, QVariant &value); QAbstractProtobufSerializer::DeserializationError deserializationError = QAbstractProtobufSerializer::NoDeserializerError; QString deserializationErrorString; + QProtobufSelfcheckIterator it; + QByteArray result; + bool preserveUnknownFields = true; private: Q_DISABLE_COPY_MOVE(QProtobufSerializerPrivate) diff --git a/src/protobufqttypes/protobufqtcoretypes/qtprotobufqttypescommon_p.h b/src/protobufqttypes/protobufqtcoretypes/qtprotobufqttypescommon_p.h index 3dabbd34..85f41ce5 100644 --- a/src/protobufqttypes/protobufqtcoretypes/qtprotobufqttypescommon_p.h +++ b/src/protobufqttypes/protobufqtcoretypes/qtprotobufqttypescommon_p.h @@ -39,42 +39,39 @@ constexpr inline bool is_optional_v> = true; template void registerQtTypeHandler() { - registerHandler( - QMetaType::fromType(), - { [](const QProtobufBaseSerializer *serializer, const QVariant &value, - const QProtobufPropertyOrderingInfo &info, QByteArray &buffer) { - auto do_convert = [](const QType &qtype) { - auto res = convert(qtype); - if constexpr (is_optional_v) { - return res; - } else { - return std::optional(std::move(res)); - } - }; + registerHandler(QMetaType::fromType(), + { [](const QProtobufBaseSerializer *serializer, const QVariant &value, + const QProtobufPropertyOrderingInfo &info) { + auto do_convert = [](const QType &qtype) { + auto res = convert(qtype); + if constexpr (is_optional_v) { + return res; + } else { + return std::optional(std::move(res)); + } + }; - std::optional object = do_convert(value.value()); - if (object) { - buffer.append(serializer->serializeObject(&(object.value()), - PType::propertyOrdering, info)); - } else { - warnTypeConversionError(); - } - }, - [](const QProtobufBaseSerializer *serializer, QProtobufSelfcheckIterator &it, - QVariant &value) { - PType object; - serializer->deserializeObject(&object, PType::propertyOrdering, it); - auto res = convert(object); - if constexpr (is_optional_v) { - if (!res) - warnTypeConversionError(); - else - value = QVariant::fromValue(*res); - } else { - value = QVariant::fromValue(res); - } - } - }); + std::optional object = do_convert(value.value()); + if (object) { + serializer->serializeObject(&(object.value()), PType::propertyOrdering, + info); + } else { + warnTypeConversionError(); + } + }, + [](const QProtobufBaseSerializer *serializer, QVariant &value) { + PType object; + serializer->deserializeObject(&object, PType::propertyOrdering); + auto res = convert(object); + if constexpr (is_optional_v) { + if (!res) + warnTypeConversionError(); + else + value = QVariant::fromValue(*res); + } else { + value = QVariant::fromValue(res); + } + } }); } } // namespace QtProtobufPrivate diff --git a/src/wellknown/qprotobufanysupport.cpp b/src/wellknown/qprotobufanysupport.cpp index deb499bb..566c8fc2 100644 --- a/src/wellknown/qprotobufanysupport.cpp +++ b/src/wellknown/qprotobufanysupport.cpp @@ -3,7 +3,7 @@ #include -#include +#include #include #include "qprotobufanysupport.h" @@ -25,7 +25,7 @@ public: }; static void serializerProxy(const QProtobufBaseSerializer *serializer, const QVariant &object, - const QProtobufPropertyOrderingInfo &fieldInfo, QByteArray &output) + const QProtobufPropertyOrderingInfo &fieldInfo) { if (object.isNull()) return; @@ -37,41 +37,28 @@ static void serializerProxy(const QProtobufBaseSerializer *serializer, const QVa google::protobuf::Any realAny; realAny.setValue(any.value()); realAny.setTypeUrl(any.typeUrl()); - output.append(serializer->serializeObject(&realAny, google::protobuf::Any::propertyOrdering, - fieldInfo)); + serializer->serializeObject(&realAny, google::protobuf::Any::propertyOrdering, fieldInfo); } -static void listSerializerProxy(const QProtobufBaseSerializer *serializer, - const QVariant &object, - const QProtobufPropertyOrderingInfo &fieldInfo, - QByteArray &output) +static void listSerializerProxy(const QProtobufBaseSerializer *serializer, const QVariant &object, + const QProtobufPropertyOrderingInfo &fieldInfo) { - const QList anyList = object.value>(); - QList msgList; - msgList.reserve(anyList.size()); - QList msgAny; - msgAny.reserve(anyList.size()); + const auto anyList = object.value>(); for (const Any &any : anyList) { google::protobuf::Any realAny; realAny.setValue(any.value()); realAny.setTypeUrl(any.typeUrl()); - msgAny.append(realAny); + serializer->serializeListObject(&realAny, google::protobuf::Any::propertyOrdering, + fieldInfo); } - for (const google::protobuf::Any &any : msgAny) { - msgList.append(&any); - } - output.append(serializer->serializeListObject(msgList, - google::protobuf::Any::propertyOrdering, - fieldInfo)); } -static void listDeserializerProxy(const QProtobufBaseSerializer *deserializer, - QProtobufSelfcheckIterator &it, QVariant &object) +static void listDeserializerProxy(const QProtobufBaseSerializer *deserializer, QVariant &object) { auto anyList = object.value>(); const auto &ordering = google::protobuf::Any::propertyOrdering; google::protobuf::Any realAny; - if (deserializer->deserializeObject(&realAny, ordering, it)) { + if (deserializer->deserializeObject(&realAny, ordering)) { Any any; any.setTypeUrl(realAny.typeUrl()); any.setValue(realAny.value()); @@ -82,11 +69,10 @@ static void listDeserializerProxy(const QProtobufBaseSerializer *deserializer, object.setValue(std::move(anyList)); } -static void deserializerProxy(const QProtobufBaseSerializer *deserializer, - QProtobufSelfcheckIterator &it, QVariant &object) +static void deserializerProxy(const QProtobufBaseSerializer *deserializer, QVariant &object) { google::protobuf::Any realAny; - if (deserializer->deserializeObject(&realAny, google::protobuf::Any::propertyOrdering, it)) { + if (deserializer->deserializeObject(&realAny, google::protobuf::Any::propertyOrdering)) { Any any; any.setTypeUrl(realAny.typeUrl()); any.setValue(realAny.value()); @@ -210,10 +196,10 @@ void Any::setValue(const QByteArray &value) } /*! - \fn template std::optional Any::as() const + \fn template std::optional Any::as(QAbstractProtobufSerializer *serializer) const This function compares the message name of T with the value of typeUrl() - before deserializing the data. + before deserializing the data using \a serializer. If the verification or deserialization fails it will return \c{std::nullopt}. @@ -222,21 +208,21 @@ void Any::setValue(const QByteArray &value) \c{Q_PROTOBUF_OBJECT} macro or (for a nested Any message) be Any itself. */ -bool Any::asImpl(QProtobufMessage *message, +bool Any::asImpl(QAbstractProtobufSerializer *serializer, QProtobufMessage *message, QtProtobufPrivate::QProtobufPropertyOrdering ordering) const { - QProtobufSerializer serializer; + Q_ASSERT_X(serializer != nullptr, "Any::asImpl", "serializer is null"); QString tUrl = typeUrl(); qsizetype lastSegmentIndex = tUrl.lastIndexOf(u'/') + 1; if (QStringView(tUrl).mid(lastSegmentIndex).compare(ordering.getMessageFullName()) != 0) return false; - return serializer.deserializeMessage(message, ordering, value()); + return serializer->deserializeMessage(message, ordering, value()); } -std::optional Any::asAnyImpl() const +std::optional Any::asAnyImpl(QAbstractProtobufSerializer *serializer) const { google::protobuf::Any realAny; - if (!asImpl(&realAny, google::protobuf::Any::propertyOrdering)) + if (!asImpl(serializer, &realAny, google::protobuf::Any::propertyOrdering)) return std::nullopt; Any any; any.setTypeUrl(realAny.typeUrl()); @@ -245,37 +231,39 @@ std::optional Any::asAnyImpl() const } /*! - \fn template static Any Any::fromMessage(const T &message, QAnyStringView typeUrlPrefix) + \fn template static Any Any::fromMessage(QAbstractProtobufSerializer *serializer, + const T &message, QAnyStringView typeUrlPrefix) This function serializes the given \a message as the value of the returned Any instance. This instance's typeUrl() is constructed from a prefix, a forward slash and the message name obtained from - \c{T::propertyOrdering.getMessageFullName()}. If \a typeUrlPrefix is - supplied, it is used as prefix, otherwise \c{"type.googleapis.com"} is used. + \c{T::propertyOrdering.getMessageFullName()} using \a serializer. If \a + typeUrlPrefix is supplied, it is used as prefix, otherwise + \c{"type.googleapis.com"} is used. \note T must be a class derived from QProtobufMessage with the \c{Q_PROTOBUF_OBJECT} macro or (for a nested Any message) be Any itself. */ -Any Any::fromMessageImpl(const QProtobufMessage *message, +Any Any::fromMessageImpl(QAbstractProtobufSerializer *serializer, const QProtobufMessage *message, QtProtobufPrivate::QProtobufPropertyOrdering ordering, QAnyStringView typeUrlPrefix) { - QProtobufSerializer serializer; Any any; - any.setValue(serializer.serializeMessage(message, ordering)); + any.setValue(serializer->serializeMessage(message, ordering)); any.setTypeUrl(typeUrlPrefix.toString() + u'/' + ordering.getMessageFullName().toString()); return { any }; } // Used to handle nested Any messages. -Any Any::fromAnyMessageImpl(const Any *message, QAnyStringView typeUrlPrefix) +Any Any::fromAnyMessageImpl(QAbstractProtobufSerializer *serializer, + const Any *message, QAnyStringView typeUrlPrefix) { using RealAny = google::protobuf::Any; RealAny realAny; realAny.setTypeUrl(message->typeUrl()); realAny.setValue(message->value()); - return fromMessageImpl(&realAny, RealAny::propertyOrdering, typeUrlPrefix); + return fromMessageImpl(serializer, &realAny, RealAny::propertyOrdering, typeUrlPrefix); } QAnyStringView Any::defaultUrlPrefix() diff --git a/src/wellknown/qprotobufanysupport.h b/src/wellknown/qprotobufanysupport.h index fcb52476..c77b982c 100644 --- a/src/wellknown/qprotobufanysupport.h +++ b/src/wellknown/qprotobufanysupport.h @@ -17,6 +17,8 @@ QT_BEGIN_NAMESPACE +class QAbstractProtobufSerializer; + namespace QtProtobuf { class AnyPrivate; class Q_PROTOBUFWELLKNOWNTYPES_EXPORT Any : public QProtobufMessage @@ -48,42 +50,45 @@ public: void setValue(const QByteArray &value); template - std::optional as() const + std::optional as(QAbstractProtobufSerializer *serializer) const { if constexpr (std::is_same_v) { - return asAnyImpl(); + return asAnyImpl(serializer); } else { static_assert(QtProtobufPrivate::HasProtobufPropertyOrdering, "T must have the Q_PROTOBUF_OBJECT macro"); T obj; - if (asImpl(&obj, T::propertyOrdering)) + if (asImpl(serializer, &obj, T::propertyOrdering)) return { std::move(obj) }; } return std::nullopt; } template - static Any fromMessage(const T &message, QAnyStringView typeUrlPrefix = defaultUrlPrefix()) + static Any fromMessage(QAbstractProtobufSerializer *serializer, const T &message, + QAnyStringView typeUrlPrefix = defaultUrlPrefix()) { if constexpr (std::is_same_v) - return fromAnyMessageImpl(&message, typeUrlPrefix); + return fromAnyMessageImpl(serializer, &message, typeUrlPrefix); static_assert(QtProtobufPrivate::HasProtobufPropertyOrdering, "T must have the Q_PROTOBUF_OBJECT macro"); - return fromMessageImpl(&message, T::propertyOrdering, typeUrlPrefix); + return fromMessageImpl(serializer, &message, T::propertyOrdering, typeUrlPrefix); } private: AnyPrivate *d_ptr; Q_DECLARE_PRIVATE(Any) - bool asImpl(QProtobufMessage *message, + bool asImpl(QAbstractProtobufSerializer *serializer, QProtobufMessage *message, QtProtobufPrivate::QProtobufPropertyOrdering ordering) const; - std::optional asAnyImpl() const; - static Any fromMessageImpl(const QProtobufMessage *message, + std::optional asAnyImpl(QAbstractProtobufSerializer *serializer) const; + static Any fromMessageImpl(QAbstractProtobufSerializer *serializer, + const QProtobufMessage *message, QtProtobufPrivate::QProtobufPropertyOrdering ordering, QAnyStringView typeUrlPrefix); - static Any fromAnyMessageImpl(const Any *message, QAnyStringView typeUrlPrefix); + static Any fromAnyMessageImpl(QAbstractProtobufSerializer *serializer, + const Any *message, QAnyStringView typeUrlPrefix); static QAnyStringView defaultUrlPrefix(); diff --git a/tests/auto/protobuf/jsontypes/tst_protobuf_deserialization_json_repeatedtypes.cpp b/tests/auto/protobuf/jsontypes/tst_protobuf_deserialization_json_repeatedtypes.cpp index 97cbc9a8..36b948d2 100644 --- a/tests/auto/protobuf/jsontypes/tst_protobuf_deserialization_json_repeatedtypes.cpp +++ b/tests/auto/protobuf/jsontypes/tst_protobuf_deserialization_json_repeatedtypes.cpp @@ -4,9 +4,9 @@ //#include "basicmessages.qpb.h" #include "repeatedmessages.qpb.h" -#include -#include +#include #include +#include using namespace Qt::Literals::StringLiterals; @@ -215,10 +215,6 @@ void QtProtobufRepeatedTypesJsonDeserializationTest::RepeatedComplexMessageTest( "{\"testFieldString\":\"\"}}]}"_ba); QCOMPARE(test.testRepeatedComplex().count(), 3); - for (auto element: test.testRepeatedComplex()) { - qWarning() << "testFieldInt = " << element.testFieldInt() - << "testFieldString = " << element.testComplexField().testFieldString(); - } QCOMPARE(test.testRepeatedComplex().at(0).testFieldInt(), 21); QCOMPARE(test.testRepeatedComplex().at(0).testComplexField().testFieldString(), QString("12345")); QCOMPARE(test.testRepeatedComplex().at(1).testFieldInt(), 22); diff --git a/tests/auto/protobuf/jsontypes/tst_protobuf_serialization_json_basictypes.cpp b/tests/auto/protobuf/jsontypes/tst_protobuf_serialization_json_basictypes.cpp index 68dcb2b9..21f1fece 100644 --- a/tests/auto/protobuf/jsontypes/tst_protobuf_serialization_json_basictypes.cpp +++ b/tests/auto/protobuf/jsontypes/tst_protobuf_serialization_json_basictypes.cpp @@ -66,23 +66,20 @@ using namespace qtprotobufnamespace::tests; void QtProtobufTypesJsonSerializationTest::BoolMessageSerializeTest_data() { QTest::addColumn("value"); - QTest::addColumn("expectedSize"); QTest::addColumn("expectedData"); - QTest::newRow("True") << true << qsizetype(22) << "{\"testFieldBool\":true}"_ba; - QTest::newRow("False") << false << qsizetype(23) << "{\"testFieldBool\":false}"_ba; + QTest::newRow("True") << true << "{\"testFieldBool\":true}"_ba; + QTest::newRow("False") << false << "{\"testFieldBool\":false}"_ba; } void QtProtobufTypesJsonSerializationTest::BoolMessageSerializeTest() { QFETCH(const bool, value); - QFETCH(const qsizetype, expectedSize); QFETCH(const QByteArray, expectedData); SimpleBoolMessage test; test.setTestFieldBool(value); QByteArray result = test.serialize(m_serializer.get()); - QCOMPARE(result.size(), expectedSize); QCOMPARE(result, expectedData); QVERIFY(!QJsonDocument::fromJson(result).isNull()); } @@ -90,23 +87,20 @@ void QtProtobufTypesJsonSerializationTest::BoolMessageSerializeTest() void QtProtobufTypesJsonSerializationTest::IntMessageSerializeTest_data() { QTest::addColumn("value"); - QTest::addColumn("expectedSize"); QTest::addColumn("expectedData"); - QTest::newRow("555") << 555 << qsizetype(20) << "{\"testFieldInt\":555}"_ba; - QTest::newRow("0") << 0 << qsizetype(18) << "{\"testFieldInt\":0}"_ba; + QTest::newRow("555") << 555 << "{\"testFieldInt\":555}"_ba; + QTest::newRow("0") << 0 << "{\"testFieldInt\":0}"_ba; } void QtProtobufTypesJsonSerializationTest::IntMessageSerializeTest() { QFETCH(const int32_t, value); - QFETCH(const qsizetype, expectedSize); QFETCH(const QByteArray, expectedData); SimpleIntMessage test; test.setTestFieldInt(value); QByteArray result = test.serialize(m_serializer.get()); - QCOMPARE(result.size(), expectedSize); QCOMPARE(result, expectedData); QVERIFY(!QJsonDocument::fromJson(result).isNull()); } @@ -114,24 +108,21 @@ void QtProtobufTypesJsonSerializationTest::IntMessageSerializeTest() void QtProtobufTypesJsonSerializationTest::UIntMessageSerializeTest_data() { QTest::addColumn("value"); - QTest::addColumn("expectedSize"); QTest::addColumn("expectedData"); - QTest::newRow("15") << (uint32_t)15 << qsizetype(19) << "{\"testFieldInt\":15}"_ba; - QTest::newRow("300") << (uint32_t)300 << qsizetype(20) << "{\"testFieldInt\":300}"_ba; - QTest::newRow("65545") << (uint32_t)65545 << qsizetype(22) << "{\"testFieldInt\":65545}"_ba; + QTest::newRow("15") << (uint32_t)15 << "{\"testFieldInt\":15}"_ba; + QTest::newRow("300") << (uint32_t)300 << "{\"testFieldInt\":300}"_ba; + QTest::newRow("65545") << (uint32_t)65545 << "{\"testFieldInt\":65545}"_ba; } void QtProtobufTypesJsonSerializationTest::UIntMessageSerializeTest() { QFETCH(const uint32_t, value); - QFETCH(const qsizetype, expectedSize); QFETCH(const QByteArray, expectedData); SimpleUIntMessage test; test.setTestFieldInt(value); QByteArray result = test.serialize(m_serializer.get()); - QCOMPARE(result.size(), expectedSize); QCOMPARE(result, expectedData); QVERIFY(!QJsonDocument::fromJson(result).isNull()); } @@ -139,28 +130,25 @@ void QtProtobufTypesJsonSerializationTest::UIntMessageSerializeTest() void QtProtobufTypesJsonSerializationTest::SIntMessageSerializeTest_data() { QTest::addColumn("value"); - QTest::addColumn("expectedSize"); QTest::addColumn("expectedData"); - QTest::newRow("15") << (int32_t)15 << qsizetype(19) << "{\"testFieldInt\":15}"_ba; - QTest::newRow("300") << (int32_t)300 << qsizetype(20) << "{\"testFieldInt\":300}"_ba; - QTest::newRow("65545") << (int32_t)65545 << qsizetype(22) << "{\"testFieldInt\":65545}"_ba; + QTest::newRow("15") << (int32_t)15 << "{\"testFieldInt\":15}"_ba; + QTest::newRow("300") << (int32_t)300 << "{\"testFieldInt\":300}"_ba; + QTest::newRow("65545") << (int32_t)65545 << "{\"testFieldInt\":65545}"_ba; - QTest::newRow("-1") << (int32_t)-1 << qsizetype(19) << "{\"testFieldInt\":-1}"_ba; - QTest::newRow("-462") << (int32_t)-462 << qsizetype(21) << "{\"testFieldInt\":-462}"_ba; - QTest::newRow("-63585") << (int32_t)-63585 << qsizetype(23) << "{\"testFieldInt\":-63585}"_ba; + QTest::newRow("-1") << (int32_t)-1 << "{\"testFieldInt\":-1}"_ba; + QTest::newRow("-462") << (int32_t)-462 << "{\"testFieldInt\":-462}"_ba; + QTest::newRow("-63585") << (int32_t)-63585 << "{\"testFieldInt\":-63585}"_ba; } void QtProtobufTypesJsonSerializationTest::SIntMessageSerializeTest() { QFETCH(const int32_t, value); - QFETCH(const qsizetype, expectedSize); QFETCH(const QByteArray, expectedData); SimpleSIntMessage test; test.setTestFieldInt(value); QByteArray result = test.serialize(m_serializer.get()); - QCOMPARE(result.size(), expectedSize); QCOMPARE(result, expectedData); QVERIFY(!QJsonDocument::fromJson(result).isNull()); } @@ -168,28 +156,25 @@ void QtProtobufTypesJsonSerializationTest::SIntMessageSerializeTest() void QtProtobufTypesJsonSerializationTest::Int64MessageSerializeTest_data() { QTest::addColumn("value"); - QTest::addColumn("expectedSize"); QTest::addColumn("expectedData"); - QTest::newRow("15") << (int64_t)15 << qsizetype(19) << "{\"testFieldInt\":15}"_ba; - QTest::newRow("300") << (int64_t)300 << qsizetype(20) << "{\"testFieldInt\":300}"_ba; - QTest::newRow("65545") << (int64_t)65545 << qsizetype(22) << "{\"testFieldInt\":65545}"_ba; + QTest::newRow("15") << (int64_t)15 << "{\"testFieldInt\":\"15\"}"_ba; + QTest::newRow("300") << (int64_t)300 << "{\"testFieldInt\":\"300\"}"_ba; + QTest::newRow("65545") << (int64_t)65545 << "{\"testFieldInt\":\"65545\"}"_ba; - QTest::newRow("-1") << (int64_t)-1 << qsizetype(19) << "{\"testFieldInt\":-1}"_ba; - QTest::newRow("-462") << (int64_t)-462 << qsizetype(21) << "{\"testFieldInt\":-462}"_ba; - QTest::newRow("-63585") << (int64_t)-63585 << qsizetype(23) << "{\"testFieldInt\":-63585}"_ba; + QTest::newRow("-1") << (int64_t)-1 << "{\"testFieldInt\":\"-1\"}"_ba; + QTest::newRow("-462") << (int64_t)-462 << "{\"testFieldInt\":\"-462\"}"_ba; + QTest::newRow("-63585") << (int64_t)-63585 << "{\"testFieldInt\":\"-63585\"}"_ba; } void QtProtobufTypesJsonSerializationTest::Int64MessageSerializeTest() { QFETCH(const int64_t, value); - QFETCH(const qsizetype, expectedSize); QFETCH(const QByteArray, expectedData); SimpleInt64Message test; test.setTestFieldInt(value); QByteArray result = test.serialize(m_serializer.get()); - QCOMPARE(result.size(), expectedSize); QCOMPARE(result, expectedData); QVERIFY(!QJsonDocument::fromJson(result).isNull()); } @@ -197,24 +182,21 @@ void QtProtobufTypesJsonSerializationTest::Int64MessageSerializeTest() void QtProtobufTypesJsonSerializationTest::UInt64MessageSerializeTest_data() { QTest::addColumn("value"); - QTest::addColumn("expectedSize"); QTest::addColumn("expectedData"); - QTest::newRow("15") << (uint64_t)15 << qsizetype(19) << "{\"testFieldInt\":15}"_ba; - QTest::newRow("300") << (uint64_t)300 << qsizetype(20) << "{\"testFieldInt\":300}"_ba; - QTest::newRow("65545") << (uint64_t)65545 << qsizetype(22) << "{\"testFieldInt\":65545}"_ba; + QTest::newRow("15") << (uint64_t)15 << "{\"testFieldInt\":\"15\"}"_ba; + QTest::newRow("300") << (uint64_t)300 << "{\"testFieldInt\":\"300\"}"_ba; + QTest::newRow("65545") << (uint64_t)65545 << "{\"testFieldInt\":\"65545\"}"_ba; } void QtProtobufTypesJsonSerializationTest::UInt64MessageSerializeTest() { QFETCH(const QtProtobuf::uint64, value); - QFETCH(const qsizetype, expectedSize); QFETCH(const QByteArray, expectedData); SimpleUInt64Message test; test.setTestFieldInt(value); QByteArray result = test.serialize(m_serializer.get()); - QCOMPARE(result.size(), expectedSize); QCOMPARE(result, expectedData); QVERIFY(!QJsonDocument::fromJson(result).isNull()); } @@ -222,28 +204,25 @@ void QtProtobufTypesJsonSerializationTest::UInt64MessageSerializeTest() void QtProtobufTypesJsonSerializationTest::SInt64MessageSerializeTest_data() { QTest::addColumn("value"); - QTest::addColumn("expectedSize"); QTest::addColumn("expectedData"); - QTest::newRow("15") << (int64_t)15 << qsizetype(19) << "{\"testFieldInt\":15}"_ba; - QTest::newRow("300") << (int64_t)300 << qsizetype(20) << "{\"testFieldInt\":300}"_ba; - QTest::newRow("65545") << (int64_t)65545 << qsizetype(22) << "{\"testFieldInt\":65545}"_ba; + QTest::newRow("15") << (int64_t)15 << "{\"testFieldInt\":\"15\"}"_ba; + QTest::newRow("300") << (int64_t)300 << "{\"testFieldInt\":\"300\"}"_ba; + QTest::newRow("65545") << (int64_t)65545 << "{\"testFieldInt\":\"65545\"}"_ba; - QTest::newRow("-1") << (int64_t)-1 << qsizetype(19) << "{\"testFieldInt\":-1}"_ba; - QTest::newRow("-462") << (int64_t)-462 << qsizetype(21) << "{\"testFieldInt\":-462}"_ba; - QTest::newRow("-63585") << (int64_t)-63585 << qsizetype(23) << "{\"testFieldInt\":-63585}"_ba; + QTest::newRow("-1") << (int64_t)-1 << "{\"testFieldInt\":\"-1\"}"_ba; + QTest::newRow("-462") << (int64_t)-462 << "{\"testFieldInt\":\"-462\"}"_ba; + QTest::newRow("-63585") << (int64_t)-63585 << "{\"testFieldInt\":\"-63585\"}"_ba; } void QtProtobufTypesJsonSerializationTest::SInt64MessageSerializeTest() { QFETCH(const int64_t, value); - QFETCH(const qsizetype, expectedSize); QFETCH(const QByteArray, expectedData); SimpleSInt64Message test; test.setTestFieldInt(value); QByteArray result = test.serialize(m_serializer.get()); - QCOMPARE(result.size(), expectedSize); QCOMPARE(result, expectedData); QVERIFY(!QJsonDocument::fromJson(result).isNull()); } @@ -251,25 +230,21 @@ void QtProtobufTypesJsonSerializationTest::SInt64MessageSerializeTest() void QtProtobufTypesJsonSerializationTest::FixedInt32MessageSerializeTest_data() { QTest::addColumn("value"); - QTest::addColumn("expectedSize"); QTest::addColumn("expectedData"); - QTest::newRow("15") << (uint32_t)15 << qsizetype(26) << "{\"testFieldFixedInt32\":15}"_ba; - QTest::newRow("300") << (uint32_t)300 << qsizetype(27) << "{\"testFieldFixedInt32\":300}"_ba; - QTest::newRow("65545") - << (uint32_t)65545 << qsizetype(29) << "{\"testFieldFixedInt32\":65545}"_ba; + QTest::newRow("15") << (uint32_t)15 << "{\"testFieldFixedInt32\":15}"_ba; + QTest::newRow("300") << (uint32_t)300 << "{\"testFieldFixedInt32\":300}"_ba; + QTest::newRow("65545") << (uint32_t)65545 << "{\"testFieldFixedInt32\":65545}"_ba; } void QtProtobufTypesJsonSerializationTest::FixedInt32MessageSerializeTest() { QFETCH(const uint32_t, value); - QFETCH(const qsizetype, expectedSize); QFETCH(const QByteArray, expectedData); SimpleFixedInt32Message test; test.setTestFieldFixedInt32(value); QByteArray result = test.serialize(m_serializer.get()); - QCOMPARE(result.size(), expectedSize); QCOMPARE(result, expectedData); QVERIFY(!QJsonDocument::fromJson(result).isNull()); } @@ -277,25 +252,21 @@ void QtProtobufTypesJsonSerializationTest::FixedInt32MessageSerializeTest() void QtProtobufTypesJsonSerializationTest::FixedInt64MessageSerializeTest_data() { QTest::addColumn("value"); - QTest::addColumn("expectedSize"); QTest::addColumn("expectedData"); - QTest::newRow("15") << (uint64_t)15 << qsizetype(26) << "{\"testFieldFixedInt64\":15}"_ba; - QTest::newRow("300") << (uint64_t)300 << qsizetype(27) << "{\"testFieldFixedInt64\":300}"_ba; - QTest::newRow("65545") - << (uint64_t)65545 << qsizetype(29) << "{\"testFieldFixedInt64\":65545}"_ba; + QTest::newRow("15") << (uint64_t)15 << "{\"testFieldFixedInt64\":\"15\"}"_ba; + QTest::newRow("300") << (uint64_t)300 << "{\"testFieldFixedInt64\":\"300\"}"_ba; + QTest::newRow("65545") << (uint64_t)65545 << "{\"testFieldFixedInt64\":\"65545\"}"_ba; } void QtProtobufTypesJsonSerializationTest::FixedInt64MessageSerializeTest() { QFETCH(const uint64_t, value); - QFETCH(const qsizetype, expectedSize); QFETCH(const QByteArray, expectedData); SimpleFixedInt64Message test; test.setTestFieldFixedInt64(value); QByteArray result = test.serialize(m_serializer.get()); - QCOMPARE(result.size(), expectedSize); QCOMPARE(result, expectedData); QVERIFY(!QJsonDocument::fromJson(result).isNull()); } @@ -303,29 +274,24 @@ void QtProtobufTypesJsonSerializationTest::FixedInt64MessageSerializeTest() void QtProtobufTypesJsonSerializationTest::SFixedInt32MessageSerializeTest_data() { QTest::addColumn("value"); - QTest::addColumn("expectedSize"); QTest::addColumn("expectedData"); - QTest::newRow("15") << (int32_t)15 << qsizetype(26) << "{\"testFieldFixedInt32\":15}"_ba; - QTest::newRow("300") << (int32_t)300 << qsizetype(27) << "{\"testFieldFixedInt32\":300}"_ba; - QTest::newRow("65545") - << (int32_t)65545 << qsizetype(29) << "{\"testFieldFixedInt32\":65545}"_ba; + QTest::newRow("15") << (int32_t)15 << "{\"testFieldFixedInt32\":15}"_ba; + QTest::newRow("300") << (int32_t)300 << "{\"testFieldFixedInt32\":300}"_ba; + QTest::newRow("65545") << (int32_t)65545 << "{\"testFieldFixedInt32\":65545}"_ba; - QTest::newRow("-1") << (int32_t)-1 << qsizetype(26) << "{\"testFieldFixedInt32\":-1}"_ba; - QTest::newRow("-462") << (int32_t)-462 << qsizetype(28) << "{\"testFieldFixedInt32\":-462}"_ba; - QTest::newRow("-63585") - << (int32_t)-63585 << qsizetype(30) << "{\"testFieldFixedInt32\":-63585}"_ba; + QTest::newRow("-1") << (int32_t)-1 << "{\"testFieldFixedInt32\":-1}"_ba; + QTest::newRow("-462") << (int32_t)-462 << "{\"testFieldFixedInt32\":-462}"_ba; + QTest::newRow("-63585") << (int32_t)-63585 << "{\"testFieldFixedInt32\":-63585}"_ba; } void QtProtobufTypesJsonSerializationTest::SFixedInt32MessageSerializeTest() { QFETCH(const int32_t, value); - QFETCH(const qsizetype, expectedSize); QFETCH(const QByteArray, expectedData); SimpleSFixedInt32Message test; test.setTestFieldFixedInt32(value); QByteArray result = test.serialize(m_serializer.get()); - QCOMPARE(result.size(), expectedSize); QCOMPARE(result, expectedData); QVERIFY(!QJsonDocument::fromJson(result).isNull()); } @@ -333,30 +299,25 @@ void QtProtobufTypesJsonSerializationTest::SFixedInt32MessageSerializeTest() void QtProtobufTypesJsonSerializationTest::SFixedInt64MessageSerializeTest_data() { QTest::addColumn("value"); - QTest::addColumn("expectedSize"); QTest::addColumn("expectedData"); - QTest::newRow("15") << (int64_t)15 << qsizetype(26) << "{\"testFieldFixedInt64\":15}"_ba; - QTest::newRow("300") << (int64_t)300 << qsizetype(27) << "{\"testFieldFixedInt64\":300}"_ba; - QTest::newRow("65545") - << (int64_t)65545 << qsizetype(29) << "{\"testFieldFixedInt64\":65545}"_ba; + QTest::newRow("15") << (int64_t)15 << "{\"testFieldFixedInt64\":\"15\"}"_ba; + QTest::newRow("300") << (int64_t)300 << "{\"testFieldFixedInt64\":\"300\"}"_ba; + QTest::newRow("65545") << (int64_t)65545 << "{\"testFieldFixedInt64\":\"65545\"}"_ba; - QTest::newRow("-1") << (int64_t)-1 << qsizetype(26) << "{\"testFieldFixedInt64\":-1}"_ba; - QTest::newRow("-462") << (int64_t)-462 << qsizetype(28) << "{\"testFieldFixedInt64\":-462}"_ba; - QTest::newRow("-63585") << (int64_t)-63585 << qsizetype(30) - << "{\"testFieldFixedInt64\":-63585}"_ba; + QTest::newRow("-1") << (int64_t)-1 << "{\"testFieldFixedInt64\":\"-1\"}"_ba; + QTest::newRow("-462") << (int64_t)-462 << "{\"testFieldFixedInt64\":\"-462\"}"_ba; + QTest::newRow("-63585") << (int64_t)-63585 << "{\"testFieldFixedInt64\":\"-63585\"}"_ba; } void QtProtobufTypesJsonSerializationTest::SFixedInt64MessageSerializeTest() { QFETCH(const int64_t, value); - QFETCH(const qsizetype, expectedSize); QFETCH(const QByteArray, expectedData); SimpleSFixedInt64Message test; test.setTestFieldFixedInt64(value); QByteArray result = test.serialize(m_serializer.get()); - QCOMPARE(result.size(), expectedSize); QCOMPARE(result, expectedData); QVERIFY(!QJsonDocument::fromJson(result).isNull()); } @@ -364,30 +325,25 @@ void QtProtobufTypesJsonSerializationTest::SFixedInt64MessageSerializeTest() void QtProtobufTypesJsonSerializationTest::FloatMessageSerializeTest_data() { QTest::addColumn("value"); - QTest::addColumn("expectedSize"); QTest::addColumn("expectedData"); - QTest::newRow("float_value_0_1") << 0.1f << qsizetype(22) << "{\"testFieldFloat\":0.1}"_ba; - QTest::newRow("float_value_min") << std::numeric_limits::min() << qsizetype(31) - << "{\"testFieldFloat\":1.175494e-38}"_ba; - QTest::newRow("float_value_max") << std::numeric_limits::max() << qsizetype(31) - << "{\"testFieldFloat\":3.402823e+38}"_ba; - QTest::newRow("float_neg_value_4_2") - << -4.2f << qsizetype(23) << "{\"testFieldFloat\":-4.2}"_ba; - QTest::newRow("float_neg_value_0_0") - << (float)-0.0f << qsizetype(20) << "{\"testFieldFloat\":0}"_ba; + QTest::newRow("float_value_0_1") << 0.1f << "{\"testFieldFloat\":0.1}"_ba; + QTest::newRow("float_value_min") + << std::numeric_limits::min() << "{\"testFieldFloat\":1.17549e-38}"_ba; + QTest::newRow("float_value_max") + << std::numeric_limits::max() << "{\"testFieldFloat\":3.40282e+38}"_ba; + QTest::newRow("float_neg_value_4_2") << -4.2f << "{\"testFieldFloat\":-4.2}"_ba; + QTest::newRow("float_neg_value_0_0") << (float)-0.0f << "{\"testFieldFloat\":0}"_ba; } void QtProtobufTypesJsonSerializationTest::FloatMessageSerializeTest() { QFETCH(const float, value); - QFETCH(const qsizetype, expectedSize); QFETCH(const QByteArray, expectedData); SimpleFloatMessage test; test.setTestFieldFloat(value); QByteArray result = test.serialize(m_serializer.get()); - QCOMPARE(result.size(), expectedSize); QCOMPARE(result, expectedData); QVERIFY(!QJsonDocument::fromJson(result).isNull()); } @@ -395,33 +351,30 @@ void QtProtobufTypesJsonSerializationTest::FloatMessageSerializeTest() void QtProtobufTypesJsonSerializationTest::DoubleMessageSerializeTest_data() { QTest::addColumn("value"); - QTest::addColumn("expectedSize"); QTest::addColumn("expectedData"); - QTest::newRow("double_value_0_1") << 0.1 << qsizetype(23) + QTest::newRow("double_value_0_1") << 0.1 << "{\"testFieldDouble\":0.1}"_ba; QTest::newRow("double_value_min") - << std::numeric_limits::min() << qsizetype(40) - << "{\"testFieldDouble\":2.2250738585072e-308}"_ba; + << std::numeric_limits::min() + << "{\"testFieldDouble\":2.2250738585072014e-308}"_ba; QTest::newRow("double_value_max") - << std::numeric_limits::max() << qsizetype(40) - << "{\"testFieldDouble\":1.7976931348623e+308}"_ba; - QTest::newRow("double_neg_value_4_2") << -4.2 << qsizetype(24) + << std::numeric_limits::max() + << "{\"testFieldDouble\":1.7976931348623157e+308}"_ba; + QTest::newRow("double_neg_value_4_2") << -4.2 << "{\"testFieldDouble\":-4.2}"_ba; - QTest::newRow("double_value_0_0") << 0.0 << qsizetype(21) + QTest::newRow("double_value_0_0") << 0.0 << "{\"testFieldDouble\":0}"_ba; } void QtProtobufTypesJsonSerializationTest::DoubleMessageSerializeTest() { QFETCH(const double, value); - QFETCH(const qsizetype, expectedSize); QFETCH(const QByteArray, expectedData); SimpleDoubleMessage test; test.setTestFieldDouble(value); QByteArray result = test.serialize(m_serializer.get()); - QCOMPARE(result.size(), expectedSize); QCOMPARE(result, expectedData); QVERIFY(!QJsonDocument::fromJson(result).isNull()); } @@ -469,16 +422,16 @@ void QtProtobufTypesJsonSerializationTest::ComplexTypeSerializeTest_data() QTest::newRow("empty_value") << 0 << "" - << "{\"testFieldInt\":0,\"testComplexField\":{\"testFieldString\":\"\"}}"_ba; + << "{\"testComplexField\":{\"testFieldString\":\"\"},\"testFieldInt\":0}"_ba; QTest::newRow("value_only_int") << 42 << "" - << "{\"testFieldInt\":42,\"testComplexField\":{\"testFieldString\":\"\"}}"_ba; + << "{\"testComplexField\":{\"testFieldString\":\"\"},\"testFieldInt\":42}"_ba; QTest::newRow("value_only_string") << 0 << "qwerty" - << "{\"testFieldInt\":0,\"testComplexField\":{\"testFieldString\":\"qwerty\"}}"_ba; + << "{\"testComplexField\":{\"testFieldString\":\"qwerty\"},\"testFieldInt\":0}"_ba; QTest::newRow("int_and_string") << 42 << "qwerty" - << "{\"testFieldInt\":42,\"testComplexField\":{\"testFieldString\":\"qwerty\"}}"_ba; + << "{\"testComplexField\":{\"testFieldString\":\"qwerty\"},\"testFieldInt\":42}"_ba; QTest::newRow("int_and_big_string") << 42 << "YVRfJvjxqbgvFwS1YvOZXgtj5ffGLS7AiNHz9oZIoKbm7z8H79xBuyPkpQXvGoO09OY9xRawx3eOAs9xjo" @@ -488,17 +441,17 @@ void QtProtobufTypesJsonSerializationTest::ComplexTypeSerializeTest_data() "5gVS2g7AQ7rkm72cBdnW9sCEyGabeXAuH5j4GRbuLT7qBZWDcFLF4SsCdS3WfFGdNHfwaijzykByo71PvF" "VlTXH2WJWoFvR5FALjBTn7bCdP0pAiSbLCY8Xz2Msc3dBb5Ff9GISPbUpNmUvBdMZMHQvqOmTNXEPpN0b7" "4MDOMQfWJShOo3NkAvMjs" - << "{\"testFieldInt\":42,\"testComplexField\":{\"testFieldString\":\"YVRfJvjxqbgvFwS1Y" + << "{\"testComplexField\":{\"testFieldString\":\"YVRfJvjxqbgvFwS1Y" "vOZXgtj5ffGLS7AiNHz9oZIoKbm7z8H79xBuyPkpQXvGoO09OY9xRawx3eOAs9xjoTA1xJhrw28TAcq1Ce" "bYlC9WUfQC6hIantaNdyHiKToffi0Zt7la42SRxXZSP4GuxbcZIp53pJnyCwfCy1qdFczT0dmn7h8fpyAd" "emEavwFeda4d0PApGfSU2jLt39X8kYUBxNM2WgALRBgHdVde87q6Pi5U69TjhMd28W1SFD1DxyogCCrqOc" "t2ZPICoLnrqdF3OdNzjRVLfeyvQ8LgLvRNFR9WfWAyAz79nKgBamd8Ntlvt4Mg35E5gVS2g7AQ7rkm72cB" "dnW9sCEyGabeXAuH5j4GRbuLT7qBZWDcFLF4SsCdS3WfFGdNHfwaijzykByo71PvFVlTXH2WJWoFvR5FAL" "jBTn7bCdP0pAiSbLCY8Xz2Msc3dBb5Ff9GISPbUpNmUvBdMZMHQvqOmTNXEPpN0b74MDOMQfWJShOo3NkA" - "vMjs\"}}"_ba; + "vMjs\"},\"testFieldInt\":42}"_ba; QTest::newRow("neg_int_and_string") << -45 << "qwerty" - << "{\"testFieldInt\":-45,\"testComplexField\":{\"testFieldString\":\"qwerty\"}}"_ba; + << "{\"testComplexField\":{\"testFieldString\":\"qwerty\"},\"testFieldInt\":-45}"_ba; } void QtProtobufTypesJsonSerializationTest::ComplexTypeSerializeTest() @@ -528,14 +481,13 @@ void QtProtobufTypesJsonSerializationTest::ResetComplexTypeSerializeTest_data() QTest::addColumn("stringField"); QTest::addColumn("expectedData"); - QTest::newRow("empty_value") - << 0 << u""_s << "{\"testFieldInt\":0,\"testComplexField\":{}}"_ba; + QTest::newRow("empty_value") << 0 << u""_s << "{\"testComplexField\":{},\"testFieldInt\":0}"_ba; QTest::newRow("value_only_int") - << 42 << u""_s << "{\"testFieldInt\":42,\"testComplexField\":{}}"_ba; + << 42 << u""_s << "{\"testComplexField\":{},\"testFieldInt\":42}"_ba; QTest::newRow("value_only_string") - << 0 << u"qwerty"_s << "{\"testFieldInt\":0,\"testComplexField\":{}}"_ba; + << 0 << u"qwerty"_s << "{\"testComplexField\":{},\"testFieldInt\":0}"_ba; QTest::newRow("int_and_string") - << 42 << u"qwerty"_s << "{\"testFieldInt\":42,\"testComplexField\":{}}"_ba; + << 42 << u"qwerty"_s << "{\"testComplexField\":{},\"testFieldInt\":42}"_ba; } void QtProtobufTypesJsonSerializationTest::ResetComplexTypeSerializeTest() @@ -561,7 +513,7 @@ void QtProtobufTypesJsonSerializationTest::DefaultConstructedComplexTypeSerializ { ComplexMessage test; QByteArray result = test.serialize(m_serializer.get()); - QCOMPARE(result, "{\"testFieldInt\":0,\"testComplexField\":{}}"_ba); + QCOMPARE(result, "{\"testComplexField\":{},\"testFieldInt\":0}"_ba); QVERIFY(!QJsonDocument::fromJson(result).isNull()); } diff --git a/tests/auto/protobuf/jsontypes/tst_protobuf_serialization_json_repeatedtypes.cpp b/tests/auto/protobuf/jsontypes/tst_protobuf_serialization_json_repeatedtypes.cpp index ead3e282..f35048fb 100644 --- a/tests/auto/protobuf/jsontypes/tst_protobuf_serialization_json_repeatedtypes.cpp +++ b/tests/auto/protobuf/jsontypes/tst_protobuf_serialization_json_repeatedtypes.cpp @@ -87,7 +87,9 @@ void QtProtobufRepeatedTypesJsonSerializationTest::RepeatedInt64MessageTest() RepeatedInt64Message test; test.setTestRepeatedInt({1, 321, -65999, 12324523123123, -3, 0, 3}); QByteArray result = test.serialize(m_serializer.get()); - QCOMPARE(result, "{\"testRepeatedInt\":[1,321,-65999,12324523123123,-3,0,3]}"_ba); + QCOMPARE( + result, + "{\"testRepeatedInt\":[\"1\",\"321\",\"-65999\",\"12324523123123\",\"-3\",\"0\",\"3\"]}"_ba); QVERIFY(!QJsonDocument::fromJson(result).isNull()); test.setTestRepeatedInt(QtProtobuf::int64List()); @@ -101,7 +103,9 @@ void QtProtobufRepeatedTypesJsonSerializationTest::RepeatedSInt64MessageTest() RepeatedSInt64Message test; test.setTestRepeatedInt({1, 321, -65999, 12324523123123, 0, -3, 3}); QByteArray result = test.serialize(m_serializer.get()); - QCOMPARE(result, "{\"testRepeatedInt\":[1,321,-65999,12324523123123,0,-3,3]}"_ba); + QCOMPARE( + result, + "{\"testRepeatedInt\":[\"1\",\"321\",\"-65999\",\"12324523123123\",\"0\",\"-3\",\"3\"]}"_ba); QVERIFY(!QJsonDocument::fromJson(result).isNull()); test.setTestRepeatedInt(QtProtobuf::sint64List()); @@ -115,7 +119,9 @@ void QtProtobufRepeatedTypesJsonSerializationTest::RepeatedUInt64MessageTest() RepeatedUInt64Message test; test.setTestRepeatedInt({1, 321, 0, 65999, 123245, 123245324235425234, 3}); QByteArray result = test.serialize(m_serializer.get()); - QCOMPARE(result, "{\"testRepeatedInt\":[1,321,0,65999,123245,123245324235425234,3]}"_ba); + QCOMPARE( + result, + "{\"testRepeatedInt\":[\"1\",\"321\",\"0\",\"65999\",\"123245\",\"123245324235425234\",\"3\"]}"_ba); QVERIFY(!QJsonDocument::fromJson(result).isNull()); test.setTestRepeatedInt(QtProtobuf::uint64List()); @@ -157,7 +163,9 @@ void QtProtobufRepeatedTypesJsonSerializationTest::RepeatedFixedInt64MessageTest RepeatedFixedInt64Message test; test.setTestRepeatedInt({1, 321, 65999, 123245324235425234, 3, 3, 0}); QByteArray result = test.serialize(m_serializer.get()); - QCOMPARE(result, "{\"testRepeatedInt\":[1,321,65999,123245324235425234,3,3,0]}"_ba); + QCOMPARE( + result, + "{\"testRepeatedInt\":[\"1\",\"321\",\"65999\",\"123245324235425234\",\"3\",\"3\",\"0\"]}"_ba); QVERIFY(!QJsonDocument::fromJson(result).isNull()); test.setTestRepeatedInt(QtProtobuf::fixed64List()); @@ -171,7 +179,9 @@ void QtProtobufRepeatedTypesJsonSerializationTest::RepeatedSFixedInt64MessageTes RepeatedSFixedInt64Message test; test.setTestRepeatedInt({1, 321, -65999, 123245324235425234, -3, 3, 0}); QByteArray result = test.serialize(m_serializer.get()); - QCOMPARE(result, "{\"testRepeatedInt\":[1,321,-65999,123245324235425234,-3,3,0]}"_ba); + QCOMPARE( + result, + "{\"testRepeatedInt\":[\"1\",\"321\",\"-65999\",\"123245324235425234\",\"-3\",\"3\",\"0\"]}"_ba); QVERIFY(!QJsonDocument::fromJson(result).isNull()); test.setTestRepeatedInt(QtProtobuf::sfixed64List()); @@ -198,10 +208,10 @@ void QtProtobufRepeatedTypesJsonSerializationTest::RepeatedStringMessageTest() void QtProtobufRepeatedTypesJsonSerializationTest::RepeatedFloatMessageTest() { RepeatedFloatMessage test; - test.setTestRepeatedFloat({0.4f, 1.2f, 0.5f, 3.912348f, 0.6f}); + test.setTestRepeatedFloat({ 0.4f, 1.2f, 0.5f, 3.91235f, 0.6f }); QByteArray result = test.serialize(m_serializer.get()); QVERIFY(!QJsonDocument::fromJson(result).isNull()); - QCOMPARE(result, "{\"testRepeatedFloat\":[0.4,1.2,0.5,3.912348,0.6]}"_ba); + QCOMPARE(result, "{\"testRepeatedFloat\":[0.4,1.2,0.5,3.91235,0.6]}"_ba); test.setTestRepeatedFloat(QtProtobuf::floatList()); result = test.serialize(m_serializer.get()); @@ -261,16 +271,14 @@ void QtProtobufRepeatedTypesJsonSerializationTest::RepeatedComplexMessageTest() test.setTestRepeatedComplex({msg, msg, msg}); QByteArray result = test.serialize(m_serializer.get()); QVERIFY(!QJsonDocument::fromJson(result).isNull()); - QCOMPARE(result, - "{\"testRepeatedComplex\":[{\"testFieldInt\":25,\"testComplexField\":" - "{\"testFieldString\":\"qwerty\"}},{\"testFieldInt\":25,\"testComplexField\":" - "{\"testFieldString\":\"qwerty\"}},{\"testFieldInt\":25,\"testComplexField\":" - "{\"testFieldString\":\"qwerty\"}}]}"_ba); + QCOMPARE( + result, + "{\"testRepeatedComplex\":[{\"testComplexField\":{\"testFieldString\":\"qwerty\"},\"testFieldInt\":25},{\"testComplexField\":{\"testFieldString\":\"qwerty\"},\"testFieldInt\":25},{\"testComplexField\":{\"testFieldString\":\"qwerty\"},\"testFieldInt\":25}]}"_ba); test.setTestRepeatedComplex({}); result = test.serialize(m_serializer.get()); QVERIFY(!QJsonDocument::fromJson(result).isNull()); - QCOMPARE(result, "{\"testRepeatedComplex\":[]}"_ba); + QCOMPARE(result, "{}"_ba); } void QtProtobufRepeatedTypesJsonSerializationTest::RepeatedBoolMessageTest() diff --git a/tests/auto/protobuf/wellknown/tst_protobuf_any.cpp b/tests/auto/protobuf/wellknown/tst_protobuf_any.cpp index b0dec8ec..6518ef74 100644 --- a/tests/auto/protobuf/wellknown/tst_protobuf_any.cpp +++ b/tests/auto/protobuf/wellknown/tst_protobuf_any.cpp @@ -49,7 +49,7 @@ void tst_protobuf_any::simpleMessage() payload.setI(42); AnyMessage message; - message.setField(QtProtobuf::Any::fromMessage(payload)); + message.setField(QtProtobuf::Any::fromMessage(&serializer, payload)); QByteArray serialized = message.serialize(&serializer); QCOMPARE_EQ(serialized.toHex(), "0a380a2f747970652e676f6f676c65617069732e636f6d2f717470726f74" @@ -58,7 +58,7 @@ void tst_protobuf_any::simpleMessage() AnyMessage message2; message2.deserialize(&serializer, serialized); - auto result = message2.field().as(); + auto result = message2.field().as(&serializer); QVERIFY(result.has_value()); QCOMPARE_EQ(result.value(), payload); } @@ -97,7 +97,7 @@ void tst_protobuf_any::anyMessage() message.deserialize(&serializer, input); QCOMPARE_EQ(serializer.deserializationError(), QAbstractProtobufSerializer::NoError); - std::optional opt = message.field().as(); + std::optional opt = message.field().as(&serializer); QVERIFY(opt.has_value()); Example ex = std::move(opt).value(); QTEST(ex.str(), "str"); @@ -124,7 +124,7 @@ void tst_protobuf_any::repeatedAnyMessage() QCOMPARE_EQ(message.anys().size(), 3); for (const QtProtobuf::Any &any : message.anys()) { - std::optional opt = any.as(); + std::optional opt = any.as(&serializer); QVERIFY(opt.has_value()); Example ex = std::move(opt).value(); QCOMPARE_EQ(ex.str(), "Hello"); @@ -177,7 +177,7 @@ void tst_protobuf_any::twoAnyMessage() TwoAnyMessage message; message.deserialize(&serializer, serializedData); - std::optional opt = message.two().as(); + std::optional opt = message.two().as(&serializer); QVERIFY(opt); const Example &ex = opt.value(); QCOMPARE_EQ(ex.str(), "Hello"); @@ -188,12 +188,12 @@ void tst_protobuf_any::twoAnyMessage() if (nested) { // The Any-message contains another Any inside: - std::optional anyOpt = message.one().as(); + std::optional anyOpt = message.one().as(&serializer); QVERIFY(anyOpt); // But the nested Any-message is empty: QCOMPARE_EQ(anyOpt->value(), QByteArray()); } else { - std::optional nestedAny = message.one().as(); + std::optional nestedAny = message.one().as(&serializer); QVERIFY(!nestedAny); // not nested // and the value of the field is empty: QCOMPARE_EQ(message.one().value(), QByteArray()); @@ -202,11 +202,12 @@ void tst_protobuf_any::twoAnyMessage() void tst_protobuf_any::fromMessage() { + QProtobufSerializer serializer; Example ex; ex.setH(242); AnyMessage message; - message.setField(QtProtobuf::Any::fromMessage(ex)); - std::optional exop = message.field().as(); + message.setField(QtProtobuf::Any::fromMessage(&serializer, ex)); + std::optional exop = message.field().as(&serializer); QVERIFY(exop.has_value()); QCOMPARE(exop->h(), 242); QCOMPARE(*exop, ex);