mirror of https://github.com/qt/qtgrpc.git
Add JSON serialization and deserialization for Qt Protobuf
Also, move basic API for serializers into QProtobufBaseSerializer class - add full basic types JSON serialization/deserialization functionality - add list serialization/deserialization functionality [ChangeLog][Protobuf] Edit existing QProtobufSerializer API, also move serialization/deserialization methods from QProtobufSerializer class into QProtobufBaseSerializer interface, since all of them shall be re-usable for new Json-serializer. Autotests cover: basic types and list serialization; TBD: maps, enums, Any type, OneOf, enumLists will be completed in subsequent tasks Pick-to: 6.7 Task-number: QTBUG-113731 Change-Id: I7556308062e8e576d32a371f3cb1d4f694824498 Reviewed-by: 🌴 Alexey Edelev 🌴 <alexey.edelev@qt.io>
This commit is contained in:
parent
e6bc158296
commit
3c6e601bb9
|
|
@ -5,11 +5,13 @@ qt_internal_add_module(Protobuf
|
|||
SOURCES
|
||||
qtprotobufglobal.h
|
||||
qabstractprotobufserializer.cpp qabstractprotobufserializer.h
|
||||
qprotobufbaseserializer.cpp qprotobufbaseserializer.h
|
||||
qprotobufmessage.cpp qprotobufmessage.h qprotobufmessage_p.h
|
||||
qprotobuflazymessagepointer.h
|
||||
qprotobufobject.h
|
||||
qprotobufselfcheckiterator.h
|
||||
qprotobufserializer.cpp qprotobufserializer.h qprotobufserializer_p.h
|
||||
qprotobufjsonserializer.cpp qprotobufjsonserializer.h
|
||||
qtprotobuflogging.cpp qtprotobuflogging_p.h
|
||||
qtprotobuftypes.cpp qtprotobuftypes.h
|
||||
qprotobufoneof.cpp qprotobufoneof.h
|
||||
|
|
|
|||
|
|
@ -0,0 +1,85 @@
|
|||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#include "qprotobufbaseserializer.h"
|
||||
|
||||
#include <QtProtobuf/qprotobufmessage.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
/*!
|
||||
\class QProtobufBaseSerializer
|
||||
\inmodule QtProtobuf
|
||||
\since 6.7
|
||||
\brief The QProtobufBaseSerializer class is an interface that represents
|
||||
basic functions for serializing/deserializing objects, lists, and enums.
|
||||
|
||||
The QProtobufBaseSerializer class registers serializers/deserializers for
|
||||
classes implementing a protobuf message, inheriting QProtobufMessage. These
|
||||
classes are generated automatically, based on a .proto file, using the cmake
|
||||
build macro qt6_add_protobuf or by running qtprotobufgen directly.
|
||||
|
||||
This class should be used as a base for specific serializers. The handlers
|
||||
property contains all message-specific serializers and should be used while
|
||||
serialization/deserialization. Inherited classes should reimplement scope of
|
||||
virtual methods that used by registered message
|
||||
serialization/deserialization functions.
|
||||
*/
|
||||
|
||||
/*!
|
||||
Destroys this QProtobufBaseSerializer.
|
||||
*/
|
||||
QProtobufBaseSerializer::~QProtobufBaseSerializer() = default;
|
||||
|
||||
/*!
|
||||
\fn QByteArray QProtobufBaseSerializer::serializeObject(const QProtobufMessage *message,
|
||||
const QtProtobufPrivate::QProtobufPropertyOrdering &ordering,
|
||||
const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo) const
|
||||
|
||||
This function serializes a registered Protobuf message \a message
|
||||
with defined \a ordering and \a fieldInfo, that is recognized
|
||||
like an object, into a QByteArray. \a message must not be \nullptr.
|
||||
|
||||
\sa deserializeObject()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool QProtobufBaseSerializer::deserializeObject(QProtobufMessage *message,
|
||||
const QtProtobufPrivate::QProtobufPropertyOrdering &ordering,
|
||||
QtProtobufPrivate::QProtobufSelfcheckIterator &it) 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.
|
||||
Returns \c true if deserialization was successful, otherwise \c false.
|
||||
|
||||
\sa serializeObject()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\relates QProtobufBaseSerializer
|
||||
\fn template<typename T> inline void qRegisterProtobufType()
|
||||
|
||||
Registers a Protobuf type \e T.
|
||||
This function is normally called by generated code.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\relates QProtobufBaseSerializer
|
||||
\fn template<typename K, typename V> inline void qRegisterProtobufMapType();
|
||||
|
||||
Registers a Protobuf map type \c K and \c V.
|
||||
\c V must be a QProtobufMessage.
|
||||
This function is normally called by generated code.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\relates QProtobufBaseSerializer
|
||||
\fn template<typename T> inline void qRegisterProtobufEnumType();
|
||||
|
||||
Registers serializers for enumeration type \c T in QtProtobuf global
|
||||
serializers registry.
|
||||
|
||||
This function is normally called by generated code.
|
||||
*/
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
@ -0,0 +1,347 @@
|
|||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QPROTOBUFSBASEERIALIZER_H
|
||||
#define QPROTOBUFSBASEERIALIZER_H
|
||||
|
||||
#include <QtProtobuf/qabstractprotobufserializer.h>
|
||||
#include <QtProtobuf/qprotobufselfcheckiterator.h>
|
||||
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QMetaObject>
|
||||
#include <QtCore/QPair>
|
||||
#include <QtCore/QVariant>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class Q_PROTOBUF_EXPORT QProtobufBaseSerializer: public QAbstractProtobufSerializer
|
||||
{
|
||||
|
||||
public:
|
||||
enum Status {
|
||||
Serialized = 0,
|
||||
SerializationInProgress,
|
||||
SerializationError
|
||||
};
|
||||
|
||||
virtual ~QProtobufBaseSerializer();
|
||||
|
||||
virtual QByteArray
|
||||
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 QByteArray
|
||||
serializeListObject(const QList<const QProtobufMessage*> &messageList,
|
||||
const QtProtobufPrivate::QProtobufPropertyOrdering &ordering,
|
||||
const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo) const = 0;
|
||||
virtual Status
|
||||
deserializeListObject(QProtobufMessage *message,
|
||||
const QtProtobufPrivate::QProtobufPropertyOrdering &ordering,
|
||||
QtProtobufPrivate::QProtobufSelfcheckIterator &it) const = 0;
|
||||
|
||||
virtual QByteArray
|
||||
serializeMapPair(const QList<QPair<QVariant, QVariant>> &list,
|
||||
const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo) const = 0;
|
||||
virtual Status deserializeMapPair(QVariant &key, QVariant &value,
|
||||
QtProtobufPrivate::QProtobufSelfcheckIterator &it) const = 0;
|
||||
|
||||
virtual QByteArray
|
||||
serializeEnum(QtProtobuf::int64 value,
|
||||
const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo) const = 0;
|
||||
virtual QByteArray
|
||||
serializeEnumList(const QList<QtProtobuf::int64> &value,
|
||||
const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo) const = 0;
|
||||
virtual bool deserializeEnum(QtProtobuf::int64 &value,
|
||||
QtProtobufPrivate::QProtobufSelfcheckIterator &it) const = 0;
|
||||
virtual bool
|
||||
deserializeEnumList(QList<QtProtobuf::int64> &value,
|
||||
QtProtobufPrivate::QProtobufSelfcheckIterator &it) const = 0;
|
||||
};
|
||||
|
||||
namespace QtProtobufPrivate {
|
||||
|
||||
using Serializer = void (*)(const QProtobufBaseSerializer *, const QVariant &,
|
||||
const QProtobufPropertyOrderingInfo &, QByteArray &);
|
||||
using Deserializer = void (*)(const QProtobufBaseSerializer *, QProtobufSelfcheckIterator &,
|
||||
QVariant &);
|
||||
|
||||
/*!
|
||||
\private
|
||||
\brief SerializationHandlers contains set of objects that required for class
|
||||
serialization/deserialization
|
||||
*/
|
||||
struct SerializationHandler
|
||||
{
|
||||
Serializer serializer = nullptr; /*!< serializer assigned to class */
|
||||
Deserializer deserializer = nullptr; /*!< deserializer assigned to class */
|
||||
};
|
||||
|
||||
extern Q_PROTOBUF_EXPORT SerializationHandler findHandler(QMetaType type);
|
||||
extern Q_PROTOBUF_EXPORT void registerHandler(QMetaType type, const SerializationHandler &handlers);
|
||||
|
||||
/*!
|
||||
\private
|
||||
\brief default serializer template for type T that inherits from QProtobufMessage
|
||||
*/
|
||||
template<typename T,
|
||||
typename std::enable_if_t<std::is_base_of<QProtobufMessage, T>::value, int> = 0>
|
||||
void serializeObject(const QProtobufBaseSerializer *serializer, const QVariant &value,
|
||||
const QProtobufPropertyOrderingInfo &fieldInfo, QByteArray &buffer)
|
||||
{
|
||||
Q_ASSERT_X(serializer != nullptr, "QProtobufBaseSerializer", "Serializer is null");
|
||||
buffer.append(serializer->serializeObject(value.value<T *>(), T::propertyOrdering, fieldInfo));
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
\brief default serializer template for list of type T objects that inherits from QProtobufMessage
|
||||
*/
|
||||
template<typename V,
|
||||
typename std::enable_if_t<std::is_base_of<QProtobufMessage, V>::value, int> = 0>
|
||||
void serializeList(const QProtobufBaseSerializer *serializer, const QVariant &listValue,
|
||||
const QProtobufPropertyOrderingInfo &fieldInfo, QByteArray &buffer)
|
||||
{
|
||||
Q_ASSERT_X(serializer != nullptr, "QProtobufBaseSerializer", "Serializer is null");
|
||||
QList<V> objList = listValue.value<QList<V>>();
|
||||
QList<const QProtobufMessage*> messageList;
|
||||
for (const auto &value : objList)
|
||||
messageList.append(&value);
|
||||
buffer.append(serializer->serializeListObject(messageList, V::propertyOrdering, fieldInfo));
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
\brief default serializer template for map of key K, value V
|
||||
*/
|
||||
template<typename K, typename V,
|
||||
typename std::enable_if_t<!std::is_base_of<QProtobufMessage, V>::value, int> = 0>
|
||||
void serializeMap(const QProtobufBaseSerializer *serializer, const QVariant &value,
|
||||
const QProtobufPropertyOrderingInfo &fieldInfo, QByteArray &buffer)
|
||||
{
|
||||
Q_ASSERT_X(serializer != nullptr, "QProtobufBaseSerializer", "Serializer is null");
|
||||
QHash<K, V> original = value.value<QHash<K, V>>();
|
||||
QList<QPair<QVariant, QVariant>> variantContainer;
|
||||
for (const auto &[k, v] : original.asKeyValueRange()) {
|
||||
variantContainer.append(qMakePair(QVariant::fromValue<K>(k),
|
||||
QVariant::fromValue<V>(v)));
|
||||
}
|
||||
buffer.append(serializer->serializeMapPair(variantContainer, fieldInfo));
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
\brief default serializer template for map of type key K, value V. Specialization for V that
|
||||
inherits from QProtobufMessage
|
||||
*/
|
||||
template<typename K, typename V,
|
||||
typename std::enable_if_t<std::is_base_of<QProtobufMessage, V>::value, int> = 0>
|
||||
void serializeMap(const QProtobufBaseSerializer *serializer, const QVariant &value,
|
||||
const QProtobufPropertyOrderingInfo &fieldInfo, QByteArray &buffer)
|
||||
{
|
||||
Q_ASSERT_X(serializer != nullptr, "QProtobufBaseSerializer", "Serializer is null");
|
||||
QHash<K, V> original = value.value<QHash<K, V>>();
|
||||
QList<QPair<QVariant, QVariant>> variantContainer;
|
||||
for (const auto &[k, v] : original.asKeyValueRange()) {
|
||||
variantContainer.append(qMakePair(QVariant::fromValue<K>(k),
|
||||
QVariant::fromValue<V *>(&v)));
|
||||
|
||||
}
|
||||
buffer.append(serializer->serializeMapPair(variantContainer, fieldInfo));
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
\brief default serializer template for enum types
|
||||
*/
|
||||
template<typename T, typename std::enable_if_t<std::is_enum<T>::value, int> = 0>
|
||||
void serializeEnum(const QProtobufBaseSerializer *serializer, const QVariant &value,
|
||||
const QProtobufPropertyOrderingInfo &fieldInfo, QByteArray &buffer)
|
||||
{
|
||||
Q_ASSERT_X(serializer != nullptr, "QProtobufBaseSerializer", "Serializer is null");
|
||||
buffer.append(serializer->serializeEnum(QtProtobuf::int64(value.value<T>()), fieldInfo));
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
\brief default serializer template for enum list types
|
||||
*/
|
||||
template<typename T, typename std::enable_if_t<std::is_enum<T>::value, int> = 0>
|
||||
void serializeEnumList(const QProtobufBaseSerializer *serializer, const QVariant &value,
|
||||
const QProtobufPropertyOrderingInfo &fieldInfo, QByteArray &buffer)
|
||||
{
|
||||
Q_ASSERT_X(serializer != nullptr, "QProtobufBaseSerializer", "Serializer is null");
|
||||
QList<QtProtobuf::int64> intList;
|
||||
for (auto enumValue : value.value<QList<T>>()) {
|
||||
intList.append(QtProtobuf::int64(enumValue));
|
||||
}
|
||||
buffer.append(serializer->serializeEnumList(intList, fieldInfo));
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
\brief default deserializer template for type T that inherits from QProtobufMessage
|
||||
*/
|
||||
template<typename T,
|
||||
typename std::enable_if_t<std::is_base_of<QProtobufMessage, T>::value, int> = 0>
|
||||
void deserializeObject(const QProtobufBaseSerializer *serializer, QProtobufSelfcheckIterator &it,
|
||||
QVariant &to)
|
||||
{
|
||||
Q_ASSERT_X(serializer != nullptr, "QProtobufBaseSerializer", "Serializer is null");
|
||||
Q_ASSERT_X(to.isNull() || to.metaType() == QMetaType::fromType<T *>(),
|
||||
"QProtobufBaseSerializer",
|
||||
"Property should be either uninitialized or contain a valid pointer");
|
||||
|
||||
T *value = to.value<T *>();
|
||||
if (value == nullptr) {
|
||||
value = new T;
|
||||
to = QVariant::fromValue<T *>(value);
|
||||
}
|
||||
serializer->deserializeObject(value, T::propertyOrdering, it);
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
\brief default deserializer template for list of type T objects that inherits from QProtobufMessage
|
||||
*/
|
||||
template<typename V,
|
||||
typename std::enable_if_t<std::is_base_of<QProtobufMessage, V>::value, int> = 0>
|
||||
void deserializeList(const QProtobufBaseSerializer *serializer, QProtobufSelfcheckIterator &it,
|
||||
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<V> list = previous.value<QList<V>>();
|
||||
list.append(newValue);
|
||||
previous.setValue(list);
|
||||
} while (result == QProtobufBaseSerializer::SerializationInProgress);
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
*
|
||||
\brief default deserializer template for map of key K, value V
|
||||
*/
|
||||
template<typename K, typename V,
|
||||
typename std::enable_if_t<!std::is_base_of<QProtobufMessage, V>::value, int> = 0>
|
||||
void deserializeMap(const QProtobufBaseSerializer *serializer, QProtobufSelfcheckIterator &it,
|
||||
QVariant &previous)
|
||||
{
|
||||
Q_ASSERT_X(serializer != nullptr, "QProtobufBaseSerializer", "Serializer is null");
|
||||
|
||||
QHash<K, V> out = previous.value<QHash<K, V>>();
|
||||
QVariant key = QVariant::fromValue<K>(K());
|
||||
QVariant value = QVariant::fromValue<V>(V());
|
||||
|
||||
if (serializer->deserializeMapPair(key, value, it) == QProtobufBaseSerializer::Serialized) {
|
||||
out[key.value<K>()] = value.value<V>();
|
||||
previous = QVariant::fromValue<QHash<K, V>>(out);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
*
|
||||
\brief default deserializer template for map of type key K, value V. Specialization for V
|
||||
that inherits from QProtobufMessage
|
||||
*/
|
||||
template<typename K, typename V,
|
||||
typename std::enable_if_t<std::is_base_of<QProtobufMessage, V>::value, int> = 0>
|
||||
void deserializeMap(const QProtobufBaseSerializer *serializer, QProtobufSelfcheckIterator &it,
|
||||
QVariant &previous)
|
||||
{
|
||||
Q_ASSERT_X(serializer != nullptr, "QProtobufBaseSerializer", "Serializer is null");
|
||||
|
||||
auto out = previous.value<QHash<K, V>>();
|
||||
QVariant key = QVariant::fromValue<K>(K());
|
||||
QVariant value = QVariant::fromValue<V *>(nullptr);
|
||||
|
||||
if (serializer->deserializeMapPair(key, value, it) == QProtobufBaseSerializer::Serialized) {
|
||||
const auto valuePtr = value.value<V *>();
|
||||
out[key.value<K>()] = valuePtr ? *valuePtr : V();
|
||||
previous = QVariant::fromValue<QHash<K, V>>(out);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
*
|
||||
\brief default deserializer template for enum type T
|
||||
*/
|
||||
template<typename T, typename std::enable_if_t<std::is_enum<T>::value, int> = 0>
|
||||
void deserializeEnum(const QProtobufBaseSerializer *serializer, QProtobufSelfcheckIterator &it,
|
||||
QVariant &to)
|
||||
{
|
||||
Q_ASSERT_X(serializer != nullptr, "QProtobufBaseSerializer", "Serializer is null");
|
||||
QtProtobuf::int64 intValue;
|
||||
if (serializer->deserializeEnum(intValue, it))
|
||||
to = QVariant::fromValue<T>(static_cast<T>(intValue._t));
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
*
|
||||
\brief default deserializer template for enumList type T
|
||||
*/
|
||||
template<typename T, typename std::enable_if_t<std::is_enum<T>::value, int> = 0>
|
||||
void deserializeEnumList(const QProtobufBaseSerializer *serializer, QProtobufSelfcheckIterator &it,
|
||||
QVariant &previous)
|
||||
{
|
||||
Q_ASSERT_X(serializer != nullptr, "QProtobufBaseSerializer", "Serializer is null");
|
||||
QList<QtProtobuf::int64> intList;
|
||||
if (!serializer->deserializeEnumList(intList, it))
|
||||
return;
|
||||
QList<T> enumList = previous.value<QList<T>>();
|
||||
for (auto intValue : intList)
|
||||
enumList.append(static_cast<T>(intValue._t));
|
||||
previous = QVariant::fromValue<QList<T>>(enumList);
|
||||
}
|
||||
} // namespace QtProtobufPrivate
|
||||
|
||||
template<typename T>
|
||||
inline void qRegisterProtobufType()
|
||||
{
|
||||
T::registerTypes();
|
||||
QtProtobufPrivate::registerOrdering(QMetaType::fromType<T>(), T::propertyOrdering);
|
||||
QtProtobufPrivate::registerHandler(
|
||||
QMetaType::fromType<T *>(),
|
||||
{ QtProtobufPrivate::serializeObject<T>, QtProtobufPrivate::deserializeObject<T> });
|
||||
QtProtobufPrivate::registerHandler(
|
||||
QMetaType::fromType<QList<T>>(),
|
||||
{ QtProtobufPrivate::serializeList<T>, QtProtobufPrivate::deserializeList<T> });
|
||||
}
|
||||
|
||||
template<typename K, typename V>
|
||||
inline void qRegisterProtobufMapType()
|
||||
{
|
||||
QtProtobufPrivate::registerHandler(
|
||||
QMetaType::fromType<QHash<K, V>>(),
|
||||
{ QtProtobufPrivate::serializeMap<K, V>, QtProtobufPrivate::deserializeMap<K, V> });
|
||||
}
|
||||
|
||||
#ifdef Q_QDOC
|
||||
template<typename T>
|
||||
inline void qRegisterProtobufEnumType();
|
||||
#else // !Q_QDOC
|
||||
template<typename T, typename std::enable_if_t<std::is_enum<T>::value, int> = 0>
|
||||
inline void qRegisterProtobufEnumType()
|
||||
{
|
||||
QtProtobufPrivate::registerHandler(
|
||||
QMetaType::fromType<T>(),
|
||||
{ QtProtobufPrivate::serializeEnum<T>, QtProtobufPrivate::deserializeEnum<T> });
|
||||
QtProtobufPrivate::registerHandler(
|
||||
QMetaType::fromType<QList<T>>(),
|
||||
{ QtProtobufPrivate::serializeEnumList<T>, QtProtobufPrivate::deserializeEnumList<T> });
|
||||
}
|
||||
#endif // Q_QDOC
|
||||
|
||||
QT_END_NAMESPACE
|
||||
#endif // QPROTOBUFSBASEERIALIZER_H
|
||||
|
|
@ -0,0 +1,679 @@
|
|||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#include "qprotobufjsonserializer.h"
|
||||
#include "qprotobufserializer_p.h"
|
||||
#include "qprotobufmessage_p.h"
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QJsonDocument>
|
||||
#include <QtCore/QJsonObject>
|
||||
#include <QtCore/QJsonArray>
|
||||
#include <QtCore/QtGlobal>
|
||||
#include <QtCore/QVariant>
|
||||
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
/*!
|
||||
\class QProtobufJsonSerializer
|
||||
\inmodule QtProtobuf
|
||||
\since 6.7
|
||||
\brief The QProtobufJsonSerializer class is interface that represents
|
||||
basic functions for serialization/deserialization of QProtobufMessage
|
||||
objects to Json.
|
||||
\reentrant
|
||||
|
||||
The QProtobufJsonSerializer class registers serializers/deserializers for
|
||||
classes implementing a protobuf message, inheriting QProtobufMessage. These
|
||||
classes are generated automatically, based on a .proto file, using the cmake
|
||||
build macro qt6_add_protobuf or by running qtprotobufgen directly.
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn QAbstractProtobufSerializer::DeserializationError QProtobufJsonSerializer::deserializationError() const
|
||||
|
||||
Returns the last deserialization error.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QString QProtobufJsonSerializer::deserializationErrorString() const
|
||||
|
||||
Returns a human-readable string describing the last deserialization error.
|
||||
If there was no error, an empty string is returned.
|
||||
*/
|
||||
|
||||
using namespace Qt::StringLiterals;
|
||||
using namespace QtProtobufPrivate;
|
||||
|
||||
class QProtobufJsonSerializerPrivate final
|
||||
{
|
||||
Q_DISABLE_COPY_MOVE(QProtobufJsonSerializerPrivate)
|
||||
|
||||
public:
|
||||
using Serializer = std::function<QByteArray(const QVariant&)>;
|
||||
using Deserializer = std::function<QVariant(const QJsonValue&, bool &ok)>;
|
||||
|
||||
struct SerializationHandlers {
|
||||
// serializer assigned to class
|
||||
Serializer serializer;
|
||||
// deserializer assigned to class
|
||||
Deserializer deserializer;
|
||||
};
|
||||
|
||||
// TBD Replace std::unordered_map to QHash
|
||||
using SerializerRegistry = std::unordered_map<int/*metatypeid*/, SerializationHandlers>;
|
||||
|
||||
static QByteArray serializeFloat(const QVariant &propertyValue)
|
||||
{
|
||||
bool ok = false;
|
||||
float value = propertyValue.toFloat(&ok);
|
||||
if (!ok || qIsNaN(value)) {
|
||||
return QByteArray("NaN");
|
||||
}
|
||||
return QByteArray::number(value, 'g', 7);
|
||||
}
|
||||
|
||||
static QByteArray serializeDouble(const QVariant &propertyValue)
|
||||
{
|
||||
bool ok = false;
|
||||
double value = propertyValue.toDouble(&ok);
|
||||
if (!ok || qIsNaN(value)) {
|
||||
return QByteArray("NaN");
|
||||
}
|
||||
return QByteArray::number(value, 'g', 14);
|
||||
}
|
||||
|
||||
static QByteArray serializeString(const QVariant &propertyValue)
|
||||
{
|
||||
return '"' + propertyValue.toString().toUtf8() + '"';
|
||||
}
|
||||
|
||||
static QByteArray serializeBytes(const QVariant &propertyValue) {
|
||||
return QByteArray("\"") + propertyValue.toByteArray().toBase64() + "\"";
|
||||
}
|
||||
|
||||
template<typename L>
|
||||
static QByteArray serializeList(const QVariant &propertyValue)
|
||||
{
|
||||
L listValue = propertyValue.value<L>();
|
||||
QByteArray result("[");
|
||||
for (auto value : listValue) {
|
||||
result += QByteArray::number(value) + ",";
|
||||
}
|
||||
//Remove trailing `,`
|
||||
if (listValue.size() > 0) {
|
||||
result.chop(1);
|
||||
}
|
||||
result += "]";
|
||||
return result;
|
||||
}
|
||||
|
||||
static QByteArray serializeBoolList(const QVariant &propertyValue)
|
||||
{
|
||||
QtProtobuf::boolList listValue = propertyValue.value<QtProtobuf::boolList>();
|
||||
QByteArray result("[");
|
||||
for (auto value : listValue) {
|
||||
if (value)
|
||||
result += QByteArray("true,");
|
||||
else
|
||||
result += QByteArray("false,");
|
||||
}
|
||||
if (listValue.size() > 0) {
|
||||
result.chop(1);
|
||||
}
|
||||
result += "]";
|
||||
return result;
|
||||
}
|
||||
|
||||
static QByteArray serializeFloatList(const QVariant &propertyValue)
|
||||
{
|
||||
QtProtobuf::floatList listValue = propertyValue.value<QtProtobuf::floatList>();
|
||||
QByteArray result("[");
|
||||
for (auto value : listValue) {
|
||||
if (qIsNaN(value))
|
||||
return QByteArray("NaN");
|
||||
result += QByteArray::number(value, 'g', 7) + ",";
|
||||
}
|
||||
if (listValue.size() > 0) {
|
||||
result.chop(1);
|
||||
}
|
||||
result += "]";
|
||||
return result;
|
||||
}
|
||||
|
||||
static QByteArray serializeStringList(const QVariant &propertyValue)
|
||||
{
|
||||
QStringList listValue = propertyValue.value<QStringList>();
|
||||
QByteArray result("[");
|
||||
for (auto value : listValue) {
|
||||
result += QByteArray("\"") + value.toUtf8() + "\",";
|
||||
}
|
||||
if (listValue.size() > 0) {
|
||||
result.chop(1);
|
||||
}
|
||||
result += "]";
|
||||
return result;
|
||||
}
|
||||
|
||||
static QByteArray serializeBytesList(const QVariant &propertyValue)
|
||||
{
|
||||
QByteArrayList listValue = propertyValue.value<QByteArrayList>();
|
||||
QByteArray result("[");
|
||||
for (auto value : listValue) {
|
||||
result += QByteArray("\"") + value.toBase64() + "\",";
|
||||
}
|
||||
if (listValue.size() > 0) {
|
||||
result.chop(1);
|
||||
}
|
||||
result += "]";
|
||||
return result;
|
||||
}
|
||||
|
||||
static QByteArray serializeDoubleList(const QVariant &propertyValue)
|
||||
{
|
||||
QtProtobuf::doubleList listValue = propertyValue.value<QtProtobuf::doubleList>();
|
||||
QByteArray result("[");
|
||||
for (auto value : listValue) {
|
||||
if (qIsNaN(value))
|
||||
return QByteArray("NaN");
|
||||
result += QByteArray::number(value, 'g', 14) + ",";
|
||||
}
|
||||
if (listValue.size() > 0) {
|
||||
result.chop(1);
|
||||
}
|
||||
result += "]";
|
||||
return result;
|
||||
}
|
||||
|
||||
QProtobufJsonSerializerPrivate(QProtobufJsonSerializer *q)
|
||||
: qPtr(q)
|
||||
{
|
||||
// TBD Change to assigning the result of a lambda to a static variable
|
||||
if (handlers.empty()) {
|
||||
handlers[qMetaTypeId<QtProtobuf::int32>()]
|
||||
= {{}, QProtobufJsonSerializerPrivate::deserializeInt32};
|
||||
handlers[qMetaTypeId<QtProtobuf::sfixed32>()]
|
||||
= {{}, QProtobufJsonSerializerPrivate::deserializeInt32};
|
||||
handlers[qMetaTypeId<QtProtobuf::sint32>()]
|
||||
= {{}, QProtobufJsonSerializerPrivate::deserializeInt32};
|
||||
handlers[qMetaTypeId<QtProtobuf::sint64>()]
|
||||
= {{}, QProtobufJsonSerializerPrivate::deserializeInt64};
|
||||
handlers[qMetaTypeId<QtProtobuf::int64>()]
|
||||
= {{}, QProtobufJsonSerializerPrivate::deserializeInt64};
|
||||
handlers[qMetaTypeId<QtProtobuf::sfixed64>()]
|
||||
= {{}, QProtobufJsonSerializerPrivate::deserializeInt64};
|
||||
handlers[qMetaTypeId<QtProtobuf::uint32>()]
|
||||
= {{}, QProtobufJsonSerializerPrivate::deserializeUInt32};
|
||||
handlers[qMetaTypeId<QtProtobuf::fixed32>()]
|
||||
= {{}, QProtobufJsonSerializerPrivate::deserializeUInt32};
|
||||
handlers[qMetaTypeId<QtProtobuf::uint64>()]
|
||||
= {{}, QProtobufJsonSerializerPrivate::deserializeUInt64};
|
||||
handlers[qMetaTypeId<QtProtobuf::fixed64>()]
|
||||
= {{}, QProtobufJsonSerializerPrivate::deserializeUInt64};
|
||||
handlers[qMetaTypeId<bool>()]
|
||||
= {{}, QProtobufJsonSerializerPrivate::deserializeBool};
|
||||
handlers[QMetaType::Float] = {QProtobufJsonSerializerPrivate::serializeFloat,
|
||||
QProtobufJsonSerializerPrivate::deserializeFloat};
|
||||
handlers[QMetaType::Double] = {QProtobufJsonSerializerPrivate::serializeDouble,
|
||||
QProtobufJsonSerializerPrivate::deserializeDouble};
|
||||
handlers[QMetaType::QString]
|
||||
= {QProtobufJsonSerializerPrivate::serializeString,
|
||||
QProtobufJsonSerializerPrivate::deserializeString};
|
||||
handlers[QMetaType::QByteArray]
|
||||
= {QProtobufJsonSerializerPrivate::serializeBytes,
|
||||
QProtobufJsonSerializerPrivate::deserializeByteArray};
|
||||
handlers[qMetaTypeId<QtProtobuf::boolList>()]
|
||||
= {QProtobufJsonSerializerPrivate::serializeBoolList,
|
||||
QProtobufJsonSerializerPrivate::deserializeList<bool>};
|
||||
handlers[qMetaTypeId<QtProtobuf::int32List>()]
|
||||
= {QProtobufJsonSerializerPrivate::serializeList<QtProtobuf::int32List>,
|
||||
QProtobufJsonSerializerPrivate::deserializeList<QtProtobuf::int32>};
|
||||
handlers[qMetaTypeId<QtProtobuf::int64List>()]
|
||||
= {QProtobufJsonSerializerPrivate::serializeList<QtProtobuf::int64List>,
|
||||
QProtobufJsonSerializerPrivate::deserializeList<QtProtobuf::int64>};
|
||||
handlers[qMetaTypeId<QtProtobuf::sint32List>()]
|
||||
= {QProtobufJsonSerializerPrivate::serializeList<QtProtobuf::sint32List>,
|
||||
QProtobufJsonSerializerPrivate::deserializeList<QtProtobuf::sint32>};
|
||||
handlers[qMetaTypeId<QtProtobuf::sint64List>()]
|
||||
= {QProtobufJsonSerializerPrivate::serializeList<QtProtobuf::sint64List>,
|
||||
QProtobufJsonSerializerPrivate::deserializeList<QtProtobuf::sint64>};
|
||||
handlers[qMetaTypeId<QtProtobuf::uint32List>()]
|
||||
= {QProtobufJsonSerializerPrivate::serializeList<QtProtobuf::uint32List>,
|
||||
QProtobufJsonSerializerPrivate::deserializeList<QtProtobuf::uint32>};
|
||||
handlers[qMetaTypeId<QtProtobuf::uint64List>()]
|
||||
= {QProtobufJsonSerializerPrivate::serializeList<QtProtobuf::uint64List>,
|
||||
QProtobufJsonSerializerPrivate::deserializeList<QtProtobuf::uint64>};
|
||||
handlers[qMetaTypeId<QtProtobuf::fixed32List>()]
|
||||
= {QProtobufJsonSerializerPrivate::serializeList<QtProtobuf::fixed32List>,
|
||||
QProtobufJsonSerializerPrivate::deserializeList<QtProtobuf::fixed32>};
|
||||
handlers[qMetaTypeId<QtProtobuf::fixed64List>()]
|
||||
= {QProtobufJsonSerializerPrivate::serializeList<QtProtobuf::fixed64List>,
|
||||
QProtobufJsonSerializerPrivate::deserializeList<QtProtobuf::fixed64>};
|
||||
handlers[qMetaTypeId<QtProtobuf::sfixed32List>()]
|
||||
= {QProtobufJsonSerializerPrivate::serializeList<QtProtobuf::sfixed32List>,
|
||||
QProtobufJsonSerializerPrivate::deserializeList<QtProtobuf::sfixed32>};
|
||||
handlers[qMetaTypeId<QtProtobuf::sfixed64List>()]
|
||||
= {QProtobufJsonSerializerPrivate::serializeList<QtProtobuf::sfixed64List>,
|
||||
QProtobufJsonSerializerPrivate::deserializeList<QtProtobuf::sfixed64>};
|
||||
handlers[qMetaTypeId<QtProtobuf::floatList>()]
|
||||
= {QProtobufJsonSerializerPrivate::serializeFloatList,
|
||||
QProtobufJsonSerializerPrivate::deserializeList<float>};
|
||||
handlers[qMetaTypeId<QtProtobuf::doubleList>()]
|
||||
= {QProtobufJsonSerializerPrivate::serializeDoubleList,
|
||||
QProtobufJsonSerializerPrivate::deserializeList<double>};
|
||||
handlers[qMetaTypeId<QStringList>()]
|
||||
= {QProtobufJsonSerializerPrivate::serializeStringList,
|
||||
QProtobufJsonSerializerPrivate::deserializeStringList};
|
||||
handlers[qMetaTypeId<QByteArrayList>()]
|
||||
= {QProtobufJsonSerializerPrivate::serializeBytesList,
|
||||
QProtobufJsonSerializerPrivate::deserializeList<QByteArray>};
|
||||
}
|
||||
}
|
||||
~QProtobufJsonSerializerPrivate() = default;
|
||||
|
||||
QByteArray serializeValue(const QVariant &propertyValue,
|
||||
const QProtobufPropertyOrderingInfo &fieldInfo)
|
||||
{
|
||||
QByteArray buffer;
|
||||
QMetaType metaType = propertyValue.metaType();
|
||||
auto userType = propertyValue.userType();
|
||||
|
||||
if (metaType.id() == QMetaType::UnknownType) {
|
||||
return {};
|
||||
}
|
||||
auto handler = QtProtobufPrivate::findHandler(metaType);
|
||||
if (handler.serializer) {
|
||||
handler.serializer(qPtr, propertyValue, fieldInfo, buffer);
|
||||
} else {
|
||||
auto handler = handlers.find(userType);
|
||||
if (handler != handlers.end() && handler->second.serializer) {
|
||||
buffer += handler->second.serializer(propertyValue);
|
||||
} else {
|
||||
buffer += propertyValue.toString().toUtf8();
|
||||
}
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
QByteArray serializeProperty(const QVariant &propertyValue,
|
||||
const QProtobufPropertyOrderingInfo &fieldInfo)
|
||||
{
|
||||
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) {
|
||||
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(serializeProperty(propertyValue, fieldInfo));
|
||||
result.append(",");
|
||||
}
|
||||
result.chop(1);
|
||||
}
|
||||
result.append("}");
|
||||
return result;
|
||||
}
|
||||
|
||||
static QVariant deserializeInt32(const QJsonValue &value, bool &ok)
|
||||
{
|
||||
auto val = value.toInt();
|
||||
ok = value.isDouble();
|
||||
return QVariant::fromValue(val);
|
||||
}
|
||||
|
||||
static QVariant deserializeUInt32(const QJsonValue &value, bool &ok)
|
||||
{
|
||||
auto val = value.toVariant().toUInt(&ok);
|
||||
return QVariant::fromValue(val);
|
||||
}
|
||||
|
||||
static QVariant deserializeInt64(const QJsonValue &value, bool &ok)
|
||||
{
|
||||
auto val = value.toVariant().toLongLong(&ok);
|
||||
return QVariant::fromValue(val);
|
||||
}
|
||||
|
||||
static QVariant deserializeUInt64(const QJsonValue &value, bool &ok)
|
||||
{
|
||||
auto val = value.toVariant().toULongLong(&ok);
|
||||
return QVariant::fromValue(val);
|
||||
}
|
||||
|
||||
static QVariant deserializeFloat(const QJsonValue &value, bool &ok)
|
||||
{
|
||||
QByteArray data = value.toVariant().toByteArray();
|
||||
if (data == "NaN" || data == "Infinity" || data == "-Infinity") {
|
||||
ok = true;
|
||||
return QVariant(data);
|
||||
}
|
||||
auto val = data.toFloat(&ok);
|
||||
return QVariant::fromValue(val);
|
||||
}
|
||||
|
||||
static QVariant deserializeDouble(const QJsonValue &value, bool &ok)
|
||||
{
|
||||
QByteArray data = value.toVariant().toByteArray();
|
||||
if (data == "NaN" || data == "Infinity" || data == "-Infinity") {
|
||||
ok = true;
|
||||
return QVariant(data);
|
||||
}
|
||||
auto val = data.toDouble(&ok);
|
||||
return QVariant::fromValue(val);
|
||||
}
|
||||
|
||||
static QVariant deserializeBool(const QJsonValue &value, bool &ok)
|
||||
{
|
||||
ok = value.isBool();
|
||||
return (value.isBool()) ? QVariant(value.toBool()) : QVariant();
|
||||
}
|
||||
|
||||
static QVariant deserializeString(const QJsonValue &value, bool &ok)
|
||||
{
|
||||
ok = value.isString();
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
static QVariant deserializeByteArray(const QJsonValue &value, bool &ok)
|
||||
{
|
||||
QByteArray data = value.toVariant().toByteArray();
|
||||
if (value.isString()) {
|
||||
ok = true;
|
||||
return QVariant::fromValue(QByteArray::fromBase64(data));
|
||||
}
|
||||
ok = false;
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static QVariant deserializeList(const QJsonValue &value, bool &ok)
|
||||
{
|
||||
if (!value.isArray()) {
|
||||
ok = false;
|
||||
return QVariant();
|
||||
}
|
||||
ok = true;
|
||||
QList<T> list;
|
||||
QJsonArray array = value.toArray();
|
||||
auto handler = handlers.find(qMetaTypeId<T>());
|
||||
if (handler == handlers.end() || !handler->second.deserializer) {
|
||||
qProtoWarning() << "Unable to deserialize simple type list."
|
||||
"Could not find deserializer for type"
|
||||
<< QMetaType::fromType<T>().name();
|
||||
return QVariant::fromValue(list);
|
||||
}
|
||||
|
||||
for (auto arrayValue : array) {
|
||||
bool valueOk = false;
|
||||
QVariant newValue = handler->second.deserializer(arrayValue, valueOk);
|
||||
list.append(newValue.value<T>());
|
||||
}
|
||||
return QVariant::fromValue(list);
|
||||
}
|
||||
|
||||
static QVariant deserializeStringList(const QJsonValue &value, bool &ok)
|
||||
{
|
||||
if (!value.isArray()) {
|
||||
ok = false;
|
||||
return QVariant();
|
||||
}
|
||||
QStringList list;
|
||||
if (value.isArray()) {
|
||||
QJsonArray array = value.toArray();
|
||||
for (auto arrayValue : array) {
|
||||
QVariant newValue = deserializeString(arrayValue, ok);
|
||||
list.append(newValue.value<QString>());
|
||||
}
|
||||
}
|
||||
return QVariant::fromValue(list);
|
||||
}
|
||||
|
||||
QVariant deserializeValue(const QMetaType &metaType,
|
||||
QProtobufSelfcheckIterator &it,
|
||||
const QJsonValue &value,
|
||||
bool &ok)
|
||||
{
|
||||
QVariant result;
|
||||
auto handler = QtProtobufPrivate::findHandler(metaType);
|
||||
if (handler.deserializer) {
|
||||
handler.deserializer(qPtr, it, result);
|
||||
ok = result.isValid();
|
||||
} else {
|
||||
auto handler = handlers.find(metaType.id());
|
||||
if (handler != handlers.end() && handler->second.deserializer) {
|
||||
result = handler->second.deserializer(value, ok);
|
||||
} 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()));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool deserializeObject(QProtobufMessage *message,
|
||||
const QProtobufPropertyOrdering &ordering,
|
||||
QByteArrayView data)
|
||||
{
|
||||
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<size_t>(data.size())));
|
||||
|
||||
if (!document.isObject())
|
||||
return false;
|
||||
|
||||
std::map<QString, QProtobufPropertyOrderingInfo> msgContainer; // map<key, fieldInfo>
|
||||
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);
|
||||
QString key = fieldInfo.getJsonName().toString();
|
||||
msgContainer.insert(std::pair<QString, QProtobufPropertyOrderingInfo>(key, fieldInfo));
|
||||
}
|
||||
|
||||
QByteArray object;
|
||||
// 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);
|
||||
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);
|
||||
}
|
||||
// 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);
|
||||
if (ok) {
|
||||
message->setProperty(iter->second, std::move(newPropertyValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
void setDeserializationError(QAbstractProtobufSerializer::DeserializationError error,
|
||||
const QString &errorString)
|
||||
{
|
||||
deserializationError = error;
|
||||
deserializationErrorString = errorString;
|
||||
}
|
||||
|
||||
void setUnexpectedEndOfStreamError()
|
||||
{
|
||||
setDeserializationError(QAbstractProtobufSerializer::UnexpectedEndOfStreamError,
|
||||
QCoreApplication::translate("QtProtobuf",
|
||||
"Unexpected end of stream"));
|
||||
}
|
||||
|
||||
void clearError();
|
||||
|
||||
QAbstractProtobufSerializer::DeserializationError deserializationError =
|
||||
QAbstractProtobufSerializer::NoDeserializerError;
|
||||
QString deserializationErrorString;
|
||||
QJsonArray activeArray;
|
||||
|
||||
private:
|
||||
static SerializerRegistry handlers;
|
||||
QProtobufJsonSerializer *qPtr;
|
||||
};
|
||||
|
||||
QProtobufJsonSerializerPrivate::SerializerRegistry QProtobufJsonSerializerPrivate::handlers = {};
|
||||
|
||||
void QProtobufJsonSerializerPrivate::clearError()
|
||||
{
|
||||
deserializationError = QAbstractProtobufSerializer::NoError;
|
||||
deserializationErrorString.clear();
|
||||
}
|
||||
|
||||
QProtobufJsonSerializer::QProtobufJsonSerializer() :
|
||||
d_ptr(new QProtobufJsonSerializerPrivate(this))
|
||||
{
|
||||
}
|
||||
|
||||
QProtobufJsonSerializer::~QProtobufJsonSerializer() = default;
|
||||
|
||||
QAbstractProtobufSerializer::DeserializationError
|
||||
QProtobufJsonSerializer::deserializationError() const
|
||||
{
|
||||
return d_ptr->deserializationError;
|
||||
}
|
||||
|
||||
QString QProtobufJsonSerializer::deserializationErrorString() const
|
||||
{
|
||||
return d_ptr->deserializationErrorString;
|
||||
}
|
||||
|
||||
QByteArray
|
||||
QProtobufJsonSerializer::serializeMessage(const QProtobufMessage *message,
|
||||
const QProtobufPropertyOrdering &ordering) const
|
||||
{
|
||||
return d_ptr->serializeObject(message, ordering);
|
||||
}
|
||||
|
||||
bool QProtobufJsonSerializer::deserializeMessage(QProtobufMessage *message,
|
||||
const QProtobufPropertyOrdering &ordering,
|
||||
QByteArrayView data) const
|
||||
{
|
||||
d_ptr->clearError();
|
||||
auto it = QProtobufSelfcheckIterator::fromView(data);
|
||||
if (!d_ptr->deserializeObject(message, ordering, data))
|
||||
return false;
|
||||
|
||||
if (!it.isValid())
|
||||
d_ptr->setUnexpectedEndOfStreamError();
|
||||
return it.isValid();
|
||||
}
|
||||
|
||||
QByteArray
|
||||
QProtobufJsonSerializer::serializeObject(const QProtobufMessage *message,
|
||||
const QProtobufPropertyOrdering &ordering,
|
||||
const QProtobufPropertyOrderingInfo &fieldInfo) const
|
||||
{
|
||||
Q_UNUSED(fieldInfo);
|
||||
return serializeMessage(message, ordering);
|
||||
}
|
||||
|
||||
QByteArray
|
||||
QProtobufJsonSerializer::serializeListObject(const QList<const QProtobufMessage*> &messageList,
|
||||
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;
|
||||
}
|
||||
|
||||
bool QProtobufJsonSerializer::deserializeObject(QProtobufMessage *message,
|
||||
const QProtobufPropertyOrdering &ordering,
|
||||
QProtobufSelfcheckIterator &it) const
|
||||
{
|
||||
return deserializeMessage(message, ordering, it.data());
|
||||
}
|
||||
|
||||
QProtobufBaseSerializer::Status
|
||||
QProtobufJsonSerializer::deserializeListObject(QProtobufMessage *message,
|
||||
const QProtobufPropertyOrdering &ordering,
|
||||
QProtobufSelfcheckIterator &it) 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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
return QProtobufBaseSerializer::SerializationError;
|
||||
}
|
||||
|
||||
QByteArray QProtobufJsonSerializer::serializeMapPair(const QList<QPair<QVariant, QVariant>> &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;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QPROTOBUFJSONSERIALIZER_H
|
||||
#define QPROTOBUFJSONSERIALIZER_H
|
||||
|
||||
#include <QtProtobuf/qtprotobufglobal.h>
|
||||
#include <QtProtobuf/qtprotobuftypes.h>
|
||||
#include <QtProtobuf/qprotobufbaseserializer.h>
|
||||
|
||||
#include <QtCore/QMetaObject>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QProtobufJsonSerializerPrivate;
|
||||
class Q_PROTOBUF_EXPORT QProtobufJsonSerializer : public QProtobufBaseSerializer
|
||||
{
|
||||
Q_DISABLE_COPY_MOVE(QProtobufJsonSerializer)
|
||||
|
||||
public:
|
||||
QProtobufJsonSerializer();
|
||||
~QProtobufJsonSerializer() override;
|
||||
|
||||
QAbstractProtobufSerializer::DeserializationError deserializationError() const override;
|
||||
QString deserializationErrorString() const override;
|
||||
|
||||
QByteArray serializeMessage(const QProtobufMessage *message,
|
||||
const QtProtobufPrivate::QProtobufPropertyOrdering &ordering
|
||||
) const override;
|
||||
|
||||
bool deserializeMessage(QProtobufMessage *message,
|
||||
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;
|
||||
|
||||
QByteArray
|
||||
serializeListObject(const QList<const QProtobufMessage *> &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;
|
||||
|
||||
QByteArray
|
||||
serializeMapPair(const QList<QPair<QVariant, QVariant>> &list,
|
||||
const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo
|
||||
) const override;
|
||||
|
||||
QProtobufBaseSerializer::Status
|
||||
deserializeMapPair(QVariant &key, QVariant &value,
|
||||
QtProtobufPrivate::QProtobufSelfcheckIterator &it) const override
|
||||
{
|
||||
Q_UNUSED(key);
|
||||
Q_UNUSED(value);
|
||||
Q_UNUSED(it);
|
||||
return QProtobufBaseSerializer::SerializationError;
|
||||
}
|
||||
|
||||
QByteArray
|
||||
serializeEnum(QtProtobuf::int64 value,
|
||||
const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo) const override
|
||||
{
|
||||
Q_UNUSED(value);
|
||||
Q_UNUSED(fieldInfo);
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
QByteArray
|
||||
serializeEnumList(const QList<QtProtobuf::int64> &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
|
||||
{
|
||||
Q_UNUSED(value);
|
||||
Q_UNUSED(it);
|
||||
return false;
|
||||
}
|
||||
|
||||
Q_REQUIRED_RESULT bool
|
||||
deserializeEnumList(QList<QtProtobuf::int64> &value,
|
||||
QtProtobufPrivate::QProtobufSelfcheckIterator &it) const override
|
||||
{
|
||||
Q_UNUSED(value);
|
||||
Q_UNUSED(it);
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<QProtobufJsonSerializerPrivate> d_ptr;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QPROTOBUFJSONSERIALIZER_H
|
||||
|
||||
|
|
@ -62,8 +62,9 @@ private:
|
|||
|
||||
friend class QProtobufSerializer;
|
||||
friend class QAbstractProtobufSerializer;
|
||||
friend class QProtobufBaseSerializer;
|
||||
friend class QProtobufSerializerPrivate;
|
||||
friend class QAbstractProtobufSerializer;
|
||||
friend class QProtobufJsonSerializerPrivate;
|
||||
friend struct QProtobufMessageDeleter;
|
||||
|
||||
QProtobufMessagePrivate *d_ptr;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include <QtCore/qvariant.h>
|
||||
#include <QtCore/qreadwritelock.h>
|
||||
|
||||
#include <QtProtobuf/qprotobufmessage.h>
|
||||
#include <QtProtobuf/private/qprotobufserializer_p.h>
|
||||
#include <QtProtobuf/private/qprotobufmessage_p.h>
|
||||
|
||||
|
|
@ -99,33 +100,6 @@ QtProtobufPrivate::SerializationHandler QtProtobufPrivate::findHandler(QMetaType
|
|||
If there was no error, an empty string is returned.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\relates QProtobufSerializer
|
||||
\fn template<typename T> inline void qRegisterProtobufType()
|
||||
|
||||
Registers a Protobuf type \e T.
|
||||
This function is normally called by generated code.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\relates QProtobufSerializer
|
||||
\fn template<typename K, typename V> inline void qRegisterProtobufMapType();
|
||||
|
||||
Registers a Protobuf map type \c K and \c V.
|
||||
\c V must be a QProtobufMessage.
|
||||
This function is normally called by generated code.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\relates QProtobufSerializer
|
||||
\fn template<typename T> inline void qRegisterProtobufEnumType();
|
||||
|
||||
Registers serializers for enumeration type \c T in QtProtobuf global
|
||||
serializers registry.
|
||||
|
||||
This function is normally called by generated code.
|
||||
*/
|
||||
|
||||
using namespace Qt::StringLiterals;
|
||||
using namespace QtProtobufPrivate;
|
||||
|
||||
|
|
@ -386,66 +360,81 @@ bool QProtobufSerializer::deserializeObject(QProtobufMessage *message,
|
|||
}
|
||||
|
||||
/*!
|
||||
This function is called to serialize \a message as a part of list property
|
||||
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 QProtobufMessage *message,
|
||||
const QtProtobufPrivate::QProtobufPropertyOrdering &ordering,
|
||||
const QProtobufPropertyOrderingInfo &fieldInfo) const
|
||||
const QList<const QProtobufMessage*> &messageList,
|
||||
const QtProtobufPrivate::QProtobufPropertyOrdering &ordering,
|
||||
const QProtobufPropertyOrderingInfo &fieldInfo) const
|
||||
{
|
||||
return serializeObject(message, ordering, fieldInfo);
|
||||
QByteArray result;
|
||||
for (const auto &message : messageList)
|
||||
result.append(serializeObject(message, ordering, fieldInfo));
|
||||
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 true if deserialization was successful, otherwise \c false.
|
||||
Returns \c Serialized if deserialization was successful,
|
||||
otherwise \c SerializationError.
|
||||
|
||||
You should not call this function directly.
|
||||
*/
|
||||
bool QProtobufSerializer::deserializeListObject(QProtobufMessage *message,
|
||||
QProtobufBaseSerializer::Status QProtobufSerializer::deserializeListObject(QProtobufMessage *message,
|
||||
const QtProtobufPrivate::QProtobufPropertyOrdering &ordering,
|
||||
QProtobufSelfcheckIterator &it) const
|
||||
{
|
||||
return deserializeObject(message, ordering, it);
|
||||
if (deserializeObject(message, ordering, it))
|
||||
return QProtobufBaseSerializer::Serialized;
|
||||
else
|
||||
return QProtobufBaseSerializer::SerializationError;
|
||||
}
|
||||
|
||||
/*!
|
||||
This function serializes QMap pair of \a key and \a value with
|
||||
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 QVariant &key, const QVariant &value,
|
||||
QProtobufSerializer::serializeMapPair(const QList<QPair<QVariant, QVariant>> &list,
|
||||
const QProtobufPropertyOrderingInfo &fieldInfo) const
|
||||
{
|
||||
auto keyHandler = findIntegratedTypeHandler(key.metaType(), false);
|
||||
Q_ASSERT_X(keyHandler, "QProtobufSerializer", "Map key is not an integrated type.");
|
||||
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.");
|
||||
|
||||
QByteArray result = QProtobufSerializerPrivate::encodeHeader(
|
||||
fieldInfo.getFieldNumber(), QtProtobuf::WireTypes::LengthDelimited);
|
||||
result.append(QProtobufSerializerPrivate::encodeHeader(
|
||||
fieldInfo.getFieldNumber(), QtProtobuf::WireTypes::LengthDelimited));
|
||||
|
||||
result.append(QProtobufSerializerPrivate::prependLengthDelimitedSize(
|
||||
result.append(QProtobufSerializerPrivate::prependLengthDelimitedSize(
|
||||
keyHandler->serializer(
|
||||
key, QProtobufSerializerPrivate::encodeHeader(1, keyHandler->wireType))
|
||||
+ d_ptr->serializeProperty(value, fieldInfo.infoForMapValue())));
|
||||
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 true if deserialization was successful, otherwise \c false.
|
||||
Returns \c Serialized if deserialization was successful,
|
||||
otherwise \c SerializationError.
|
||||
|
||||
You should not call this function directly.
|
||||
*/
|
||||
bool QProtobufSerializer::deserializeMapPair(QVariant &key, QVariant &value, QProtobufSelfcheckIterator &it) const
|
||||
QProtobufBaseSerializer::Status QProtobufSerializer::deserializeMapPair(QVariant &key, QVariant &value, QProtobufSelfcheckIterator &it) const
|
||||
{
|
||||
return d_ptr->deserializeMapPair(key, value, it);
|
||||
if (d_ptr->deserializeMapPair(key, value, it))
|
||||
return QProtobufBaseSerializer::Serialized;
|
||||
else
|
||||
return QProtobufBaseSerializer::SerializationError;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -742,10 +731,12 @@ bool QProtobufSerializerPrivate::deserializeProperty(
|
|||
auto handler = QtProtobufPrivate::findHandler(metaType);
|
||||
if (!handler.deserializer) {
|
||||
qProtoWarning() << "No deserializer for type" << metaType.name();
|
||||
QString error
|
||||
= QString::fromUtf8("No deserializer is registered for type %1")
|
||||
.arg(QString::fromUtf8(metaType.name()));
|
||||
setDeserializationError(
|
||||
QAbstractProtobufSerializer::NoDeserializerError,
|
||||
QCoreApplication::translate("QtProtobuf",
|
||||
"No deserializer is registered for type %1"));
|
||||
QCoreApplication::translate("QtProtobuf", error.toUtf8().data()));
|
||||
return false;
|
||||
}
|
||||
handler.deserializer(q_ptr, it, newPropertyValue);
|
||||
|
|
|
|||
|
|
@ -6,15 +6,9 @@
|
|||
#define QPROTOBUFSERIALIZER_H
|
||||
|
||||
#include <QtProtobuf/qtprotobufglobal.h>
|
||||
|
||||
#include <QtProtobuf/qabstractprotobufserializer.h>
|
||||
|
||||
#include <QtProtobuf/qprotobufbaseserializer.h>
|
||||
#include <QtProtobuf/qtprotobuftypes.h>
|
||||
|
||||
#include <QtProtobuf/QProtobufMessage>
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtCore/QMetaObject>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
|
|
@ -24,8 +18,9 @@ namespace QtProtobufPrivate {
|
|||
class QProtobufSelfcheckIterator;
|
||||
} // namespace QtProtobufPrivate
|
||||
|
||||
class QProtobufMessage;
|
||||
class QProtobufSerializerPrivate;
|
||||
class Q_PROTOBUF_EXPORT QProtobufSerializer : public QAbstractProtobufSerializer
|
||||
class Q_PROTOBUF_EXPORT QProtobufSerializer : public QProtobufBaseSerializer
|
||||
{
|
||||
Q_DISABLE_COPY_MOVE(QProtobufSerializer)
|
||||
public:
|
||||
|
|
@ -37,7 +32,8 @@ public:
|
|||
|
||||
QByteArray
|
||||
serializeMessage(const QProtobufMessage *message,
|
||||
const QtProtobufPrivate::QProtobufPropertyOrdering &ordering) const override;
|
||||
const QtProtobufPrivate::QProtobufPropertyOrdering &ordering
|
||||
) const override;
|
||||
bool deserializeMessage(QProtobufMessage *message,
|
||||
const QtProtobufPrivate::QProtobufPropertyOrdering &ordering,
|
||||
QByteArrayView data) const override;
|
||||
|
|
@ -45,311 +41,50 @@ public:
|
|||
QByteArray
|
||||
serializeObject(const QProtobufMessage *message,
|
||||
const QtProtobufPrivate::QProtobufPropertyOrdering &ordering,
|
||||
const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo) const;
|
||||
const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo
|
||||
) const override;
|
||||
bool deserializeObject(QProtobufMessage *message,
|
||||
const QtProtobufPrivate::QProtobufPropertyOrdering &ordering,
|
||||
QtProtobufPrivate::QProtobufSelfcheckIterator &it) const;
|
||||
QtProtobufPrivate::QProtobufSelfcheckIterator &it) const override;
|
||||
|
||||
QByteArray
|
||||
serializeListObject(const QProtobufMessage *message,
|
||||
serializeListObject(const QList<const QProtobufMessage *> &messageList,
|
||||
const QtProtobufPrivate::QProtobufPropertyOrdering &ordering,
|
||||
const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo) const;
|
||||
bool deserializeListObject(QProtobufMessage *message,
|
||||
const QtProtobufPrivate::QProtobufPropertyOrdering &ordering,
|
||||
QtProtobufPrivate::QProtobufSelfcheckIterator &it) const;
|
||||
const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo
|
||||
) const override;
|
||||
QProtobufBaseSerializer::Status deserializeListObject(QProtobufMessage *message,
|
||||
const QtProtobufPrivate::QProtobufPropertyOrdering &ordering,
|
||||
QtProtobufPrivate::QProtobufSelfcheckIterator &it
|
||||
) const override;
|
||||
|
||||
QByteArray
|
||||
serializeMapPair(const QVariant &key, const QVariant &value,
|
||||
const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo) const;
|
||||
bool deserializeMapPair(QVariant &key, QVariant &value,
|
||||
QtProtobufPrivate::QProtobufSelfcheckIterator &it) const;
|
||||
serializeMapPair(const QList<QPair<QVariant, QVariant> > &list,
|
||||
const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo
|
||||
) const override;
|
||||
QProtobufBaseSerializer::Status deserializeMapPair(QVariant &key, QVariant &value,
|
||||
QtProtobufPrivate::QProtobufSelfcheckIterator &it
|
||||
) const override;
|
||||
|
||||
QByteArray
|
||||
serializeEnum(QtProtobuf::int64 value,
|
||||
const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo) const;
|
||||
const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo
|
||||
) const override;
|
||||
QByteArray
|
||||
serializeEnumList(const QList<QtProtobuf::int64> &value,
|
||||
const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo) const;
|
||||
const QtProtobufPrivate::QProtobufPropertyOrderingInfo &fieldInfo
|
||||
) const override;
|
||||
|
||||
Q_REQUIRED_RESULT
|
||||
bool deserializeEnum(QtProtobuf::int64 &value,
|
||||
QtProtobufPrivate::QProtobufSelfcheckIterator &it) const;
|
||||
Q_REQUIRED_RESULT
|
||||
bool deserializeEnumList(QList<QtProtobuf::int64> &value,
|
||||
QtProtobufPrivate::QProtobufSelfcheckIterator &it) const;
|
||||
QtProtobufPrivate::QProtobufSelfcheckIterator &it) const override;
|
||||
Q_REQUIRED_RESULT bool
|
||||
deserializeEnumList(QList<QtProtobuf::int64> &value,
|
||||
QtProtobufPrivate::QProtobufSelfcheckIterator &it) const override;
|
||||
|
||||
void shouldPreserveUnknownFields(bool preserveUnknownFields);
|
||||
private:
|
||||
std::unique_ptr<QProtobufSerializerPrivate> d_ptr;
|
||||
};
|
||||
|
||||
namespace QtProtobufPrivate {
|
||||
|
||||
using Serializer = void (*)(const QProtobufSerializer *, const QVariant &,
|
||||
const QProtobufPropertyOrderingInfo &, QByteArray &);
|
||||
using Deserializer = void (*)(const QProtobufSerializer *, QProtobufSelfcheckIterator &,
|
||||
QVariant &);
|
||||
|
||||
/*!
|
||||
\private
|
||||
\brief SerializationHandlers contains set of objects that required for class
|
||||
serialization/deserialization
|
||||
*/
|
||||
struct SerializationHandler
|
||||
{
|
||||
Serializer serializer = nullptr; /*!< serializer assigned to class */
|
||||
Deserializer deserializer = nullptr; /*!< deserializer assigned to class */
|
||||
};
|
||||
|
||||
extern Q_PROTOBUF_EXPORT SerializationHandler findHandler(QMetaType type);
|
||||
extern Q_PROTOBUF_EXPORT void registerHandler(QMetaType type, const SerializationHandler &handlers);
|
||||
|
||||
/*!
|
||||
\private
|
||||
\brief default serializer template for type T that inherits from QProtobufMessage
|
||||
*/
|
||||
template<typename T,
|
||||
typename std::enable_if_t<std::is_base_of<QProtobufMessage, T>::value, int> = 0>
|
||||
void serializeObject(const QProtobufSerializer *serializer, const QVariant &value,
|
||||
const QProtobufPropertyOrderingInfo &fieldInfo, QByteArray &buffer)
|
||||
{
|
||||
Q_ASSERT_X(serializer != nullptr, "QProtobufSerializer", "Serializer is null");
|
||||
buffer.append(serializer->serializeObject(value.value<T *>(), T::propertyOrdering, fieldInfo));
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
\brief default serializer template for list of type T objects that inherits from QProtobufMessage
|
||||
*/
|
||||
template<typename V,
|
||||
typename std::enable_if_t<std::is_base_of<QProtobufMessage, V>::value, int> = 0>
|
||||
void serializeList(const QProtobufSerializer *serializer, const QVariant &listValue,
|
||||
const QProtobufPropertyOrderingInfo &fieldInfo, QByteArray &buffer)
|
||||
{
|
||||
Q_ASSERT_X(serializer != nullptr, "QProtobufSerializer", "Serializer is null");
|
||||
for (const auto &value : listValue.value<QList<V>>()) {
|
||||
buffer.append(serializer->serializeListObject(&value, V::propertyOrdering, fieldInfo));
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
\brief default serializer template for map of key K, value V
|
||||
*/
|
||||
template<typename K, typename V,
|
||||
typename std::enable_if_t<!std::is_base_of<QProtobufMessage, V>::value, int> = 0>
|
||||
void serializeMap(const QProtobufSerializer *serializer, const QVariant &value,
|
||||
const QProtobufPropertyOrderingInfo &fieldInfo, QByteArray &buffer)
|
||||
{
|
||||
Q_ASSERT_X(serializer != nullptr, "QProtobufSerializer", "Serializer is null");
|
||||
for (const auto &[k, v] : value.value<QHash<K, V>>().asKeyValueRange()) {
|
||||
buffer.append(serializer->serializeMapPair(QVariant::fromValue<K>(k),
|
||||
QVariant::fromValue<V>(v), fieldInfo));
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
\brief default serializer template for map of type key K, value V. Specialization for V that
|
||||
inherits from QProtobufMessage
|
||||
*/
|
||||
template<typename K, typename V,
|
||||
typename std::enable_if_t<std::is_base_of<QProtobufMessage, V>::value, int> = 0>
|
||||
void serializeMap(const QProtobufSerializer *serializer, const QVariant &value,
|
||||
const QProtobufPropertyOrderingInfo &fieldInfo, QByteArray &buffer)
|
||||
{
|
||||
Q_ASSERT_X(serializer != nullptr, "QProtobufSerializer", "Serializer is null");
|
||||
for (const auto &[k, v] : value.value<QHash<K, V>>().asKeyValueRange()) {
|
||||
buffer.append(serializer->serializeMapPair(QVariant::fromValue<K>(k),
|
||||
QVariant::fromValue<V *>(&v), fieldInfo));
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
\brief default serializer template for enum types
|
||||
*/
|
||||
template<typename T, typename std::enable_if_t<std::is_enum<T>::value, int> = 0>
|
||||
void serializeEnum(const QProtobufSerializer *serializer, const QVariant &value,
|
||||
const QProtobufPropertyOrderingInfo &fieldInfo, QByteArray &buffer)
|
||||
{
|
||||
Q_ASSERT_X(serializer != nullptr, "QProtobufSerializer", "Serializer is null");
|
||||
buffer.append(serializer->serializeEnum(QtProtobuf::int64(value.value<T>()), fieldInfo));
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
\brief default serializer template for enum list types
|
||||
*/
|
||||
template<typename T, typename std::enable_if_t<std::is_enum<T>::value, int> = 0>
|
||||
void serializeEnumList(const QProtobufSerializer *serializer, const QVariant &value,
|
||||
const QProtobufPropertyOrderingInfo &fieldInfo, QByteArray &buffer)
|
||||
{
|
||||
Q_ASSERT_X(serializer != nullptr, "QProtobufSerializer", "Serializer is null");
|
||||
QList<QtProtobuf::int64> intList;
|
||||
for (auto enumValue : value.value<QList<T>>()) {
|
||||
intList.append(QtProtobuf::int64(enumValue));
|
||||
}
|
||||
buffer.append(serializer->serializeEnumList(intList, fieldInfo));
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
\brief default deserializer template for type T that inherits from QProtobufMessage
|
||||
*/
|
||||
template<typename T,
|
||||
typename std::enable_if_t<std::is_base_of<QProtobufMessage, T>::value, int> = 0>
|
||||
void deserializeObject(const QProtobufSerializer *serializer, QProtobufSelfcheckIterator &it,
|
||||
QVariant &to)
|
||||
{
|
||||
Q_ASSERT_X(serializer != nullptr, "QProtobufSerializer", "Serializer is null");
|
||||
Q_ASSERT_X(to.isNull() || to.metaType() == QMetaType::fromType<T *>(), "QProtobufSerializer",
|
||||
"Property should be either uninitialized or contain a valid pointer");
|
||||
|
||||
T *value = to.value<T *>();
|
||||
if (value == nullptr) {
|
||||
value = new T;
|
||||
to = QVariant::fromValue<T *>(value);
|
||||
}
|
||||
serializer->deserializeObject(value, T::propertyOrdering, it);
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
\brief default deserializer template for list of type T objects that inherits from QProtobufMessage
|
||||
*/
|
||||
template<typename V,
|
||||
typename std::enable_if_t<std::is_base_of<QProtobufMessage, V>::value, int> = 0>
|
||||
void deserializeList(const QProtobufSerializer *serializer, QProtobufSelfcheckIterator &it,
|
||||
QVariant &previous)
|
||||
{
|
||||
Q_ASSERT_X(serializer != nullptr, "QProtobufSerializer", "Serializer is null");
|
||||
|
||||
V newValue;
|
||||
if (serializer->deserializeListObject(&newValue, V::propertyOrdering, it)) {
|
||||
QList<V> list = previous.value<QList<V>>();
|
||||
list.append(newValue);
|
||||
previous.setValue(list);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
*
|
||||
\brief default deserializer template for map of key K, value V
|
||||
*/
|
||||
template<typename K, typename V,
|
||||
typename std::enable_if_t<!std::is_base_of<QProtobufMessage, V>::value, int> = 0>
|
||||
void deserializeMap(const QProtobufSerializer *serializer, QProtobufSelfcheckIterator &it,
|
||||
QVariant &previous)
|
||||
{
|
||||
Q_ASSERT_X(serializer != nullptr, "QProtobufSerializer", "Serializer is null");
|
||||
|
||||
QHash<K, V> out = previous.value<QHash<K, V>>();
|
||||
QVariant key = QVariant::fromValue<K>(K());
|
||||
QVariant value = QVariant::fromValue<V>(V());
|
||||
|
||||
if (serializer->deserializeMapPair(key, value, it)) {
|
||||
out[key.value<K>()] = value.value<V>();
|
||||
previous = QVariant::fromValue<QHash<K, V>>(out);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
*
|
||||
\brief default deserializer template for map of type key K, value V. Specialization for V
|
||||
that inherits from QProtobufMessage
|
||||
*/
|
||||
template<typename K, typename V,
|
||||
typename std::enable_if_t<std::is_base_of<QProtobufMessage, V>::value, int> = 0>
|
||||
void deserializeMap(const QProtobufSerializer *serializer, QProtobufSelfcheckIterator &it,
|
||||
QVariant &previous)
|
||||
{
|
||||
Q_ASSERT_X(serializer != nullptr, "QProtobufSerializer", "Serializer is null");
|
||||
|
||||
auto out = previous.value<QHash<K, V>>();
|
||||
QVariant key = QVariant::fromValue<K>(K());
|
||||
QVariant value = QVariant::fromValue<V *>(nullptr);
|
||||
|
||||
if (serializer->deserializeMapPair(key, value, it)) {
|
||||
const auto valuePtr = value.value<V *>();
|
||||
out[key.value<K>()] = valuePtr ? *valuePtr : V();
|
||||
previous = QVariant::fromValue<QHash<K, V>>(out);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
*
|
||||
\brief default deserializer template for enum type T
|
||||
*/
|
||||
template<typename T, typename std::enable_if_t<std::is_enum<T>::value, int> = 0>
|
||||
void deserializeEnum(const QProtobufSerializer *serializer, QProtobufSelfcheckIterator &it,
|
||||
QVariant &to)
|
||||
{
|
||||
Q_ASSERT_X(serializer != nullptr, "QProtobufSerializer", "Serializer is null");
|
||||
QtProtobuf::int64 intValue;
|
||||
if (serializer->deserializeEnum(intValue, it))
|
||||
to = QVariant::fromValue<T>(static_cast<T>(intValue._t));
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
*
|
||||
\brief default deserializer template for enumList type T
|
||||
*/
|
||||
template<typename T, typename std::enable_if_t<std::is_enum<T>::value, int> = 0>
|
||||
void deserializeEnumList(const QProtobufSerializer *serializer, QProtobufSelfcheckIterator &it,
|
||||
QVariant &previous)
|
||||
{
|
||||
Q_ASSERT_X(serializer != nullptr, "QProtobufSerializer", "Serializer is null");
|
||||
QList<QtProtobuf::int64> intList;
|
||||
if (!serializer->deserializeEnumList(intList, it))
|
||||
return;
|
||||
QList<T> enumList = previous.value<QList<T>>();
|
||||
for (auto intValue : intList)
|
||||
enumList.append(static_cast<T>(intValue._t));
|
||||
previous = QVariant::fromValue<QList<T>>(enumList);
|
||||
}
|
||||
} // namespace QtProtobufPrivate
|
||||
|
||||
template<typename T>
|
||||
inline void qRegisterProtobufType()
|
||||
{
|
||||
T::registerTypes();
|
||||
QtProtobufPrivate::registerOrdering(QMetaType::fromType<T>(), T::propertyOrdering);
|
||||
QtProtobufPrivate::registerHandler(
|
||||
QMetaType::fromType<T *>(),
|
||||
{ QtProtobufPrivate::serializeObject<T>, QtProtobufPrivate::deserializeObject<T> });
|
||||
QtProtobufPrivate::registerHandler(
|
||||
QMetaType::fromType<QList<T>>(),
|
||||
{ QtProtobufPrivate::serializeList<T>, QtProtobufPrivate::deserializeList<T> });
|
||||
}
|
||||
|
||||
template<typename K, typename V>
|
||||
inline void qRegisterProtobufMapType()
|
||||
{
|
||||
QtProtobufPrivate::registerHandler(
|
||||
QMetaType::fromType<QHash<K, V>>(),
|
||||
{ QtProtobufPrivate::serializeMap<K, V>, QtProtobufPrivate::deserializeMap<K, V> });
|
||||
}
|
||||
|
||||
#ifdef Q_QDOC
|
||||
template<typename T>
|
||||
inline void qRegisterProtobufEnumType();
|
||||
#else // !Q_QDOC
|
||||
template<typename T, typename std::enable_if_t<std::is_enum<T>::value, int> = 0>
|
||||
inline void qRegisterProtobufEnumType()
|
||||
{
|
||||
QtProtobufPrivate::registerHandler(
|
||||
QMetaType::fromType<T>(),
|
||||
{ QtProtobufPrivate::serializeEnum<T>, QtProtobufPrivate::deserializeEnum<T> });
|
||||
QtProtobufPrivate::registerHandler(
|
||||
QMetaType::fromType<QList<T>>(),
|
||||
{ QtProtobufPrivate::serializeEnumList<T>, QtProtobufPrivate::deserializeEnumList<T> });
|
||||
}
|
||||
#endif // Q_QDOC
|
||||
|
||||
QT_END_NAMESPACE
|
||||
#endif // QPROTOBUFSERIALIZER_H
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ void registerQtTypeHandler()
|
|||
{
|
||||
registerHandler(
|
||||
QMetaType::fromType<QType>(),
|
||||
{ [](const QProtobufSerializer *serializer, const QVariant &value,
|
||||
{ [](const QProtobufBaseSerializer *serializer, const QVariant &value,
|
||||
const QProtobufPropertyOrderingInfo &info, QByteArray &buffer) {
|
||||
auto do_convert = [](const QType &qtype) {
|
||||
auto res = convert(qtype);
|
||||
|
|
@ -60,7 +60,7 @@ void registerQtTypeHandler()
|
|||
warnTypeConversionError();
|
||||
}
|
||||
},
|
||||
[](const QProtobufSerializer *serializer, QProtobufSelfcheckIterator &it,
|
||||
[](const QProtobufBaseSerializer *serializer, QProtobufSelfcheckIterator &it,
|
||||
QVariant &value) {
|
||||
PType object;
|
||||
serializer->deserializeObject(&object, PType::propertyOrdering, it);
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ public:
|
|||
static AnyPrivate *get(const Any *any) { return any->d_ptr; }
|
||||
};
|
||||
|
||||
static void serializerProxy(const QProtobufSerializer *serializer, const QVariant &object,
|
||||
static void serializerProxy(const QProtobufBaseSerializer *serializer, const QVariant &object,
|
||||
const QProtobufPropertyOrderingInfo &fieldInfo, QByteArray &output)
|
||||
{
|
||||
if (object.isNull())
|
||||
|
|
@ -41,20 +41,31 @@ static void serializerProxy(const QProtobufSerializer *serializer, const QVarian
|
|||
fieldInfo));
|
||||
}
|
||||
|
||||
static void listSerializerProxy(const QProtobufSerializer *serializer, const QVariant &object,
|
||||
const QProtobufPropertyOrderingInfo &fieldInfo, QByteArray &output)
|
||||
static void listSerializerProxy(const QProtobufBaseSerializer *serializer,
|
||||
const QVariant &object,
|
||||
const QProtobufPropertyOrderingInfo &fieldInfo,
|
||||
QByteArray &output)
|
||||
{
|
||||
const auto anyList = object.value<QList<Any>>();
|
||||
const QList<Any> anyList = object.value<QList<Any>>();
|
||||
QList<const QProtobufMessage*> msgList;
|
||||
msgList.reserve(anyList.size());
|
||||
QList<google::protobuf::Any> msgAny;
|
||||
msgAny.reserve(anyList.size());
|
||||
for (const Any &any : anyList) {
|
||||
google::protobuf::Any realAny;
|
||||
realAny.setValue(any.value());
|
||||
realAny.setTypeUrl(any.typeUrl());
|
||||
output.append(serializer->serializeListObject(&realAny,
|
||||
google::protobuf::Any::propertyOrdering, fieldInfo));
|
||||
msgAny.append(realAny);
|
||||
}
|
||||
for (const google::protobuf::Any &any : msgAny) {
|
||||
msgList.append(&any);
|
||||
}
|
||||
output.append(serializer->serializeListObject(msgList,
|
||||
google::protobuf::Any::propertyOrdering,
|
||||
fieldInfo));
|
||||
}
|
||||
|
||||
static void listDeserializerProxy(const QProtobufSerializer *deserializer,
|
||||
static void listDeserializerProxy(const QProtobufBaseSerializer *deserializer,
|
||||
QProtobufSelfcheckIterator &it, QVariant &object)
|
||||
{
|
||||
auto anyList = object.value<QList<Any>>();
|
||||
|
|
@ -71,7 +82,7 @@ static void listDeserializerProxy(const QProtobufSerializer *deserializer,
|
|||
object.setValue(std::move(anyList));
|
||||
}
|
||||
|
||||
static void deserializerProxy(const QProtobufSerializer *deserializer,
|
||||
static void deserializerProxy(const QProtobufBaseSerializer *deserializer,
|
||||
QProtobufSelfcheckIterator &it, QVariant &object)
|
||||
{
|
||||
google::protobuf::Any realAny;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ if(TARGET Qt6::qtprotobufgen)
|
|||
get_target_property(protoc_version WrapProtoc::WrapProtoc _qt_internal_protobuf_version)
|
||||
|
||||
add_subdirectory(basic)
|
||||
add_subdirectory(jsontypes)
|
||||
add_subdirectory(syntax)
|
||||
add_subdirectory(nopackage)
|
||||
add_subdirectory(enums)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
[RepeatedComplexMessageTest]
|
||||
macos
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
# Copyright (C) 2023 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(tst_protobuf_json_basic LANGUAGES CXX)
|
||||
find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
|
||||
endif()
|
||||
|
||||
qt6_add_protobuf(tst_protobuf_json_basic_types_gen
|
||||
PROTO_FILES
|
||||
../basic/proto/basicmessages.proto
|
||||
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/qt_protobuf_generated"
|
||||
)
|
||||
qt_autogen_tools_initial_setup(tst_protobuf_json_basic_types_gen)
|
||||
|
||||
qt_internal_add_test(tst_protobuf_json_basic_types
|
||||
SOURCES
|
||||
tst_protobuf_serialization_json_basictypes.cpp
|
||||
LIBRARIES
|
||||
Qt::Test
|
||||
Qt::Protobuf
|
||||
tst_protobuf_json_basic_types_gen
|
||||
)
|
||||
|
||||
qt_internal_add_test(tst_protobuf_deserialization_json_basictypes
|
||||
SOURCES
|
||||
tst_protobuf_deserialization_json_basictypes.cpp
|
||||
LIBRARIES
|
||||
Qt::Test
|
||||
Qt::Protobuf
|
||||
tst_protobuf_json_basic_types_gen
|
||||
)
|
||||
|
||||
qt6_add_protobuf(tst_protobuf_json_repeatedtypes_gen
|
||||
PROTO_FILES
|
||||
../basic/proto/repeatedmessages.proto
|
||||
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/qt_protobuf_generated"
|
||||
)
|
||||
target_link_libraries(tst_protobuf_json_repeatedtypes_gen
|
||||
PUBLIC
|
||||
tst_protobuf_json_basic_types_gen
|
||||
)
|
||||
qt_autogen_tools_initial_setup(tst_protobuf_json_repeatedtypes_gen)
|
||||
|
||||
qt_internal_add_test(tst_protobuf_serialization_json_repeatedtypes
|
||||
SOURCES
|
||||
tst_protobuf_serialization_json_repeatedtypes.cpp
|
||||
LIBRARIES
|
||||
Qt::Test
|
||||
Qt::Protobuf
|
||||
tst_protobuf_json_basic_types_gen
|
||||
tst_protobuf_json_repeatedtypes_gen
|
||||
)
|
||||
|
||||
qt_internal_add_test(tst_protobuf_deserialization_json_repeatedtypes
|
||||
SOURCES
|
||||
tst_protobuf_deserialization_json_repeatedtypes.cpp
|
||||
LIBRARIES
|
||||
Qt::Test
|
||||
Qt::Protobuf
|
||||
tst_protobuf_json_basic_types_gen
|
||||
tst_protobuf_json_repeatedtypes_gen
|
||||
)
|
||||
|
||||
qt6_add_protobuf(tst_protobuf_json_maptypes_gen
|
||||
PROTO_FILES
|
||||
../basic/proto/mapmessages.proto
|
||||
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/qt_protobuf_generated"
|
||||
)
|
||||
if(MINGW)
|
||||
target_compile_options(tst_protobuf_json_maptypes_gen PRIVATE "-Wa,-mbig-obj")
|
||||
endif()
|
||||
|
||||
qt_autogen_tools_initial_setup(tst_protobuf_json_maptypes_gen)
|
||||
|
||||
target_link_libraries(tst_protobuf_json_maptypes_gen
|
||||
PUBLIC
|
||||
tst_protobuf_json_basic_types_gen
|
||||
)
|
||||
|
||||
qt_internal_add_test(tst_protobuf_serialization_json_maptypes
|
||||
SOURCES
|
||||
tst_protobuf_serialization_json_maptypes.cpp
|
||||
INCLUDE_DIRECTORIES
|
||||
../shared
|
||||
LIBRARIES
|
||||
Qt::Test
|
||||
Qt::Protobuf
|
||||
tst_protobuf_json_basic_types_gen
|
||||
tst_protobuf_json_maptypes_gen
|
||||
)
|
||||
|
|
@ -0,0 +1,494 @@
|
|||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "basicmessages.qpb.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QProtobufJsonSerializer>
|
||||
#include <QTest>
|
||||
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
class QtProtobufTypesJsonDeserializationTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void init() { qRegisterProtobufTypes(); serializer.reset(new QProtobufJsonSerializer); }
|
||||
|
||||
void BoolMessageDeserializeTest_data();
|
||||
void BoolMessageDeserializeTest();
|
||||
void IntMessageDeserializeTest_data();
|
||||
void IntMessageDeserializeTest();
|
||||
void UIntMessageDeserializeTest_data();
|
||||
void UIntMessageDeserializeTest();
|
||||
void SIntMessageDeserializeTest_data();
|
||||
void SIntMessageDeserializeTest();
|
||||
void Int64MessageDeserializeTest_data();
|
||||
void Int64MessageDeserializeTest();
|
||||
void UInt64MessageDeserializeTest_data();
|
||||
void UInt64MessageDeserializeTest();
|
||||
void SInt64MessageDeserializeTest_data();
|
||||
void SInt64MessageDeserializeTest();
|
||||
void FixedInt32MessageDeserializeTest_data();
|
||||
void FixedInt32MessageDeserializeTest();
|
||||
void FixedInt64MessageDeserializeTest_data();
|
||||
void FixedInt64MessageDeserializeTest();
|
||||
void SFixedInt32MessageDeserializeTest_data();
|
||||
void SFixedInt32MessageDeserializeTest();
|
||||
void SFixedInt64MessageDeserializeTest_data();
|
||||
void SFixedInt64MessageDeserializeTest();
|
||||
void FloatMessageDeserializeTest_data();
|
||||
void FloatMessageDeserializeTest();
|
||||
void DoubleMessageDeserializeTest_data();
|
||||
void DoubleMessageDeserializeTest();
|
||||
void StringMessageDeserializeTest();
|
||||
void ComplexTypeDeserializeTest_data();
|
||||
void ComplexTypeDeserializeTest();
|
||||
void ResetComplexTypeDeserializeTest_data();
|
||||
void ResetComplexTypeDeserializeTest();
|
||||
void DefaultConstructedComplexTypeDeserializeTest();
|
||||
void EmptyBytesMessageTest();
|
||||
void EmptyStringMessageTest();
|
||||
|
||||
private:
|
||||
std::unique_ptr<QProtobufJsonSerializer> serializer;
|
||||
};
|
||||
|
||||
using namespace qtprotobufnamespace::tests;
|
||||
|
||||
void QtProtobufTypesJsonDeserializationTest::BoolMessageDeserializeTest_data()
|
||||
{
|
||||
QTest::addColumn<bool>("value");
|
||||
QTest::addColumn<QByteArray>("serializeData");
|
||||
|
||||
QTest::newRow("True") << true << "{\"testFieldBool\":true}"_ba;
|
||||
QTest::newRow("False") << false << "{\"testFieldBool\":false}"_ba;
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonDeserializationTest::BoolMessageDeserializeTest()
|
||||
{
|
||||
QFETCH(const bool, value);
|
||||
QFETCH(const QByteArray, serializeData);
|
||||
|
||||
SimpleBoolMessage test;
|
||||
test.deserialize(serializer.get(), serializeData);
|
||||
QCOMPARE(test.testFieldBool(), value);
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonDeserializationTest::IntMessageDeserializeTest_data()
|
||||
{
|
||||
QTest::addColumn<int32_t>("value");
|
||||
QTest::addColumn<QByteArray>("serializeData");
|
||||
|
||||
QTest::newRow("555") << 555 << "{\"testFieldInt\":555}"_ba;
|
||||
QTest::newRow("0") << 0 << "{\"testFieldInt\":0}"_ba;
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonDeserializationTest::IntMessageDeserializeTest()
|
||||
{
|
||||
QFETCH(const int32_t, value);
|
||||
QFETCH(const QByteArray, serializeData);
|
||||
|
||||
SimpleIntMessage test;
|
||||
test.deserialize(serializer.get(), serializeData);
|
||||
QCOMPARE(test.testFieldInt(), value);
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonDeserializationTest::UIntMessageDeserializeTest_data()
|
||||
{
|
||||
QTest::addColumn<uint32_t>("value");
|
||||
QTest::addColumn<QByteArray>("serializeData");
|
||||
|
||||
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 QtProtobufTypesJsonDeserializationTest::UIntMessageDeserializeTest()
|
||||
{
|
||||
QFETCH(const uint32_t, value);
|
||||
QFETCH(const QByteArray, serializeData);
|
||||
|
||||
SimpleUIntMessage test;
|
||||
test.deserialize(serializer.get(), serializeData);
|
||||
QCOMPARE(test.testFieldInt(), value);
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonDeserializationTest::SIntMessageDeserializeTest_data()
|
||||
{
|
||||
QTest::addColumn<int32_t>("value");
|
||||
QTest::addColumn<QByteArray>("serializeData");
|
||||
|
||||
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 << "{\"testFieldInt\":-1}"_ba;
|
||||
QTest::newRow("-462") << (int32_t)-462 << "{\"testFieldInt\":-462}"_ba;
|
||||
QTest::newRow("-63585") << (int32_t)-63585 << "{\"testFieldInt\":-63585}"_ba;
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonDeserializationTest::SIntMessageDeserializeTest()
|
||||
{
|
||||
QFETCH(const int32_t, value);
|
||||
QFETCH(const QByteArray, serializeData);
|
||||
|
||||
SimpleSIntMessage test;
|
||||
test.deserialize(serializer.get(), serializeData);
|
||||
QCOMPARE(test.testFieldInt(), value);
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonDeserializationTest::Int64MessageDeserializeTest_data()
|
||||
{
|
||||
QTest::addColumn<int64_t>("value");
|
||||
QTest::addColumn<QByteArray>("serializeData");
|
||||
|
||||
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 << "{\"testFieldInt\":-1}"_ba;
|
||||
QTest::newRow("-462") << (int64_t)-462 << "{\"testFieldInt\":-462}"_ba;
|
||||
QTest::newRow("-63585") << (int64_t)-63585 << "{\"testFieldInt\":-63585}"_ba;
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonDeserializationTest::Int64MessageDeserializeTest()
|
||||
{
|
||||
QFETCH(const int64_t, value);
|
||||
QFETCH(const QByteArray, serializeData);
|
||||
|
||||
SimpleInt64Message test;
|
||||
test.deserialize(serializer.get(), serializeData);
|
||||
QCOMPARE(test.testFieldInt(), value);
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonDeserializationTest::UInt64MessageDeserializeTest_data()
|
||||
{
|
||||
QTest::addColumn<uint64_t>("value");
|
||||
QTest::addColumn<QByteArray>("serializeData");
|
||||
|
||||
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 QtProtobufTypesJsonDeserializationTest::UInt64MessageDeserializeTest()
|
||||
{
|
||||
QFETCH(const QtProtobuf::uint64, value);
|
||||
QFETCH(const QByteArray, serializeData);
|
||||
|
||||
SimpleUInt64Message test;
|
||||
test.deserialize(serializer.get(), serializeData);
|
||||
QCOMPARE(test.testFieldInt(), value);
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonDeserializationTest::SInt64MessageDeserializeTest_data()
|
||||
{
|
||||
QTest::addColumn<int64_t>("value");
|
||||
QTest::addColumn<QByteArray>("serializeData");
|
||||
|
||||
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 << "{\"testFieldInt\":-1}"_ba;
|
||||
QTest::newRow("-462") << (int64_t)-462 << "{\"testFieldInt\":-462}"_ba;
|
||||
QTest::newRow("-63585") << (int64_t)-63585 << "{\"testFieldInt\":-63585}"_ba;
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonDeserializationTest::SInt64MessageDeserializeTest()
|
||||
{
|
||||
QFETCH(const int64_t, value);
|
||||
QFETCH(const QByteArray, serializeData);
|
||||
|
||||
SimpleSInt64Message test;
|
||||
test.deserialize(serializer.get(), serializeData);
|
||||
QCOMPARE(test.testFieldInt(), value);
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonDeserializationTest::FixedInt32MessageDeserializeTest_data()
|
||||
{
|
||||
QTest::addColumn<uint32_t>("value");
|
||||
QTest::addColumn<QByteArray>("serializeData");
|
||||
|
||||
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;
|
||||
|
||||
QTest::newRow("5") << (uint32_t)5 << "{\"testFieldFixedInt32\": 5}"_ba;
|
||||
QTest::newRow("0") << (uint32_t)0 << "{\"testFieldFixedInt32\": 0}"_ba;
|
||||
QTest::newRow("555") << (uint32_t)555 << "{\"testFieldFixedInt32\":555}"_ba;
|
||||
QTest::newRow("nullptr") << (uint32_t)0 << "{\"testFieldFixedInt32\":null}"_ba;
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonDeserializationTest::FixedInt32MessageDeserializeTest()
|
||||
{
|
||||
QFETCH(const uint32_t, value);
|
||||
QFETCH(const QByteArray, serializeData);
|
||||
|
||||
SimpleFixedInt32Message test;
|
||||
test.deserialize(serializer.get(), serializeData);
|
||||
QCOMPARE(test.testFieldFixedInt32(), value);
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonDeserializationTest::FixedInt64MessageDeserializeTest_data()
|
||||
{
|
||||
QTest::addColumn<uint64_t>("value");
|
||||
QTest::addColumn<QByteArray>("serializeData");
|
||||
|
||||
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 QtProtobufTypesJsonDeserializationTest::FixedInt64MessageDeserializeTest()
|
||||
{
|
||||
QFETCH(const uint64_t, value);
|
||||
QFETCH(const QByteArray, serializeData);
|
||||
|
||||
SimpleFixedInt64Message test;
|
||||
test.deserialize(serializer.get(), serializeData);
|
||||
QCOMPARE(test.testFieldFixedInt64(), value);
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonDeserializationTest::SFixedInt32MessageDeserializeTest_data()
|
||||
{
|
||||
QTest::addColumn<int32_t>("value");
|
||||
QTest::addColumn<QByteArray>("serializeData");
|
||||
|
||||
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 << "{\"testFieldFixedInt32\":-1}"_ba;
|
||||
QTest::newRow("-462") << (int32_t)-462 << "{\"testFieldFixedInt32\":-462}"_ba;
|
||||
QTest::newRow("-63585") << (int32_t)-63585 << "{\"testFieldFixedInt32\":-63585}"_ba;
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonDeserializationTest::SFixedInt32MessageDeserializeTest()
|
||||
{
|
||||
QFETCH(const int32_t, value);
|
||||
QFETCH(const QByteArray, serializeData);
|
||||
|
||||
SimpleSFixedInt32Message test;
|
||||
test.deserialize(serializer.get(), serializeData);
|
||||
QCOMPARE(test.testFieldFixedInt32(), value);
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonDeserializationTest::SFixedInt64MessageDeserializeTest_data()
|
||||
{
|
||||
QTest::addColumn<int64_t>("value");
|
||||
QTest::addColumn<QByteArray>("serializeData");
|
||||
|
||||
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 << "{\"testFieldFixedInt64\":-1}"_ba;
|
||||
QTest::newRow("-462") << (int64_t)-462 << "{\"testFieldFixedInt64\":-462}"_ba;
|
||||
QTest::newRow("-63585") << (int64_t)-63585 << "{\"testFieldFixedInt64\":-63585}"_ba;
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonDeserializationTest::SFixedInt64MessageDeserializeTest()
|
||||
{
|
||||
QFETCH(const int64_t, value);
|
||||
QFETCH(const QByteArray, serializeData);
|
||||
|
||||
SimpleSFixedInt64Message test;
|
||||
test.deserialize(serializer.get(), serializeData);
|
||||
QCOMPARE(test.testFieldFixedInt64(), value);
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonDeserializationTest::FloatMessageDeserializeTest_data()
|
||||
{
|
||||
QTest::addColumn<float>("value");
|
||||
QTest::addColumn<QByteArray>("serializeData");
|
||||
|
||||
QTest::newRow("float_value_0_1") << 0.1f << "{\"testFieldFloat\":0.1}"_ba;
|
||||
QTest::newRow("float_value_min") << std::numeric_limits<float>::min()
|
||||
<< "{\"testFieldFloat\":1.17549e-38}"_ba;
|
||||
QTest::newRow("float_value_max") << std::numeric_limits<float>::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 QtProtobufTypesJsonDeserializationTest::FloatMessageDeserializeTest()
|
||||
{
|
||||
QFETCH(const float, value);
|
||||
QFETCH(const QByteArray, serializeData);
|
||||
|
||||
SimpleFloatMessage test;
|
||||
test.setTestFieldFloat(value);
|
||||
test.deserialize(serializer.get(), serializeData);
|
||||
QCOMPARE(test.testFieldFloat(), value);
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonDeserializationTest::DoubleMessageDeserializeTest_data()
|
||||
{
|
||||
QTest::addColumn<double>("value");
|
||||
QTest::addColumn<QByteArray>("serializeData");
|
||||
|
||||
QTest::newRow("double_value_0_1") << 0.1 << "{\"testFieldDouble\":0.1}"_ba;
|
||||
QTest::newRow("double_value_min")
|
||||
<< std::numeric_limits<double>::min()
|
||||
<< "{\"testFieldDouble\":2.2250738585072014e-308}"_ba;
|
||||
QTest::newRow("double_value_max")
|
||||
<< std::numeric_limits<double>::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 << "{\"testFieldDouble\":0}"_ba;
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonDeserializationTest::DoubleMessageDeserializeTest()
|
||||
{
|
||||
QFETCH(const double, value);
|
||||
QFETCH(const QByteArray, serializeData);
|
||||
|
||||
SimpleDoubleMessage test;
|
||||
test.setTestFieldDouble(value);
|
||||
test.deserialize(serializer.get(), serializeData);
|
||||
QCOMPARE(test.testFieldDouble(), value);
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonDeserializationTest::StringMessageDeserializeTest()
|
||||
{
|
||||
SimpleStringMessage test;
|
||||
test.deserialize(serializer.get(), "{\"testFieldString\":\"qwerty\"}"_ba);
|
||||
QCOMPARE(test.testFieldString(), "qwerty");
|
||||
|
||||
test.deserialize(serializer.get(), "{\"testFieldString\":\"\"}"_ba);
|
||||
QCOMPARE(test.testFieldString(), "");
|
||||
|
||||
test.deserialize(serializer.get(), "{\"testFieldString\":\"null\"}"_ba);
|
||||
QCOMPARE(test.testFieldString(), "null");
|
||||
|
||||
test.deserialize(serializer.get(), "{\"testFieldString\":\"NaN\"}"_ba);
|
||||
QCOMPARE(test.testFieldString(), "NaN");
|
||||
|
||||
test.deserialize(serializer.get(), "{\"testFieldString\":\"Infinity\"}"_ba);
|
||||
QCOMPARE(test.testFieldString(), "Infinity");
|
||||
|
||||
test.deserialize(serializer.get(), "{\"testFieldString\":\"-Infinity\"}"_ba);
|
||||
QCOMPARE(test.testFieldString(), "-Infinity");
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonDeserializationTest::ComplexTypeDeserializeTest_data()
|
||||
{
|
||||
QTest::addColumn<int>("intField");
|
||||
QTest::addColumn<QString>("stringField");
|
||||
QTest::addColumn<QByteArray>("serializeData");
|
||||
|
||||
QTest::newRow("empty_value")
|
||||
<< 0 << ""
|
||||
<< "{\"testFieldInt\":0,\"testComplexField\":{\"testFieldString\":\"\"}}"_ba;
|
||||
QTest::newRow("null_complex_field")
|
||||
<< 0 << ""
|
||||
<< "{\"testFieldInt\":0,\"testComplexField\":null}"_ba;
|
||||
QTest::newRow("value_only_int")
|
||||
<< 42 << ""
|
||||
<< "{\"testFieldInt\":42,\"testComplexField\":{\"testFieldString\":\"\"}}"_ba;
|
||||
QTest::newRow("value_only_string")
|
||||
<< 0 << "qwerty"
|
||||
<< "{\"testFieldInt\":0,\"testComplexField\":{\"testFieldString\":\"qwerty\"}}"_ba;
|
||||
QTest::newRow("int_and_string")
|
||||
<< 42 << "qwerty"
|
||||
<< "{\"testFieldInt\":42,\"testComplexField\":{\"testFieldString\":\"qwerty\"}}"_ba;
|
||||
QTest::newRow("int_and_big_string")
|
||||
<< 42
|
||||
<< "YVRfJvjxqbgvFwS1YvOZXgtj5ffGLS7AiNHz9oZIoKbm7z8H79xBuyPkpQXvGoO09OY9xRawx3eOAs9xjo"
|
||||
"TA1xJhrw28TAcq1CebYlC9WUfQC6hIantaNdyHiKToffi0Zt7la42SRxXZSP4GuxbcZIp53pJnyCwfCy1q"
|
||||
"dFczT0dmn7h8fpyAdemEavwFeda4d0PApGfSU2jLt39X8kYUBxNM2WgALRBgHdVde87q6Pi5U69TjhMd28"
|
||||
"W1SFD1DxyogCCrqOct2ZPICoLnrqdF3OdNzjRVLfeyvQ8LgLvRNFR9WfWAyAz79nKgBamd8Ntlvt4Mg35E"
|
||||
"5gVS2g7AQ7rkm72cBdnW9sCEyGabeXAuH5j4GRbuLT7qBZWDcFLF4SsCdS3WfFGdNHfwaijzykByo71PvF"
|
||||
"VlTXH2WJWoFvR5FALjBTn7bCdP0pAiSbLCY8Xz2Msc3dBb5Ff9GISPbUpNmUvBdMZMHQvqOmTNXEPpN0b7"
|
||||
"4MDOMQfWJShOo3NkAvMjs"
|
||||
<< "{\"testFieldInt\":42,\"testComplexField\":{\"testFieldString\":\"YVRfJvjxqbgvFwS1Y"
|
||||
"vOZXgtj5ffGLS7AiNHz9oZIoKbm7z8H79xBuyPkpQXvGoO09OY9xRawx3eOAs9xjoTA1xJhrw28TAcq1Ce"
|
||||
"bYlC9WUfQC6hIantaNdyHiKToffi0Zt7la42SRxXZSP4GuxbcZIp53pJnyCwfCy1qdFczT0dmn7h8fpyAd"
|
||||
"emEavwFeda4d0PApGfSU2jLt39X8kYUBxNM2WgALRBgHdVde87q6Pi5U69TjhMd28W1SFD1DxyogCCrqOc"
|
||||
"t2ZPICoLnrqdF3OdNzjRVLfeyvQ8LgLvRNFR9WfWAyAz79nKgBamd8Ntlvt4Mg35E5gVS2g7AQ7rkm72cB"
|
||||
"dnW9sCEyGabeXAuH5j4GRbuLT7qBZWDcFLF4SsCdS3WfFGdNHfwaijzykByo71PvFVlTXH2WJWoFvR5FAL"
|
||||
"jBTn7bCdP0pAiSbLCY8Xz2Msc3dBb5Ff9GISPbUpNmUvBdMZMHQvqOmTNXEPpN0b74MDOMQfWJShOo3NkA"
|
||||
"vMjs\"}}"_ba;
|
||||
QTest::newRow("neg_int_and_string")
|
||||
<< -45 << "qwerty"
|
||||
<< "{\"testFieldInt\":-45,\"testComplexField\":{\"testFieldString\":\"qwerty\"}}"_ba;
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonDeserializationTest::ComplexTypeDeserializeTest()
|
||||
{
|
||||
QFETCH(const int, intField);
|
||||
QFETCH(const QString, stringField);
|
||||
QFETCH(const QByteArray, serializeData);
|
||||
|
||||
SimpleStringMessage stringMessage;
|
||||
stringMessage.setTestFieldString(stringField);
|
||||
|
||||
ComplexMessage test;
|
||||
test.deserialize(serializer.get(), serializeData);
|
||||
QCOMPARE(test.testFieldInt(), intField);
|
||||
QCOMPARE(test.testComplexField(), stringMessage);
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonDeserializationTest::ResetComplexTypeDeserializeTest_data()
|
||||
{
|
||||
QTest::addColumn<int>("intField");
|
||||
QTest::addColumn<QString>("stringField");
|
||||
QTest::addColumn<QByteArray>("serializeData");
|
||||
|
||||
QTest::newRow("empty_value")
|
||||
<< 0 << u""_s << "{\"testFieldInt\":0,\"testComplexField\":{}}"_ba;
|
||||
QTest::newRow("value_only_int")
|
||||
<< 42 << u""_s << "{\"testFieldInt\":42,\"testComplexField\":{}}"_ba;
|
||||
QTest::newRow("value_only_string")
|
||||
<< 0 << u""_s << "{\"testFieldInt\":0,\"testComplexField\":{}}"_ba;
|
||||
QTest::newRow("int_and_string")
|
||||
<< 42 << u"qwerty"_s
|
||||
<< "{\"testFieldInt\":42,\"testComplexField\":{\"testFieldString\":\"qwerty\"}}"_ba;
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonDeserializationTest::ResetComplexTypeDeserializeTest()
|
||||
{
|
||||
QFETCH(const int, intField);
|
||||
QFETCH(const QString, stringField);
|
||||
QFETCH(const QByteArray, serializeData);
|
||||
|
||||
SimpleStringMessage stringMessage;
|
||||
stringMessage.setTestFieldString(stringField);
|
||||
ComplexMessage test;
|
||||
test.setTestFieldInt(intField);
|
||||
test.setTestComplexField(stringMessage);
|
||||
|
||||
// Reset Complex field
|
||||
test.clearTestComplexField();
|
||||
test.deserialize(serializer.get(), serializeData);
|
||||
QCOMPARE(test.testFieldInt(), intField);
|
||||
QCOMPARE(test.testComplexField(), stringMessage);
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonDeserializationTest::DefaultConstructedComplexTypeDeserializeTest()
|
||||
{
|
||||
ComplexMessage test;
|
||||
test.deserialize(serializer.get(), "{\"testFieldInt\":0,\"testComplexField\":{}}"_ba);
|
||||
QCOMPARE(test.testFieldInt(), 0);
|
||||
QCOMPARE(test.testComplexField().testFieldString(), "");
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonDeserializationTest::EmptyBytesMessageTest()
|
||||
{
|
||||
SimpleBytesMessage test;
|
||||
test.deserialize(serializer.get(), "{\"testFieldBytes\":\"\"}"_ba);
|
||||
QCOMPARE(test.testFieldBytes(), "");
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonDeserializationTest::EmptyStringMessageTest()
|
||||
{
|
||||
SimpleStringMessage test;
|
||||
test.deserialize(serializer.get(), "{\"testFieldString\":\"\"}"_ba);
|
||||
QCOMPARE(test.testFieldString(), "");
|
||||
}
|
||||
|
||||
QTEST_MAIN(QtProtobufTypesJsonDeserializationTest)
|
||||
#include "tst_protobuf_deserialization_json_basictypes.moc"
|
||||
|
|
@ -0,0 +1,245 @@
|
|||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
//#include "basicmessages.qpb.h"
|
||||
#include "repeatedmessages.qpb.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QTest>
|
||||
#include <QProtobufJsonSerializer>
|
||||
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
class QtProtobufRepeatedTypesJsonDeserializationTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void init()
|
||||
{
|
||||
serializer.reset(new QProtobufJsonSerializer);
|
||||
}
|
||||
|
||||
void RepeatedStringMessageTest();
|
||||
void RepeatedFloatMessageTest();
|
||||
void RepeatedBytesMessageTest();
|
||||
void RepeatedDoubleMessageTest();
|
||||
void RepeatedIntMessageTest();
|
||||
void RepeatedSIntMessageTest();
|
||||
void RepeatedUIntMessageTest();
|
||||
void RepeatedInt64MessageTest();
|
||||
void RepeatedSInt64MessageTest();
|
||||
void RepeatedUInt64MessageTest();
|
||||
void RepeatedFixedIntMessageTest();
|
||||
void RepeatedSFixedIntMessageTest();
|
||||
void RepeatedFixedInt64MessageTest();
|
||||
void RepeatedSFixedInt64MessageTest();
|
||||
void RepeatedComplexMessageTest();
|
||||
void RepeatedBoolMessageTest();
|
||||
private:
|
||||
std::unique_ptr<QProtobufJsonSerializer> serializer;
|
||||
};
|
||||
|
||||
using namespace qtprotobufnamespace::tests;
|
||||
|
||||
void QtProtobufRepeatedTypesJsonDeserializationTest::RepeatedStringMessageTest()
|
||||
{
|
||||
RepeatedStringMessage test;
|
||||
test.deserialize(serializer.get(), "{\"testRepeatedString\":[\"aaaa\",\"bbbbb\",\"ccc\",\"dddddd\",\"eeeee\",\"\"]}"_ba);
|
||||
QCOMPARE(test.testRepeatedString().count(), 6);
|
||||
QCOMPARE(test.testRepeatedString(), QStringList({"aaaa","bbbbb","ccc","dddddd","eeeee",""}));
|
||||
|
||||
test.deserialize(serializer.get(), "{\"testRepeatedString\":[]"_ba);
|
||||
QVERIFY(test.testRepeatedString().isEmpty());
|
||||
}
|
||||
|
||||
void QtProtobufRepeatedTypesJsonDeserializationTest::RepeatedBytesMessageTest()
|
||||
{
|
||||
RepeatedBytesMessage test;
|
||||
test.deserialize(serializer.get(), "{\"testRepeatedBytes\":[\"AQIDBAUG\",\"/////w==\",\"6urq6uo=\",\"AQIDBAUG\"]}"_ba);
|
||||
QCOMPARE(test.testRepeatedBytes().count(), 4);
|
||||
QCOMPARE(test.testRepeatedBytes(), QByteArrayList({QByteArray::fromHex("010203040506"),
|
||||
QByteArray::fromHex("ffffffff"),
|
||||
QByteArray::fromHex("eaeaeaeaea"),
|
||||
QByteArray::fromHex("010203040506")}));
|
||||
//TODO: Serialization for list types works partially incorrect because of appending of values to existing
|
||||
//Need to make decision if deserialize should reset all protobuf properties or not
|
||||
RepeatedBytesMessage test2;
|
||||
test2.deserialize(serializer.get(), "{\"testRepeatedBytes\":[\"AQIDBAUG\",\"\",\"6urq6uo=\",\"AQIDBAUG\"]}"_ba);
|
||||
QCOMPARE(test2.testRepeatedBytes().count(), 4);
|
||||
QCOMPARE(test2.testRepeatedBytes(), QByteArrayList({QByteArray::fromHex("010203040506"),
|
||||
QByteArray::fromHex(""),
|
||||
QByteArray::fromHex("eaeaeaeaea"),
|
||||
QByteArray::fromHex("010203040506")}));
|
||||
test.deserialize(serializer.get(), "{\"testRepeatedBytes\":[]"_ba);
|
||||
QVERIFY(test.testRepeatedBytes().isEmpty());
|
||||
}
|
||||
|
||||
void QtProtobufRepeatedTypesJsonDeserializationTest::RepeatedFloatMessageTest()
|
||||
{
|
||||
RepeatedFloatMessage test;
|
||||
test.deserialize(serializer.get(), "{\"testRepeatedFloat\":[0.4,1.2,0.5,3.912348,0.6]}"_ba);
|
||||
QCOMPARE(test.testRepeatedFloat().count(), 5);
|
||||
QCOMPARE(test.testRepeatedFloat(), QtProtobuf::floatList({0.4f, 1.2f, 0.5f, 3.912348f, 0.6f}));
|
||||
|
||||
test.deserialize(serializer.get(), "{\"testRepeatedFloat\":[]"_ba);
|
||||
QVERIFY(test.testRepeatedFloat().isEmpty());
|
||||
}
|
||||
|
||||
void QtProtobufRepeatedTypesJsonDeserializationTest::RepeatedDoubleMessageTest()
|
||||
{
|
||||
RepeatedDoubleMessage test;
|
||||
test.deserialize(serializer.get(), "{\"testRepeatedDouble\":[0.1,0.2,0.3,3.912348239293,0.5]}"_ba);
|
||||
QCOMPARE(test.testRepeatedDouble().count(), 5);
|
||||
QCOMPARE(test.testRepeatedDouble(), QtProtobuf::doubleList({0.1,0.2,0.3,3.912348239293,0.5}));
|
||||
|
||||
test.deserialize(serializer.get(), "{\"testRepeatedDouble\":[]"_ba);
|
||||
QVERIFY(test.testRepeatedDouble().isEmpty());
|
||||
}
|
||||
|
||||
void QtProtobufRepeatedTypesJsonDeserializationTest::RepeatedIntMessageTest()
|
||||
{
|
||||
RepeatedIntMessage test;
|
||||
test.deserialize(serializer.get(), "{\"testRepeatedInt\":[0,1,321,-65999,123245,-3,3]}"_ba);
|
||||
QCOMPARE(test.testRepeatedInt().count(), 7);
|
||||
QCOMPARE(test.testRepeatedInt(), QtProtobuf::int32List({0, 1, 321, -65999, 123245, -3, 3}));
|
||||
|
||||
test.deserialize(serializer.get(), "{\"testRepeatedInt\":[]"_ba);
|
||||
QVERIFY(test.testRepeatedInt().isEmpty());
|
||||
}
|
||||
|
||||
void QtProtobufRepeatedTypesJsonDeserializationTest::RepeatedSIntMessageTest()
|
||||
{
|
||||
RepeatedSIntMessage test;
|
||||
test.deserialize(serializer.get(), "{\"testRepeatedInt\":[1,321,-65999,123245,-3,3]}"_ba);
|
||||
QCOMPARE(test.testRepeatedInt().count(), 6);
|
||||
QCOMPARE(test.testRepeatedInt(), QtProtobuf::sint32List({1, 321, -65999, 123245, -3, 3}));
|
||||
|
||||
test.deserialize(serializer.get(), "{\"testRepeatedInt\":[]"_ba);
|
||||
QVERIFY(test.testRepeatedInt().isEmpty());
|
||||
}
|
||||
|
||||
void QtProtobufRepeatedTypesJsonDeserializationTest::RepeatedUIntMessageTest()
|
||||
{
|
||||
RepeatedUIntMessage test;
|
||||
test.deserialize(serializer.get(), "{\"testRepeatedInt\":[1,0,321,65999,123245,3]}"_ba);
|
||||
QCOMPARE(test.testRepeatedInt().count(), 6);
|
||||
QCOMPARE(test.testRepeatedInt(), QtProtobuf::uint32List({1, 0, 321, 65999, 123245, 3}));
|
||||
|
||||
test.deserialize(serializer.get(), "{\"testRepeatedInt\":[]"_ba);
|
||||
QVERIFY(test.testRepeatedInt().isEmpty());
|
||||
}
|
||||
|
||||
void QtProtobufRepeatedTypesJsonDeserializationTest::RepeatedInt64MessageTest()
|
||||
{
|
||||
RepeatedInt64Message test;
|
||||
test.deserialize(serializer.get(), "{\"testRepeatedInt\":[1,321,-65999,12324523123123,-3,0,3]}"_ba);
|
||||
QCOMPARE(test.testRepeatedInt().count(), 7);
|
||||
QCOMPARE(test.testRepeatedInt(), QtProtobuf::int64List({1, 321, -65999, 12324523123123, -3, 0, 3}));
|
||||
|
||||
test.deserialize(serializer.get(), "{\"testRepeatedInt\":[]"_ba);
|
||||
QVERIFY(test.testRepeatedInt().isEmpty());
|
||||
}
|
||||
|
||||
void QtProtobufRepeatedTypesJsonDeserializationTest::RepeatedSInt64MessageTest()
|
||||
{
|
||||
RepeatedSInt64Message test;
|
||||
test.deserialize(serializer.get(), "{\"testRepeatedInt\":[1,321,-65999,12324523123123,-3,3]}"_ba);
|
||||
QCOMPARE(test.testRepeatedInt().count(), 6);
|
||||
QCOMPARE(test.testRepeatedInt(), QtProtobuf::sint64List({1, 321, -65999, 12324523123123, -3, 3}));
|
||||
|
||||
test.deserialize(serializer.get(), "{\"testRepeatedInt\":[]"_ba);
|
||||
QVERIFY(test.testRepeatedInt().isEmpty());
|
||||
}
|
||||
|
||||
void QtProtobufRepeatedTypesJsonDeserializationTest::RepeatedUInt64MessageTest()
|
||||
{
|
||||
RepeatedUInt64Message test;
|
||||
test.deserialize(serializer.get(), "{\"testRepeatedInt\":[1,321,65999,123245,123245324235425234,3]}"_ba);
|
||||
QCOMPARE(test.testRepeatedInt().count(), 6);
|
||||
QCOMPARE(test.testRepeatedInt(), QtProtobuf::uint64List({1, 321, 65999, 123245, 123245324235425234, 3}));
|
||||
|
||||
test.deserialize(serializer.get(), "{\"testRepeatedInt\":[]"_ba);
|
||||
QVERIFY(test.testRepeatedInt().isEmpty());
|
||||
}
|
||||
|
||||
void QtProtobufRepeatedTypesJsonDeserializationTest::RepeatedFixedIntMessageTest()
|
||||
{
|
||||
RepeatedFixedIntMessage test;
|
||||
test.deserialize(serializer.get(), "{\"testRepeatedInt\":[1,321,65999,12324523,3,3]}"_ba);
|
||||
QCOMPARE(test.testRepeatedInt().count(), 6);
|
||||
QCOMPARE(test.testRepeatedInt(), QtProtobuf::fixed32List({1, 321, 65999, 12324523, 3, 3}));
|
||||
|
||||
test.deserialize(serializer.get(), "{\"testRepeatedInt\":[]"_ba);
|
||||
QVERIFY(test.testRepeatedInt().isEmpty());
|
||||
}
|
||||
|
||||
void QtProtobufRepeatedTypesJsonDeserializationTest::RepeatedSFixedIntMessageTest()
|
||||
{
|
||||
RepeatedSFixedIntMessage test;
|
||||
test.deserialize(serializer.get(), "{\"testRepeatedInt\":[0,1,321,-65999,12324523,-3,3]}"_ba);
|
||||
QCOMPARE(test.testRepeatedInt().count(), 7);
|
||||
QCOMPARE(test.testRepeatedInt(), QtProtobuf::sfixed32List({0, 1, 321, -65999, 12324523, -3, 3}));
|
||||
|
||||
test.deserialize(serializer.get(), "{\"testRepeatedInt\":[]"_ba);
|
||||
QVERIFY(test.testRepeatedInt().isEmpty());
|
||||
}
|
||||
|
||||
void QtProtobufRepeatedTypesJsonDeserializationTest::RepeatedFixedInt64MessageTest()
|
||||
{
|
||||
RepeatedFixedInt64Message test;
|
||||
test.deserialize(serializer.get(), "{\"testRepeatedInt\":[1,321,65999,123245324235425234,3,3]}"_ba);
|
||||
QCOMPARE(test.testRepeatedInt().count(), 6);
|
||||
QCOMPARE(test.testRepeatedInt(), QtProtobuf::fixed64List({1, 321, 65999, 123245324235425234, 3, 3}));
|
||||
|
||||
test.deserialize(serializer.get(), "{\"testRepeatedInt\":[]"_ba);
|
||||
QVERIFY(test.testRepeatedInt().isEmpty());
|
||||
}
|
||||
|
||||
void QtProtobufRepeatedTypesJsonDeserializationTest::RepeatedSFixedInt64MessageTest()
|
||||
{
|
||||
RepeatedSFixedInt64Message test;
|
||||
test.deserialize(serializer.get(), "{\"testRepeatedInt\":[1,321,-65999,123245324235425234,-3,3]}"_ba);
|
||||
QCOMPARE(test.testRepeatedInt().count(), 6);
|
||||
QCOMPARE(test.testRepeatedInt(), QtProtobuf::sfixed64List({1, 321, -65999, 123245324235425234, -3, 3}));
|
||||
|
||||
test.deserialize(serializer.get(), "{\"testRepeatedInt\":[]"_ba);
|
||||
QVERIFY(test.testRepeatedInt().isEmpty());
|
||||
}
|
||||
|
||||
void QtProtobufRepeatedTypesJsonDeserializationTest::RepeatedComplexMessageTest()
|
||||
{
|
||||
RepeatedComplexMessage test;
|
||||
test.deserialize(serializer.get(), "{\"testRepeatedComplex\":[{\"testFieldInt\":21,\"testComplexField\":"
|
||||
"{\"testFieldString\":\"12345\"}},{\"testFieldInt\":22,\"testComplexField\":"
|
||||
"{\"testFieldString\":\"qwerty\"}},{\"testFieldInt\":23,\"testComplexField\":"
|
||||
"{\"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);
|
||||
QCOMPARE(test.testRepeatedComplex().at(1).testComplexField().testFieldString(), QString("qwerty"));
|
||||
QCOMPARE(test.testRepeatedComplex().at(2).testFieldInt(), 23);
|
||||
QCOMPARE(test.testRepeatedComplex().at(2).testComplexField().testFieldString(), QString(""));
|
||||
|
||||
test.deserialize(serializer.get(), "{\"testRepeatedComplex\":[]}"_ba);
|
||||
QVERIFY(!test.testRepeatedComplex().isEmpty());
|
||||
}
|
||||
|
||||
void QtProtobufRepeatedTypesJsonDeserializationTest::RepeatedBoolMessageTest()
|
||||
{
|
||||
RepeatedBoolMessage boolMsg;
|
||||
boolMsg.deserialize(serializer.get(), "{\"testRepeatedBool\":[true,true,true,false,false,false,false,false,false,false,false,false,true]}"_ba);
|
||||
QCOMPARE(serializer->deserializationError(), QAbstractProtobufSerializer::NoError);
|
||||
QtProtobuf::boolList expected({ true, true, true, false, false, false, false,
|
||||
false, false, false, false, false, true });
|
||||
QCOMPARE(boolMsg.testRepeatedBool().count(), 13);
|
||||
QCOMPARE(boolMsg.testRepeatedBool(), expected);
|
||||
}
|
||||
|
||||
QTEST_MAIN(QtProtobufRepeatedTypesJsonDeserializationTest)
|
||||
#include "tst_protobuf_deserialization_json_repeatedtypes.moc"
|
||||
|
|
@ -0,0 +1,603 @@
|
|||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "basicmessages.qpb.h"
|
||||
|
||||
#include <QProtobufJsonSerializer>
|
||||
#include <QTest>
|
||||
#include <QJsonDocument>
|
||||
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
class QtProtobufTypesJsonSerializationTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void init() { qRegisterProtobufTypes(); m_serializer.reset(new QProtobufJsonSerializer); }
|
||||
|
||||
void BoolMessageSerializeTest_data();
|
||||
void BoolMessageSerializeTest();
|
||||
void IntMessageSerializeTest_data();
|
||||
void IntMessageSerializeTest();
|
||||
void UIntMessageSerializeTest_data();
|
||||
void UIntMessageSerializeTest();
|
||||
void SIntMessageSerializeTest_data();
|
||||
void SIntMessageSerializeTest();
|
||||
void Int64MessageSerializeTest_data();
|
||||
void Int64MessageSerializeTest();
|
||||
void UInt64MessageSerializeTest_data();
|
||||
void UInt64MessageSerializeTest();
|
||||
void SInt64MessageSerializeTest_data();
|
||||
void SInt64MessageSerializeTest();
|
||||
void FixedInt32MessageSerializeTest_data();
|
||||
void FixedInt32MessageSerializeTest();
|
||||
void FixedInt64MessageSerializeTest_data();
|
||||
void FixedInt64MessageSerializeTest();
|
||||
void SFixedInt32MessageSerializeTest_data();
|
||||
void SFixedInt32MessageSerializeTest();
|
||||
void SFixedInt64MessageSerializeTest_data();
|
||||
void SFixedInt64MessageSerializeTest();
|
||||
void FloatMessageSerializeTest_data();
|
||||
void FloatMessageSerializeTest();
|
||||
void DoubleMessageSerializeTest_data();
|
||||
void DoubleMessageSerializeTest();
|
||||
void StringMessageSerializeTest();
|
||||
void ComplexTypeSerializeTest_data();
|
||||
void ComplexTypeSerializeTest();
|
||||
void ResetComplexTypeSerializeTest_data();
|
||||
void ResetComplexTypeSerializeTest();
|
||||
void DefaultConstructedComplexTypeSerializeTest();
|
||||
void EmptyBytesMessageTest();
|
||||
void EmptyStringMessageTest();
|
||||
|
||||
/* TBD: Add ANY type support for Json Serializer
|
||||
void OneofMessageEmptyTest();
|
||||
void OneofMessageClearTest();
|
||||
void OneofMessageIntTest();
|
||||
void OneofMessageComplexTest();
|
||||
*/
|
||||
|
||||
private:
|
||||
std::unique_ptr<QProtobufJsonSerializer> m_serializer;
|
||||
};
|
||||
|
||||
using namespace qtprotobufnamespace::tests;
|
||||
|
||||
void QtProtobufTypesJsonSerializationTest::BoolMessageSerializeTest_data()
|
||||
{
|
||||
QTest::addColumn<bool>("value");
|
||||
QTest::addColumn<qsizetype>("expectedSize");
|
||||
QTest::addColumn<QByteArray>("expectedData");
|
||||
|
||||
QTest::newRow("True") << true << qsizetype(22) << "{\"testFieldBool\":true}"_ba;
|
||||
QTest::newRow("False") << false << qsizetype(23) << "{\"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());
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonSerializationTest::IntMessageSerializeTest_data()
|
||||
{
|
||||
QTest::addColumn<int32_t>("value");
|
||||
QTest::addColumn<qsizetype>("expectedSize");
|
||||
QTest::addColumn<QByteArray>("expectedData");
|
||||
|
||||
QTest::newRow("555") << 555 << qsizetype(20) << "{\"testFieldInt\":555}"_ba;
|
||||
QTest::newRow("0") << 0 << qsizetype(18) << "{\"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());
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonSerializationTest::UIntMessageSerializeTest_data()
|
||||
{
|
||||
QTest::addColumn<uint32_t>("value");
|
||||
QTest::addColumn<qsizetype>("expectedSize");
|
||||
QTest::addColumn<QByteArray>("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;
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonSerializationTest::SIntMessageSerializeTest_data()
|
||||
{
|
||||
QTest::addColumn<int32_t>("value");
|
||||
QTest::addColumn<qsizetype>("expectedSize");
|
||||
QTest::addColumn<QByteArray>("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("-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;
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonSerializationTest::Int64MessageSerializeTest_data()
|
||||
{
|
||||
QTest::addColumn<int64_t>("value");
|
||||
QTest::addColumn<qsizetype>("expectedSize");
|
||||
QTest::addColumn<QByteArray>("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("-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;
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonSerializationTest::UInt64MessageSerializeTest_data()
|
||||
{
|
||||
QTest::addColumn<uint64_t>("value");
|
||||
QTest::addColumn<qsizetype>("expectedSize");
|
||||
QTest::addColumn<QByteArray>("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;
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonSerializationTest::SInt64MessageSerializeTest_data()
|
||||
{
|
||||
QTest::addColumn<int64_t>("value");
|
||||
QTest::addColumn<qsizetype>("expectedSize");
|
||||
QTest::addColumn<QByteArray>("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("-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;
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonSerializationTest::FixedInt32MessageSerializeTest_data()
|
||||
{
|
||||
QTest::addColumn<uint32_t>("value");
|
||||
QTest::addColumn<qsizetype>("expectedSize");
|
||||
QTest::addColumn<QByteArray>("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;
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonSerializationTest::FixedInt64MessageSerializeTest_data()
|
||||
{
|
||||
QTest::addColumn<uint64_t>("value");
|
||||
QTest::addColumn<qsizetype>("expectedSize");
|
||||
QTest::addColumn<QByteArray>("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;
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonSerializationTest::SFixedInt32MessageSerializeTest_data()
|
||||
{
|
||||
QTest::addColumn<int32_t>("value");
|
||||
QTest::addColumn<qsizetype>("expectedSize");
|
||||
QTest::addColumn<QByteArray>("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("-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;
|
||||
}
|
||||
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());
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonSerializationTest::SFixedInt64MessageSerializeTest_data()
|
||||
{
|
||||
QTest::addColumn<int64_t>("value");
|
||||
QTest::addColumn<qsizetype>("expectedSize");
|
||||
QTest::addColumn<QByteArray>("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("-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;
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonSerializationTest::FloatMessageSerializeTest_data()
|
||||
{
|
||||
QTest::addColumn<float>("value");
|
||||
QTest::addColumn<qsizetype>("expectedSize");
|
||||
QTest::addColumn<QByteArray>("expectedData");
|
||||
|
||||
QTest::newRow("float_value_0_1") << 0.1f << qsizetype(22) << "{\"testFieldFloat\":0.1}"_ba;
|
||||
QTest::newRow("float_value_min") << std::numeric_limits<float>::min() << qsizetype(31)
|
||||
<< "{\"testFieldFloat\":1.175494e-38}"_ba;
|
||||
QTest::newRow("float_value_max") << std::numeric_limits<float>::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;
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonSerializationTest::DoubleMessageSerializeTest_data()
|
||||
{
|
||||
QTest::addColumn<double>("value");
|
||||
QTest::addColumn<qsizetype>("expectedSize");
|
||||
QTest::addColumn<QByteArray>("expectedData");
|
||||
|
||||
QTest::newRow("double_value_0_1") << 0.1 << qsizetype(23)
|
||||
<< "{\"testFieldDouble\":0.1}"_ba;
|
||||
QTest::newRow("double_value_min")
|
||||
<< std::numeric_limits<double>::min() << qsizetype(40)
|
||||
<< "{\"testFieldDouble\":2.2250738585072e-308}"_ba;
|
||||
QTest::newRow("double_value_max")
|
||||
<< std::numeric_limits<double>::max() << qsizetype(40)
|
||||
<< "{\"testFieldDouble\":1.7976931348623e+308}"_ba;
|
||||
QTest::newRow("double_neg_value_4_2") << -4.2 << qsizetype(24)
|
||||
<< "{\"testFieldDouble\":-4.2}"_ba;
|
||||
QTest::newRow("double_value_0_0") << 0.0 << qsizetype(21)
|
||||
<< "{\"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());
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonSerializationTest::StringMessageSerializeTest()
|
||||
{
|
||||
SimpleStringMessage test;
|
||||
test.setTestFieldString("qwerty");
|
||||
QByteArray result = test.serialize(m_serializer.get());
|
||||
|
||||
QCOMPARE(result, "{\"testFieldString\":\"qwerty\"}"_ba);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
|
||||
test.setTestFieldString("");
|
||||
result = test.serialize(m_serializer.get());
|
||||
QCOMPARE(result, "{\"testFieldString\":\"\"}"_ba);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
|
||||
test.setTestFieldString("null");
|
||||
result = test.serialize(m_serializer.get());
|
||||
QCOMPARE(result, "{\"testFieldString\":\"null\"}"_ba);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
|
||||
test.setTestFieldString("NaN");
|
||||
result = test.serialize(m_serializer.get());
|
||||
QCOMPARE(result, "{\"testFieldString\":\"NaN\"}"_ba);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
|
||||
test.setTestFieldString("Infinity");
|
||||
result = test.serialize(m_serializer.get());
|
||||
QCOMPARE(result, "{\"testFieldString\":\"Infinity\"}"_ba);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
|
||||
test.setTestFieldString("-Infinity");
|
||||
result = test.serialize(m_serializer.get());
|
||||
QCOMPARE(result, "{\"testFieldString\":\"-Infinity\"}"_ba);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonSerializationTest::ComplexTypeSerializeTest_data()
|
||||
{
|
||||
QTest::addColumn<int>("intField");
|
||||
QTest::addColumn<QString>("stringField");
|
||||
QTest::addColumn<QByteArray>("expectedData");
|
||||
|
||||
QTest::newRow("empty_value")
|
||||
<< 0 << ""
|
||||
<< "{\"testFieldInt\":0,\"testComplexField\":{\"testFieldString\":\"\"}}"_ba;
|
||||
QTest::newRow("value_only_int")
|
||||
<< 42 << ""
|
||||
<< "{\"testFieldInt\":42,\"testComplexField\":{\"testFieldString\":\"\"}}"_ba;
|
||||
QTest::newRow("value_only_string")
|
||||
<< 0 << "qwerty"
|
||||
<< "{\"testFieldInt\":0,\"testComplexField\":{\"testFieldString\":\"qwerty\"}}"_ba;
|
||||
QTest::newRow("int_and_string")
|
||||
<< 42 << "qwerty"
|
||||
<< "{\"testFieldInt\":42,\"testComplexField\":{\"testFieldString\":\"qwerty\"}}"_ba;
|
||||
QTest::newRow("int_and_big_string")
|
||||
<< 42
|
||||
<< "YVRfJvjxqbgvFwS1YvOZXgtj5ffGLS7AiNHz9oZIoKbm7z8H79xBuyPkpQXvGoO09OY9xRawx3eOAs9xjo"
|
||||
"TA1xJhrw28TAcq1CebYlC9WUfQC6hIantaNdyHiKToffi0Zt7la42SRxXZSP4GuxbcZIp53pJnyCwfCy1q"
|
||||
"dFczT0dmn7h8fpyAdemEavwFeda4d0PApGfSU2jLt39X8kYUBxNM2WgALRBgHdVde87q6Pi5U69TjhMd28"
|
||||
"W1SFD1DxyogCCrqOct2ZPICoLnrqdF3OdNzjRVLfeyvQ8LgLvRNFR9WfWAyAz79nKgBamd8Ntlvt4Mg35E"
|
||||
"5gVS2g7AQ7rkm72cBdnW9sCEyGabeXAuH5j4GRbuLT7qBZWDcFLF4SsCdS3WfFGdNHfwaijzykByo71PvF"
|
||||
"VlTXH2WJWoFvR5FALjBTn7bCdP0pAiSbLCY8Xz2Msc3dBb5Ff9GISPbUpNmUvBdMZMHQvqOmTNXEPpN0b7"
|
||||
"4MDOMQfWJShOo3NkAvMjs"
|
||||
<< "{\"testFieldInt\":42,\"testComplexField\":{\"testFieldString\":\"YVRfJvjxqbgvFwS1Y"
|
||||
"vOZXgtj5ffGLS7AiNHz9oZIoKbm7z8H79xBuyPkpQXvGoO09OY9xRawx3eOAs9xjoTA1xJhrw28TAcq1Ce"
|
||||
"bYlC9WUfQC6hIantaNdyHiKToffi0Zt7la42SRxXZSP4GuxbcZIp53pJnyCwfCy1qdFczT0dmn7h8fpyAd"
|
||||
"emEavwFeda4d0PApGfSU2jLt39X8kYUBxNM2WgALRBgHdVde87q6Pi5U69TjhMd28W1SFD1DxyogCCrqOc"
|
||||
"t2ZPICoLnrqdF3OdNzjRVLfeyvQ8LgLvRNFR9WfWAyAz79nKgBamd8Ntlvt4Mg35E5gVS2g7AQ7rkm72cB"
|
||||
"dnW9sCEyGabeXAuH5j4GRbuLT7qBZWDcFLF4SsCdS3WfFGdNHfwaijzykByo71PvFVlTXH2WJWoFvR5FAL"
|
||||
"jBTn7bCdP0pAiSbLCY8Xz2Msc3dBb5Ff9GISPbUpNmUvBdMZMHQvqOmTNXEPpN0b74MDOMQfWJShOo3NkA"
|
||||
"vMjs\"}}"_ba;
|
||||
QTest::newRow("neg_int_and_string")
|
||||
<< -45 << "qwerty"
|
||||
<< "{\"testFieldInt\":-45,\"testComplexField\":{\"testFieldString\":\"qwerty\"}}"_ba;
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonSerializationTest::ComplexTypeSerializeTest()
|
||||
{
|
||||
QFETCH(const int, intField);
|
||||
QFETCH(const QString, stringField);
|
||||
QFETCH(const QByteArray, expectedData);
|
||||
|
||||
SimpleStringMessage stringMessage;
|
||||
stringMessage.setTestFieldString(stringField);
|
||||
ComplexMessage test, testStd;
|
||||
|
||||
test.setTestFieldInt(intField);
|
||||
test.setTestComplexField(stringMessage);
|
||||
|
||||
testStd.setTestFieldInt(intField);
|
||||
testStd.setTestComplexField(stringMessage);
|
||||
|
||||
QByteArray result = test.serialize(m_serializer.get());
|
||||
QCOMPARE(result, expectedData);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonSerializationTest::ResetComplexTypeSerializeTest_data()
|
||||
{
|
||||
QTest::addColumn<int>("intField");
|
||||
QTest::addColumn<QString>("stringField");
|
||||
QTest::addColumn<QByteArray>("expectedData");
|
||||
|
||||
QTest::newRow("empty_value")
|
||||
<< 0 << u""_s << "{\"testFieldInt\":0,\"testComplexField\":{}}"_ba;
|
||||
QTest::newRow("value_only_int")
|
||||
<< 42 << u""_s << "{\"testFieldInt\":42,\"testComplexField\":{}}"_ba;
|
||||
QTest::newRow("value_only_string")
|
||||
<< 0 << u"qwerty"_s << "{\"testFieldInt\":0,\"testComplexField\":{}}"_ba;
|
||||
QTest::newRow("int_and_string")
|
||||
<< 42 << u"qwerty"_s << "{\"testFieldInt\":42,\"testComplexField\":{}}"_ba;
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonSerializationTest::ResetComplexTypeSerializeTest()
|
||||
{
|
||||
QFETCH(const int, intField);
|
||||
QFETCH(const QString, stringField);
|
||||
QFETCH(const QByteArray, expectedData);
|
||||
|
||||
SimpleStringMessage stringMessage;
|
||||
stringMessage.setTestFieldString(stringField);
|
||||
ComplexMessage test;
|
||||
test.setTestFieldInt(intField);
|
||||
test.setTestComplexField(stringMessage);
|
||||
|
||||
// Reset Complex field
|
||||
test.clearTestComplexField();
|
||||
QByteArray result = test.serialize(m_serializer.get());
|
||||
QCOMPARE(result, expectedData);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonSerializationTest::DefaultConstructedComplexTypeSerializeTest()
|
||||
{
|
||||
ComplexMessage test;
|
||||
QByteArray result = test.serialize(m_serializer.get());
|
||||
QCOMPARE(result, "{\"testFieldInt\":0,\"testComplexField\":{}}"_ba);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonSerializationTest::EmptyBytesMessageTest()
|
||||
{
|
||||
SimpleBytesMessage msg;
|
||||
QByteArray result = msg.serialize(m_serializer.get());
|
||||
QCOMPARE(result, "{\"testFieldBytes\":\"\"}"_ba);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonSerializationTest::EmptyStringMessageTest()
|
||||
{
|
||||
SimpleStringMessage msg;
|
||||
QByteArray result = msg.serialize(m_serializer.get());
|
||||
QCOMPARE(result, "{\"testFieldString\":\"\"}"_ba);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
}
|
||||
|
||||
/* TBD: Add ANY type support for Json Serializer
|
||||
void QtProtobufTypesJsonSerializationTest::OneofMessageEmptyTest()
|
||||
{
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonSerializationTest::OneofMessageIntTest()
|
||||
{
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonSerializationTest::OneofMessageClearTest()
|
||||
{
|
||||
}
|
||||
|
||||
void QtProtobufTypesJsonSerializationTest::OneofMessageComplexTest()
|
||||
{
|
||||
}
|
||||
*/
|
||||
|
||||
QTEST_MAIN(QtProtobufTypesJsonSerializationTest)
|
||||
#include "tst_protobuf_serialization_json_basictypes.moc"
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "mapmessages.qpb.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QProtobufJsonSerializer>
|
||||
#include <QTest>
|
||||
|
||||
using namespace qtprotobufnamespace::tests;
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
class QtProtobufJsonMapTypesSerializationTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void init() { m_serializer.reset(new QProtobufJsonSerializer); }
|
||||
void SimpleFixed32StringMapSerializeTest();
|
||||
void SimpleSFixed32StringMapSerializeTest();
|
||||
void SimpleInt32StringMapSerializeTest();
|
||||
void SimpleSInt32StringMapSerializeTest();
|
||||
void SimpleUInt32StringMapSerializeTest();
|
||||
void SimpleFixed64StringMapSerializeTest();
|
||||
void SimpleSFixed64StringMapSerializeTest();
|
||||
void SimpleInt64StringMapSerializeTest();
|
||||
void SimpleSInt64StringMapSerializeTest();
|
||||
void SimpleUInt64StringMapSerializeTest();
|
||||
void SimpleStringStringMapSerializeTest();
|
||||
|
||||
private:
|
||||
std::unique_ptr<QProtobufJsonSerializer> m_serializer;
|
||||
};
|
||||
|
||||
void QtProtobufJsonMapTypesSerializationTest::SimpleFixed32StringMapSerializeTest()
|
||||
{
|
||||
SimpleFixed32StringMapMessage test;
|
||||
test.setMapField({ { 10, { "ten" } }, { 42, { "fourty two" } }, { 15, { "fifteen" } } });
|
||||
QByteArray result = test.serialize(m_serializer.get());
|
||||
}
|
||||
|
||||
void QtProtobufJsonMapTypesSerializationTest::SimpleSFixed32StringMapSerializeTest()
|
||||
{
|
||||
SimpleSFixed32StringMapMessage test;
|
||||
test.setMapField({ { 10, { "ten" } }, { -42, { "minus fourty two" } }, { 15, { "fifteen" } } });
|
||||
QByteArray result = test.serialize(m_serializer.get());
|
||||
}
|
||||
|
||||
void QtProtobufJsonMapTypesSerializationTest::SimpleInt32StringMapSerializeTest()
|
||||
{
|
||||
SimpleInt32StringMapMessage test;
|
||||
test.setMapField({ { -10, { "minus ten" } }, { 42, { "fourty two" } }, { 15, { "fifteen" } } });
|
||||
QByteArray result = test.serialize(m_serializer.get());
|
||||
|
||||
}
|
||||
|
||||
void QtProtobufJsonMapTypesSerializationTest::SimpleSInt32StringMapSerializeTest()
|
||||
{
|
||||
SimpleSInt32StringMapMessage test;
|
||||
test.setMapField({ { 10, { "ten" } }, { -42, { "minus fourty two" } }, { 15, { "fifteen" } } });
|
||||
QByteArray result = test.serialize(m_serializer.get());
|
||||
|
||||
}
|
||||
|
||||
void QtProtobufJsonMapTypesSerializationTest::SimpleUInt32StringMapSerializeTest()
|
||||
{
|
||||
SimpleUInt32StringMapMessage test;
|
||||
test.setMapField({ { 10, { "ten" } }, { 42, { "fourty two" } }, { 15, { "fifteen" } } });
|
||||
QByteArray result = test.serialize(m_serializer.get());
|
||||
|
||||
}
|
||||
|
||||
void QtProtobufJsonMapTypesSerializationTest::SimpleFixed64StringMapSerializeTest()
|
||||
{
|
||||
SimpleFixed64StringMapMessage test;
|
||||
test.setMapField({ { 10, { "ten" } }, { 42, { "fourty two" } }, { 15, { "fifteen" } } });
|
||||
QByteArray result = test.serialize(m_serializer.get());
|
||||
|
||||
}
|
||||
|
||||
void QtProtobufJsonMapTypesSerializationTest::SimpleSFixed64StringMapSerializeTest()
|
||||
{
|
||||
SimpleSFixed64StringMapMessage test;
|
||||
test.setMapField({ { 10, { "ten" } }, { -42, { "minus fourty two" } }, { 15, { "fifteen" } } });
|
||||
QByteArray result = test.serialize(m_serializer.get());
|
||||
|
||||
}
|
||||
|
||||
void QtProtobufJsonMapTypesSerializationTest::SimpleInt64StringMapSerializeTest()
|
||||
{
|
||||
SimpleInt64StringMapMessage test;
|
||||
test.setMapField({ { -10, { "minus ten" } }, { 42, { "fourty two" } }, { 15, { "fifteen" } } });
|
||||
QByteArray result = test.serialize(m_serializer.get());
|
||||
|
||||
}
|
||||
|
||||
void QtProtobufJsonMapTypesSerializationTest::SimpleSInt64StringMapSerializeTest()
|
||||
{
|
||||
SimpleSInt64StringMapMessage test;
|
||||
test.setMapField({ { 10, { "ten" } }, { -42, { "minus fourty two" } }, { 15, { "fifteen" } } });
|
||||
QByteArray result = test.serialize(m_serializer.get());
|
||||
|
||||
}
|
||||
|
||||
void QtProtobufJsonMapTypesSerializationTest::SimpleUInt64StringMapSerializeTest()
|
||||
{
|
||||
SimpleUInt64StringMapMessage test;
|
||||
test.setMapField({ { 10, { "ten" } }, { 42, { "fourty two" } }, { 15, { "fifteen" } } });
|
||||
QByteArray result = test.serialize(m_serializer.get());
|
||||
|
||||
}
|
||||
|
||||
void QtProtobufJsonMapTypesSerializationTest::SimpleStringStringMapSerializeTest()
|
||||
{
|
||||
SimpleStringStringMapMessage test;
|
||||
test.setMapField({ { "ben", "ten" },
|
||||
{ "what is the answer?", "fourty two" },
|
||||
{ "sweet", "fifteen" } });
|
||||
QByteArray result = test.serialize(m_serializer.get());
|
||||
|
||||
}
|
||||
|
||||
QTEST_MAIN(QtProtobufJsonMapTypesSerializationTest)
|
||||
#include "tst_protobuf_serialization_json_maptypes.moc"
|
||||
|
|
@ -0,0 +1,293 @@
|
|||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
//#include "basicmessages.qpb.h"
|
||||
#include "repeatedmessages.qpb.h"
|
||||
|
||||
#include <QProtobufJsonSerializer>
|
||||
#include <QJsonDocument>
|
||||
#include <QTest>
|
||||
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
class QtProtobufRepeatedTypesJsonSerializationTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void init() {
|
||||
m_serializer.reset(new QProtobufJsonSerializer);
|
||||
}
|
||||
void RepeatedIntMessageTest();
|
||||
void RepeatedSIntMessageTest();
|
||||
void RepeatedUIntMessageTest();
|
||||
void RepeatedInt64MessageTest();
|
||||
void RepeatedSInt64MessageTest();
|
||||
void RepeatedUInt64MessageTest();
|
||||
void RepeatedFixedIntMessageTest();
|
||||
void RepeatedSFixedIntMessageTest();
|
||||
void RepeatedFixedInt64MessageTest();
|
||||
void RepeatedSFixedInt64MessageTest();
|
||||
void RepeatedStringMessageTest();
|
||||
void RepeatedFloatMessageTest();
|
||||
void RepeatedDoubleMessageTest();
|
||||
void RepeatedBytesMessageTest();
|
||||
void RepeatedComplexMessageTest();
|
||||
void RepeatedBoolMessageTest();
|
||||
private:
|
||||
std::unique_ptr<QProtobufJsonSerializer> m_serializer;
|
||||
};
|
||||
|
||||
using namespace qtprotobufnamespace::tests;
|
||||
|
||||
void QtProtobufRepeatedTypesJsonSerializationTest::RepeatedIntMessageTest()
|
||||
{
|
||||
RepeatedIntMessage test;
|
||||
test.setTestRepeatedInt({0, 1, 321, -65999, 123245, -3, 3});
|
||||
QByteArray result = test.serialize(m_serializer.get());
|
||||
|
||||
QCOMPARE(result, "{\"testRepeatedInt\":[0,1,321,-65999,123245,-3,3]}"_ba);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
|
||||
test.setTestRepeatedInt(QtProtobuf::int32List());
|
||||
result = test.serialize(m_serializer.get());
|
||||
QCOMPARE(result, "{\"testRepeatedInt\":[]}"_ba);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
}
|
||||
|
||||
void QtProtobufRepeatedTypesJsonSerializationTest::RepeatedSIntMessageTest()
|
||||
{
|
||||
RepeatedSIntMessage test;
|
||||
test.setTestRepeatedInt({1, 321, -65999, 123245, -3, 3, 0});
|
||||
QByteArray result = test.serialize(m_serializer.get());
|
||||
QCOMPARE(result, "{\"testRepeatedInt\":[1,321,-65999,123245,-3,3,0]}"_ba);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
|
||||
test.setTestRepeatedInt(QtProtobuf::sint32List());
|
||||
result = test.serialize(m_serializer.get());
|
||||
QCOMPARE(result, "{\"testRepeatedInt\":[]}"_ba);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
}
|
||||
|
||||
void QtProtobufRepeatedTypesJsonSerializationTest::RepeatedUIntMessageTest()
|
||||
{
|
||||
RepeatedUIntMessage test;
|
||||
test.setTestRepeatedInt({1, 0, 321, 65999, 123245, 3});
|
||||
QByteArray result = test.serialize(m_serializer.get());
|
||||
QCOMPARE(result, "{\"testRepeatedInt\":[1,0,321,65999,123245,3]}"_ba);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
|
||||
test.setTestRepeatedInt(QtProtobuf::uint32List());
|
||||
result = test.serialize(m_serializer.get());
|
||||
QCOMPARE(result, "{\"testRepeatedInt\":[]}"_ba);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
}
|
||||
|
||||
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);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
|
||||
test.setTestRepeatedInt(QtProtobuf::int64List());
|
||||
result = test.serialize(m_serializer.get());
|
||||
QCOMPARE(result, "{\"testRepeatedInt\":[]}"_ba);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
}
|
||||
|
||||
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);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
|
||||
test.setTestRepeatedInt(QtProtobuf::sint64List());
|
||||
result = test.serialize(m_serializer.get());
|
||||
QCOMPARE(result, "{\"testRepeatedInt\":[]}"_ba);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
}
|
||||
|
||||
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);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
|
||||
test.setTestRepeatedInt(QtProtobuf::uint64List());
|
||||
result = test.serialize(m_serializer.get());
|
||||
QCOMPARE(result, "{\"testRepeatedInt\":[]}"_ba);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
}
|
||||
|
||||
void QtProtobufRepeatedTypesJsonSerializationTest::RepeatedFixedIntMessageTest()
|
||||
{
|
||||
RepeatedFixedIntMessage test;
|
||||
test.setTestRepeatedInt({1, 321, 65999, 12324523, 3, 3, 0});
|
||||
QByteArray result = test.serialize(m_serializer.get());
|
||||
QCOMPARE(result, "{\"testRepeatedInt\":[1,321,65999,12324523,3,3,0]}"_ba);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
|
||||
test.setTestRepeatedInt(QtProtobuf::fixed32List());
|
||||
result = test.serialize(m_serializer.get());
|
||||
QCOMPARE(result, "{\"testRepeatedInt\":[]}"_ba);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
}
|
||||
|
||||
void QtProtobufRepeatedTypesJsonSerializationTest::RepeatedSFixedIntMessageTest()
|
||||
{
|
||||
RepeatedSFixedIntMessage test;
|
||||
test.setTestRepeatedInt({0, 1, 321, -65999, 12324523, -3, 3});
|
||||
QByteArray result = test.serialize(m_serializer.get());
|
||||
QCOMPARE(result, "{\"testRepeatedInt\":[0,1,321,-65999,12324523,-3,3]}"_ba);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
|
||||
test.setTestRepeatedInt(QtProtobuf::sfixed32List());
|
||||
result = test.serialize(m_serializer.get());
|
||||
QCOMPARE(result, "{\"testRepeatedInt\":[]}"_ba);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
}
|
||||
|
||||
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);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
|
||||
test.setTestRepeatedInt(QtProtobuf::fixed64List());
|
||||
result = test.serialize(m_serializer.get());
|
||||
QCOMPARE(result, "{\"testRepeatedInt\":[]}"_ba);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
}
|
||||
|
||||
void QtProtobufRepeatedTypesJsonSerializationTest::RepeatedSFixedInt64MessageTest()
|
||||
{
|
||||
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);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
|
||||
test.setTestRepeatedInt(QtProtobuf::sfixed64List());
|
||||
result = test.serialize(m_serializer.get());
|
||||
QCOMPARE(result, "{\"testRepeatedInt\":[]}"_ba);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
}
|
||||
|
||||
void QtProtobufRepeatedTypesJsonSerializationTest::RepeatedStringMessageTest()
|
||||
{
|
||||
RepeatedStringMessage test;
|
||||
test.setTestRepeatedString({"aaaa","bbbbb","ccc","dddddd","eeeee", ""});
|
||||
QByteArray result = test.serialize(m_serializer.get());
|
||||
QCOMPARE(result,
|
||||
"{\"testRepeatedString\":[\"aaaa\",\"bbbbb\",\"ccc\",\"dddddd\",\"eeeee\",\"\"]}"_ba);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
|
||||
test.setTestRepeatedString(QStringList());
|
||||
result = test.serialize(m_serializer.get());
|
||||
QCOMPARE(result, "{\"testRepeatedString\":[]}"_ba);
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
}
|
||||
|
||||
void QtProtobufRepeatedTypesJsonSerializationTest::RepeatedFloatMessageTest()
|
||||
{
|
||||
RepeatedFloatMessage test;
|
||||
test.setTestRepeatedFloat({0.4f, 1.2f, 0.5f, 3.912348f, 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);
|
||||
|
||||
test.setTestRepeatedFloat(QtProtobuf::floatList());
|
||||
result = test.serialize(m_serializer.get());
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
QCOMPARE(result, "{\"testRepeatedFloat\":[]}"_ba);
|
||||
}
|
||||
|
||||
void QtProtobufRepeatedTypesJsonSerializationTest::RepeatedDoubleMessageTest()
|
||||
{
|
||||
RepeatedDoubleMessage test;
|
||||
test.setTestRepeatedDouble({0.1, 0.2, 0.3, 3.912348239293, 0.5});
|
||||
QByteArray result = test.serialize(m_serializer.get());
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
QCOMPARE(result, "{\"testRepeatedDouble\":[0.1,0.2,0.3,3.912348239293,0.5]}"_ba);
|
||||
|
||||
test.setTestRepeatedDouble(QtProtobuf::doubleList());
|
||||
result = test.serialize(m_serializer.get());
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
QCOMPARE(result, "{\"testRepeatedDouble\":[]}"_ba);
|
||||
}
|
||||
|
||||
void QtProtobufRepeatedTypesJsonSerializationTest::RepeatedBytesMessageTest()
|
||||
{
|
||||
RepeatedBytesMessage test;
|
||||
test.setTestRepeatedBytes({QByteArray::fromHex("010203040506"),
|
||||
QByteArray::fromHex("ffffffff"),
|
||||
QByteArray::fromHex("eaeaeaeaea"),
|
||||
QByteArray::fromHex("010203040506")});
|
||||
QByteArray result = test.serialize(m_serializer.get());
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
QCOMPARE(result,
|
||||
"{\"testRepeatedBytes\":[\"AQIDBAUG\",\"/////w==\",\"6urq6uo=\",\"AQIDBAUG\"]}"_ba);
|
||||
|
||||
test.setTestRepeatedBytes(QByteArrayList());
|
||||
result = test.serialize(m_serializer.get());
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
QCOMPARE(result, "{\"testRepeatedBytes\":[]}"_ba);
|
||||
|
||||
test.setTestRepeatedBytes({QByteArray::fromHex("010203040506"),
|
||||
QByteArray::fromHex(""),
|
||||
QByteArray::fromHex("eaeaeaeaea"),
|
||||
QByteArray::fromHex("010203040506")});
|
||||
result = test.serialize(m_serializer.get());
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
QCOMPARE(result,
|
||||
"{\"testRepeatedBytes\":[\"AQIDBAUG\",\"\",\"6urq6uo=\",\"AQIDBAUG\"]}"_ba);
|
||||
}
|
||||
|
||||
void QtProtobufRepeatedTypesJsonSerializationTest::RepeatedComplexMessageTest()
|
||||
{
|
||||
SimpleStringMessage stringMsg;
|
||||
stringMsg.setTestFieldString("qwerty");
|
||||
ComplexMessage msg;
|
||||
msg.setTestFieldInt(25);
|
||||
msg.setTestComplexField(stringMsg);
|
||||
RepeatedComplexMessage test;
|
||||
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);
|
||||
|
||||
test.setTestRepeatedComplex({});
|
||||
result = test.serialize(m_serializer.get());
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
QCOMPARE(result, "{\"testRepeatedComplex\":[]}"_ba);
|
||||
}
|
||||
|
||||
void QtProtobufRepeatedTypesJsonSerializationTest::RepeatedBoolMessageTest()
|
||||
{
|
||||
RepeatedBoolMessage boolMsg;
|
||||
boolMsg.setTestRepeatedBool({ true, true, true, false, false, false, false, false,
|
||||
false, false, false, false, true });
|
||||
QByteArray result = boolMsg.serialize(m_serializer.get());
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
QCOMPARE(result, "{\"testRepeatedBool\":[true,true,true,false,false,false,false,"
|
||||
"false,false,false,false,false,true]}"_ba);
|
||||
|
||||
boolMsg.setTestRepeatedBool(QtProtobuf::boolList());
|
||||
result = boolMsg.serialize(m_serializer.get());
|
||||
QVERIFY(!QJsonDocument::fromJson(result).isNull());
|
||||
QCOMPARE(result, "{\"testRepeatedBool\":[]}"_ba);
|
||||
}
|
||||
|
||||
QTEST_MAIN(QtProtobufRepeatedTypesJsonSerializationTest)
|
||||
#include "tst_protobuf_serialization_json_repeatedtypes.moc"
|
||||
Loading…
Reference in New Issue