Add the packed attribute support for the message fields

Protobuf allows non-packed way of serialization of the repeated
fields. This is controlled on the protobuf schema level by adding the
'packed' attribute to a message field descriptor. If the attribute is
not set the default value is 'true', so all repeated messages should
use the 'packed' approach when serializing.

Fixes: QTBUG-103979
Change-Id: I078a18734785865a4b7b34190a642b82b7829755
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
Alexey Edelev 2022-11-16 14:59:48 +01:00
parent 11fe1e2e40
commit e1a4a1c531
7 changed files with 617 additions and 8 deletions

View File

@ -246,6 +246,43 @@ constexpr SerializerRegistryType<30> IntegratedTypesSerializers = { {
QT_CONSTRUCT_PROTOBUF_LIST_SERIALIZATION_HANDLER(QByteArrayList, QByteArray),
} };
#define QT_CONSTRUCT_PROTOBUF_NON_PACKED_LIST_SERIALIZATION_HANDLER(ListType, Type, WireType) \
{ \
QMetaType::fromType<ListType>(), \
QProtobufSerializerPrivate::serializeWrapper< \
ListType, \
QProtobufSerializerPrivate::serializeNonPackedListTypeCommon<Type, WireType>>, \
QProtobufSerializerPrivate::deserializeNonPackedList<Type>, WireType \
}
constexpr SerializerRegistryType<13> IntegratedNonPackedSerializers = { {
QT_CONSTRUCT_PROTOBUF_NON_PACKED_LIST_SERIALIZATION_HANDLER(
QtProtobuf::floatList, float, QtProtobuf::WireTypes::Fixed32),
QT_CONSTRUCT_PROTOBUF_NON_PACKED_LIST_SERIALIZATION_HANDLER(
QtProtobuf::doubleList, double, QtProtobuf::WireTypes::Fixed64),
QT_CONSTRUCT_PROTOBUF_NON_PACKED_LIST_SERIALIZATION_HANDLER(
QtProtobuf::int32List, QtProtobuf::int32, QtProtobuf::WireTypes::Varint),
QT_CONSTRUCT_PROTOBUF_NON_PACKED_LIST_SERIALIZATION_HANDLER(
QtProtobuf::int64List, QtProtobuf::int64, QtProtobuf::WireTypes::Varint),
QT_CONSTRUCT_PROTOBUF_NON_PACKED_LIST_SERIALIZATION_HANDLER(
QtProtobuf::uint32List, QtProtobuf::uint32, QtProtobuf::WireTypes::Varint),
QT_CONSTRUCT_PROTOBUF_NON_PACKED_LIST_SERIALIZATION_HANDLER(
QtProtobuf::uint64List, QtProtobuf::uint64, QtProtobuf::WireTypes::Varint),
QT_CONSTRUCT_PROTOBUF_NON_PACKED_LIST_SERIALIZATION_HANDLER(
QtProtobuf::sint32List, QtProtobuf::sint32, QtProtobuf::WireTypes::Varint),
QT_CONSTRUCT_PROTOBUF_NON_PACKED_LIST_SERIALIZATION_HANDLER(
QtProtobuf::sint64List, QtProtobuf::sint64, QtProtobuf::WireTypes::Varint),
QT_CONSTRUCT_PROTOBUF_NON_PACKED_LIST_SERIALIZATION_HANDLER(
QtProtobuf::fixed32List, QtProtobuf::fixed32, QtProtobuf::WireTypes::Fixed32),
QT_CONSTRUCT_PROTOBUF_NON_PACKED_LIST_SERIALIZATION_HANDLER(
QtProtobuf::fixed64List, QtProtobuf::fixed64, QtProtobuf::WireTypes::Fixed64),
QT_CONSTRUCT_PROTOBUF_NON_PACKED_LIST_SERIALIZATION_HANDLER(
QtProtobuf::sfixed32List, QtProtobuf::sfixed32, QtProtobuf::WireTypes::Fixed32),
QT_CONSTRUCT_PROTOBUF_NON_PACKED_LIST_SERIALIZATION_HANDLER(
QtProtobuf::sfixed64List, QtProtobuf::sfixed64, QtProtobuf::WireTypes::Fixed64),
QT_CONSTRUCT_PROTOBUF_NON_PACKED_LIST_SERIALIZATION_HANDLER(
QtProtobuf::boolList, QtProtobuf::boolean, QtProtobuf::WireTypes::Varint),
} };
template<std::size_t N>
std::optional<QProtobufSerializerPrivate::ProtobufSerializationHandler>
findIntegratedTypeHandlerImpl(QMetaType metaType, const SerializerRegistryType<N> &registry)
@ -261,8 +298,11 @@ findIntegratedTypeHandlerImpl(QMetaType metaType, const SerializerRegistryType<N
}
std::optional<QProtobufSerializerPrivate::ProtobufSerializationHandler>
findIntegratedTypeHandler(QMetaType metaType)
findIntegratedTypeHandler(QMetaType metaType, bool nonPacked)
{
if (nonPacked)
return findIntegratedTypeHandlerImpl(metaType, IntegratedNonPackedSerializers);
return findIntegratedTypeHandlerImpl(metaType, IntegratedTypesSerializers);
}
}
@ -558,7 +598,8 @@ QProtobufSerializerPrivate::serializeProperty(const QVariant &propertyValue,
QMetaType metaType = propertyValue.metaType();
//TODO: replace with some common function
auto basicHandler = findIntegratedTypeHandler(metaType);
auto basicHandler = findIntegratedTypeHandler(
metaType, fieldInfo.getFieldFlags() & QtProtobufPrivate::NonPacked);
if (basicHandler) {
type = basicHandler->wireType;
int fieldIndex = fieldInfo.getFieldNumber();
@ -613,7 +654,8 @@ bool QProtobufSerializerPrivate::deserializeProperty(QObject *object, const QtPr
QMetaType metaType = metaProperty.metaType();
//TODO: replace with some common function
auto basicHandler = findIntegratedTypeHandler(metaType);
auto basicHandler = findIntegratedTypeHandler(
metaType, ordering.getFieldFlags(index) & QtProtobufPrivate::NonPacked);
if (basicHandler) {
basicHandler->deserializer(it, newPropertyValue);
} else {
@ -656,7 +698,7 @@ bool QProtobufSerializerPrivate::deserializeMapPair(QVariant &key, QVariant &val
if (mapIndex == 1) {
//Only simple types are supported as keys
QMetaType metaType = key.metaType();
auto basicHandler = findIntegratedTypeHandler(metaType);
auto basicHandler = findIntegratedTypeHandler(metaType, false);
if (!basicHandler) {
// clang-format off
QString errorStr = QCoreApplication::tr("QtProtobuf",
@ -671,7 +713,7 @@ bool QProtobufSerializerPrivate::deserializeMapPair(QVariant &key, QVariant &val
} else {
//TODO: replace with some common function
QMetaType metaType = value.metaType();
auto basicHandler = findIntegratedTypeHandler(metaType);
auto basicHandler = findIntegratedTypeHandler(metaType, false);
if (basicHandler) {
basicHandler->deserializer(it, value);
} else {

View File

@ -259,6 +259,35 @@ public:
return serializedList;
}
template<typename V, QtProtobuf::WireTypes W,
typename std::enable_if_t<std::is_integral<V>::value
|| std::is_same<V, QtProtobuf::fixed32>::value
|| std::is_same<V, QtProtobuf::sfixed32>::value
|| std::is_same<V, float>::value
|| std::is_same<V, QtProtobuf::fixed64>::value
|| std::is_same<V, QtProtobuf::sfixed64>::value
|| std::is_same<V, double>::value
|| std::is_same<QtProtobuf::int32, V>::value
|| std::is_same<QtProtobuf::int64, V>::value,
int> = 0>
static QByteArray serializeNonPackedListTypeCommon(const QList<V> &listValue,
int &outFieldIndex)
{
qProtoDebug("listValue.count %" PRIdQSIZETYPE " outFieldIndex %d", listValue.count(),
outFieldIndex);
QByteArray header = QProtobufSerializerPrivate::encodeHeader(outFieldIndex, W);
outFieldIndex = QtProtobufPrivate::NotUsedFieldIndex;
QByteArray serializedList;
for (auto &value : listValue) {
serializedList.append(header);
QByteArray element = serializeBasic<V>(value, outFieldIndex);
if (element.isEmpty())
element.append('\0');
serializedList.append(element);
}
return serializedList;
}
//###########################################################################
// Deserializers
//###########################################################################
@ -406,6 +435,21 @@ public:
return true;
}
template<typename V>
Q_REQUIRED_RESULT static bool deserializeNonPackedList(QProtobufSelfcheckIterator &it,
QVariant &previousValue)
{
qProtoDebug("currentByte: 0x%x", *it);
QVariant variantValue;
if (deserializeBasic<V>(it, variantValue)) {
auto out = previousValue.value<QList<V>>();
qProtoDebug() << out;
out.append(variantValue.value<V>());
previousValue.setValue(out);
}
return false;
}
//###########################################################################
// Common functions
//###########################################################################

View File

@ -22,7 +22,7 @@ QT_BEGIN_NAMESPACE
namespace QtProtobufPrivate {
enum FieldFlag : uint { NoFlags = 0x0 };
enum FieldFlag : uint { NoFlags = 0x0, NonPacked = 0x1 };
struct QProtobufPropertyOrdering
{

View File

@ -489,7 +489,7 @@ const Descriptor *common::findHighestMessage(const Descriptor *message)
return highestMessage;
}
std::string common::collectFieldFlags([[maybe_unused]] const FieldDescriptor *field)
std::string common::collectFieldFlags(const FieldDescriptor *field)
{
std::string_view separator = " | ";
std::string_view active_separator;
@ -502,7 +502,16 @@ std::string common::collectFieldFlags([[maybe_unused]] const FieldDescriptor *fi
active_separator = separator;
};
writeFlag("NoFlags");
if (field->type() != FieldDescriptor::TYPE_STRING
&& field->type() != FieldDescriptor::TYPE_BYTES
&& field->type() != FieldDescriptor::TYPE_MESSAGE
&& field->type() != FieldDescriptor::TYPE_ENUM && !field->is_map() && field->is_repeated()
&& !field->is_packed()) {
writeFlag("NonPacked");
}
if (flags.empty())
writeFlag("NoFlags");
return flags;
}

View File

@ -146,6 +146,22 @@ qt_internal_add_test(tst_protobuf_deserialization_maptypes
tst_protobuf_maptypes_gen
)
qt_internal_add_test(tst_protobuf_non_packed_repeatedtypes
SOURCES
tst_protobuf_non_packed_repeatedtypes.cpp
LIBRARIES
Qt::Test
Qt::CorePrivate
)
qt6_add_protobuf(tst_protobuf_non_packed_repeatedtypes
PROTO_FILES
proto/repeatednonpackedmessages.proto
FIELD_ENUM
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/qt_protobuf_generated"
)
qt_autogen_tools_initial_setup(tst_protobuf_non_packed_repeatedtypes)
if(UNIX AND NOT CMAKE_CROSSCOMPILING)
qt_internal_add_test(tst_protobuf_internals
SOURCES

View File

@ -0,0 +1,74 @@
syntax = "proto3";
package qtprotobufnamespace.tests;
message RepeatedNonPackedIntMessage
{
repeated int32 testRepeatedInt = 1 [ packed = false ];
}
message RepeatedNonPackedSIntMessage
{
repeated sint32 testRepeatedInt = 1 [ packed = false ];
}
message RepeatedNonPackedUIntMessage
{
repeated uint32 testRepeatedInt = 1 [ packed = false ];
}
message RepeatedNonPackedInt64Message
{
repeated int64 testRepeatedInt = 1 [ packed = false ];
}
message RepeatedNonPackedSInt64Message
{
repeated sint64 testRepeatedInt = 1 [ packed = false ];
}
message RepeatedNonPackedUInt64Message
{
repeated uint64 testRepeatedInt = 1 [ packed = false ];
}
message RepeatedNonPackedFixedIntMessage
{
repeated fixed32 testRepeatedInt = 1 [ packed = false ];
}
message RepeatedNonPackedSFixedIntMessage
{
repeated sfixed32 testRepeatedInt = 1 [ packed = false ];
}
message RepeatedNonPackedFixedInt64Message
{
repeated fixed64 testRepeatedInt = 1 [ packed = false ];
}
message RepeatedNonPackedSFixedInt64Message
{
repeated sfixed64 testRepeatedInt = 1 [ packed = false ];
}
message RepeatedNonPackedBoolMessage
{
repeated bool testRepeatedBool = 1 [ packed = false ];
}
message RepeatedNonPackedDoubleMessage
{
repeated double testRepeatedDouble = 1 [ packed = false ];
}
message RepeatedNonPackedFloatMessage
{
repeated float testRepeatedFloat = 1 [ packed = false ];
}
message NonPackedIntMessageWithExtraMember
{
repeated int32 testRepeatedInt = 1 [ packed = false ];
string extra = 2;
}

View File

@ -0,0 +1,424 @@
// Copyright (C) 2022 The Qt Company Ltd.
// Copyright (C) 2022 Alexey Edelev <semlanik@gmail.com>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "repeatednonpackedmessages.qpb.h"
#include <QtTest/QtTest>
#include <QProtobufSerializer>
class QtProtobufNonPackedRepeatedTypesTest : public QObject
{
Q_OBJECT
private slots:
void init() { m_serializer.reset(new QProtobufSerializer); }
void RepeatedIntNonPackedMessageSerializerTest();
void RepeatedSIntNonPackedMessageSerializerTest();
void RepeatedUIntNonPackedMessageSerializerTest();
void RepeatedInt64NonPackedMessageSerializerTest();
void RepeatedSInt64NonPackedMessageSerializerTest();
void RepeatedUInt64NonPackedMessageSerializerTest();
void RepeatedFixedIntNonPackedMessageSerializerTest();
void RepeatedSFixedIntNonPackedMessageSerializerTest();
void RepeatedFixedInt64NonPackedMessageSerializerTest();
void RepeatedSFixedInt64NonPackedMessageSerializerTest();
void RepeatedFloatNonPackedMessageSerializerTest();
void RepeatedDoubleNonPackedMessageSerializerTest();
void RepeatedBoolNonPackedMessageSerializerTest();
void RepeatedIntNonPackedMessageDeserializerTest();
void NonPackedIntWithInterleavedExtra();
void RepeatedSIntNonPackedMessageDeserializerTest();
void RepeatedUIntNonPackedMessageDeserializerTest();
void RepeatedInt64NonPackedMessageDeserializerTest();
void RepeatedSInt64NonPackedMessageDeserializerTest();
void RepeatedUInt64NonPackedMessageDeserializerTest();
void RepeatedFixedIntNonPackedMessageDeserializerTest();
void RepeatedSFixedIntNonPackedMessageDeserializerTest();
void RepeatedFixedInt64NonPackedMessageDeserializerTest();
void RepeatedSFixedInt64NonPackedMessageDeserializerTest();
void RepeatedFloatNonPackedMessageDeserializerTest();
void RepeatedDoubleNonPackedMessageDeserializerTest();
void RepeatedBoolNonPackedMessageDeserializerTest();
private:
std::unique_ptr<QProtobufSerializer> m_serializer;
};
using namespace qtprotobufnamespace::tests;
void QtProtobufNonPackedRepeatedTypesTest::RepeatedIntNonPackedMessageSerializerTest()
{
RepeatedNonPackedIntMessage test;
test.setTestRepeatedInt({ 0, 1, 0, 321, 0, -65999, 123245, -3, 3, 0,
std::numeric_limits<int16_t>::min(),
std::numeric_limits<int32_t>::min() });
QByteArray result = test.serialize(m_serializer.get());
QString expectedResult =
QString("08000801080008c102080008b1fcfbffffffffffff0108edc20708fdffffffffffffffff010803"
"0800088080feffffffffffff010880808080f8ffffffff01");
QCOMPARE(result.toHex(), expectedResult);
test.setTestRepeatedInt(QtProtobuf::int32List());
result = test.serialize(m_serializer.get());
QVERIFY(result.isEmpty());
}
void QtProtobufNonPackedRepeatedTypesTest::RepeatedSIntNonPackedMessageSerializerTest()
{
RepeatedNonPackedSIntMessage test;
test.setTestRepeatedInt({ 1, 0, 321, 0, -65999, 123245, -3, 3, 0,
std::numeric_limits<int16_t>::min(),
std::numeric_limits<int32_t>::min() });
QByteArray result = test.serialize(m_serializer.get());
QString expectedResult =
QString("080208000882050800089d870808da850f08050806080008ffff0308ffffffff0f");
QCOMPARE(result.toHex(), expectedResult);
test.setTestRepeatedInt(QtProtobuf::sint32List());
result = test.serialize(m_serializer.get());
QVERIFY(result.isEmpty());
}
void QtProtobufNonPackedRepeatedTypesTest::RepeatedUIntNonPackedMessageSerializerTest()
{
RepeatedNonPackedUIntMessage test;
test.setTestRepeatedInt({ 1, 0, 321, 0, 123245, 3, 0, std::numeric_limits<uint16_t>::max(),
std::numeric_limits<uint32_t>::max() });
QByteArray result = test.serialize(m_serializer.get());
QString expectedResult = QString("0801080008c102080008edc2070803080008ffff0308ffffffff0f");
QCOMPARE(result.toHex(), expectedResult);
test.setTestRepeatedInt(QtProtobuf::uint32List());
result = test.serialize(m_serializer.get());
QVERIFY(result.isEmpty());
}
void QtProtobufNonPackedRepeatedTypesTest::RepeatedInt64NonPackedMessageSerializerTest()
{
RepeatedNonPackedInt64Message test;
test.setTestRepeatedInt({ 0, 1, 0, 321, 0, -65999, 123245, -3, 3, 0,
std::numeric_limits<int16_t>::min(),
std::numeric_limits<int64_t>::min() });
QByteArray result = test.serialize(m_serializer.get());
QString expectedResult =
QString("08000801080008c102080008b1fcfbffffffffffff0108edc20708fdffffffffffffffff010803"
"0800088080feffffffffffff010880808080808080808001");
QCOMPARE(result.toHex(), expectedResult);
test.setTestRepeatedInt(QtProtobuf::int64List());
result = test.serialize(m_serializer.get());
QVERIFY(result.isEmpty());
}
void QtProtobufNonPackedRepeatedTypesTest::RepeatedSInt64NonPackedMessageSerializerTest()
{
RepeatedNonPackedSInt64Message test;
test.setTestRepeatedInt({ 1, 0, 321, 0, -65999, 123245, -3, 3, 0,
std::numeric_limits<int16_t>::min(),
std::numeric_limits<int64_t>::min() });
QByteArray result = test.serialize(m_serializer.get());
QString expectedResult =
QString("080208000882050800089d870808da850f08050806080008ffff0308ffffffffffffffffff01");
QCOMPARE(result.toHex(), expectedResult);
test.setTestRepeatedInt(QtProtobuf::sint64List());
result = test.serialize(m_serializer.get());
QVERIFY(result.isEmpty());
}
void QtProtobufNonPackedRepeatedTypesTest::RepeatedUInt64NonPackedMessageSerializerTest()
{
RepeatedNonPackedUInt64Message test;
test.setTestRepeatedInt({ 1, 0, 321, 0, 123245, 3, 0, std::numeric_limits<uint16_t>::max(),
std::numeric_limits<uint64_t>::max() });
QByteArray result = test.serialize(m_serializer.get());
QString expectedResult =
QString("0801080008c102080008edc2070803080008ffff0308ffffffffffffffffff01");
QCOMPARE(result.toHex(), expectedResult);
test.setTestRepeatedInt(QtProtobuf::uint64List());
result = test.serialize(m_serializer.get());
QVERIFY(result.isEmpty());
}
void QtProtobufNonPackedRepeatedTypesTest::RepeatedFixedIntNonPackedMessageSerializerTest()
{
RepeatedNonPackedFixedIntMessage test;
test.setTestRepeatedInt({ 1, 0, 321, 0, 123245, 3, 0, std::numeric_limits<uint16_t>::max(),
std::numeric_limits<uint32_t>::max() });
QByteArray result = test.serialize(m_serializer.get());
QString expectedResult = QString("0d010000000d000000000d410100000d000000000d6de101000d030000000"
"d000000000dffff00000dffffffff");
QCOMPARE(result.toHex(), expectedResult);
test.setTestRepeatedInt(QtProtobuf::fixed32List());
result = test.serialize(m_serializer.get());
QVERIFY(result.isEmpty());
}
void QtProtobufNonPackedRepeatedTypesTest::RepeatedSFixedIntNonPackedMessageSerializerTest()
{
RepeatedNonPackedSFixedIntMessage test;
test.setTestRepeatedInt({ 1, 0, 321, 0, -65999, 123245, -3, 3, 0,
std::numeric_limits<int16_t>::min(),
std::numeric_limits<int32_t>::min() });
QByteArray result = test.serialize(m_serializer.get());
QString expectedResult = QString("0d010000000d000000000d410100000d000000000d31fefeff0d6de101000"
"dfdffffff0d030000000d000000000d0080ffff0d00000080");
QCOMPARE(result.toHex(), expectedResult);
test.setTestRepeatedInt(QtProtobuf::sfixed32List());
result = test.serialize(m_serializer.get());
QVERIFY(result.isEmpty());
}
void QtProtobufNonPackedRepeatedTypesTest::RepeatedFixedInt64NonPackedMessageSerializerTest()
{
RepeatedNonPackedFixedInt64Message test;
test.setTestRepeatedInt({ 1, 0, 321, 0, 123245, 3, 0, std::numeric_limits<uint16_t>::max(),
std::numeric_limits<uint64_t>::max() });
QByteArray result = test.serialize(m_serializer.get());
QString expectedResult = QString(
"090100000000000000090000000000000000094101000000000000090000000000000000096de101000000"
"000009030000000000000009000000000000000009ffff00000000000009ffffffffffffffff");
QCOMPARE(result.toHex(), expectedResult);
test.setTestRepeatedInt(QtProtobuf::fixed64List());
result = test.serialize(m_serializer.get());
QVERIFY(result.isEmpty());
}
void QtProtobufNonPackedRepeatedTypesTest::RepeatedSFixedInt64NonPackedMessageSerializerTest()
{
RepeatedNonPackedSFixedInt64Message test;
test.setTestRepeatedInt({ 1, 0, 321, 0, -65999, 123245, -3, 3, 0,
std::numeric_limits<int16_t>::min(),
std::numeric_limits<int64_t>::min() });
QByteArray result = test.serialize(m_serializer.get());
QString expectedResult =
QString("0901000000000000000900000000000000000941010000000000000900000000000000000931fe"
"feffffffffff096de101000000000009fdffffffffffffff090300000000000000090000000000"
"000000090080ffffffffffff090000000000000080");
QCOMPARE(result.toHex(), expectedResult);
test.setTestRepeatedInt(QtProtobuf::sfixed64List());
result = test.serialize(m_serializer.get());
QVERIFY(result.isEmpty());
}
void QtProtobufNonPackedRepeatedTypesTest::RepeatedDoubleNonPackedMessageSerializerTest()
{
RepeatedNonPackedDoubleMessage test;
test.setTestRepeatedDouble({ 0.1, 0.2, 0.3, 0.4, 0.5, 0.0 });
QByteArray result = test.serialize(m_serializer.get());
QString expectedResult = QString("099a9999999999b93f099a9999999999c93f09333333333333d33f099a999"
"9999999d93f09000000000000e03f090000000000000000");
QCOMPARE(result.toHex(), expectedResult);
test.setTestRepeatedDouble(QtProtobuf::doubleList());
result = test.serialize(m_serializer.get());
QVERIFY(result.isEmpty());
}
void QtProtobufNonPackedRepeatedTypesTest::RepeatedFloatNonPackedMessageSerializerTest()
{
RepeatedNonPackedFloatMessage test;
test.setTestRepeatedFloat({ 0.0, 0.4f, 1.2f, 0.5f, 1.4f, 0.6f });
QByteArray result = test.serialize(m_serializer.get());
QString expectedResult =
QString("0d000000000dcdcccc3e0d9a99993f0d0000003f0d3333b33f0d9a99193f");
QCOMPARE(result.toHex(), expectedResult);
test.setTestRepeatedFloat(QtProtobuf::floatList());
result = test.serialize(m_serializer.get());
QVERIFY(result.isEmpty());
}
void QtProtobufNonPackedRepeatedTypesTest::RepeatedBoolNonPackedMessageSerializerTest()
{
RepeatedNonPackedBoolMessage boolMsg;
boolMsg.setTestRepeatedBool({ true, true, true, false, false, true, false, false, false, false,
false, false, true });
QByteArray result = boolMsg.serialize(m_serializer.get());
QString expectedResult = QString("0801080108010800080008010800080008000800080008000801");
QCOMPARE(result.toHex(), expectedResult);
}
void QtProtobufNonPackedRepeatedTypesTest::RepeatedIntNonPackedMessageDeserializerTest()
{
RepeatedNonPackedIntMessage test;
test.deserialize(
m_serializer.get(),
QByteArray::fromHex(
"08000801080008c102080008b1fcfbffffffffffff0108edc20708fdffffffffffffffff010803"
"0800088080feffffffffffff010880808080f8ffffffff01"));
QCOMPARE(test.testRepeatedInt().count(), 12);
QCOMPARE(test.testRepeatedInt(),
QtProtobuf::int32List({ 0, 1, 0, 321, 0, -65999, 123245, -3, 3, 0,
std::numeric_limits<int16_t>::min(),
std::numeric_limits<int32_t>::min() }));
}
void QtProtobufNonPackedRepeatedTypesTest::NonPackedIntWithInterleavedExtra()
{
NonPackedIntMessageWithExtraMember test;
// [0, 1], "242", [3] - the two arrays are actually the same,
// but the entries are separated by a string.
QByteArray input = QByteArray::fromHex("0800080112033234320803");
test.deserialize(m_serializer.get(), input);
QCOMPARE(test.testRepeatedInt().count(), 3);
QCOMPARE(test.testRepeatedInt(), QtProtobuf::int32List({ 0, 1, 3 }));
QCOMPARE(test.extra(), "242");
}
void QtProtobufNonPackedRepeatedTypesTest::RepeatedSIntNonPackedMessageDeserializerTest()
{
RepeatedNonPackedSIntMessage test;
test.deserialize(m_serializer.get(),
QByteArray::fromHex(
"080208000882050800089d870808da850f08050806080008ffff0308ffffffff0f"));
QCOMPARE(test.testRepeatedInt().count(), 11);
QCOMPARE(test.testRepeatedInt(),
QtProtobuf::sint32List({ 1, 0, 321, 0, -65999, 123245, -3, 3, 0,
std::numeric_limits<int16_t>::min(),
std::numeric_limits<int32_t>::min() }));
}
void QtProtobufNonPackedRepeatedTypesTest::RepeatedUIntNonPackedMessageDeserializerTest()
{
RepeatedNonPackedUIntMessage test;
test.deserialize(m_serializer.get(),
QByteArray::fromHex("0801080008c102080008edc2070803080008ffff0308ffffffff0f"));
QCOMPARE(test.testRepeatedInt().count(), 9);
QCOMPARE(test.testRepeatedInt(),
QtProtobuf::uint32List({ 1, 0, 321, 0, 123245, 3, 0,
std::numeric_limits<uint16_t>::max(),
std::numeric_limits<uint32_t>::max() }));
}
void QtProtobufNonPackedRepeatedTypesTest::RepeatedInt64NonPackedMessageDeserializerTest()
{
RepeatedNonPackedInt64Message test;
test.deserialize(
m_serializer.get(),
QByteArray::fromHex(
"08000801080008c102080008b1fcfbffffffffffff0108edc20708fdffffffffffffffff010803"
"0800088080feffffffffffff010880808080808080808001"));
QCOMPARE(test.testRepeatedInt().count(), 12);
QCOMPARE(test.testRepeatedInt(),
QtProtobuf::int64List({ 0, 1, 0, 321, 0, -65999, 123245, -3, 3, 0,
std::numeric_limits<int16_t>::min(),
std::numeric_limits<int64_t>::min() }));
}
void QtProtobufNonPackedRepeatedTypesTest::RepeatedSInt64NonPackedMessageDeserializerTest()
{
RepeatedNonPackedSInt64Message test;
test.deserialize(m_serializer.get(),
QByteArray::fromHex("080208000882050800089d870808da850f08050806080008ffff0308f"
"fffffffffffffffff01"));
QCOMPARE(test.testRepeatedInt().count(), 11);
QCOMPARE(test.testRepeatedInt(),
QtProtobuf::sint64List({ 1, 0, 321, 0, -65999, 123245, -3, 3, 0,
std::numeric_limits<int16_t>::min(),
std::numeric_limits<int64_t>::min() }));
}
void QtProtobufNonPackedRepeatedTypesTest::RepeatedUInt64NonPackedMessageDeserializerTest()
{
RepeatedNonPackedUInt64Message test;
test.deserialize(m_serializer.get(),
QByteArray::fromHex(
"0801080008c102080008edc2070803080008ffff0308ffffffffffffffffff01"));
QCOMPARE(test.testRepeatedInt().count(), 9);
QCOMPARE(test.testRepeatedInt(),
QtProtobuf::uint64List({ 1, 0, 321, 0, 123245, 3, 0,
std::numeric_limits<uint16_t>::max(),
std::numeric_limits<uint64_t>::max() }));
}
void QtProtobufNonPackedRepeatedTypesTest::RepeatedFixedIntNonPackedMessageDeserializerTest()
{
RepeatedNonPackedFixedIntMessage test;
test.deserialize(
m_serializer.get(),
QByteArray::fromHex("0d010000000d000000000d410100000d000000000d6de101000d030000000"
"d000000000dffff00000dffffffff"));
QCOMPARE(test.testRepeatedInt().count(), 9);
QCOMPARE(test.testRepeatedInt(),
QtProtobuf::fixed32List({ 1, 0, 321, 0, 123245, 3, 0,
std::numeric_limits<uint16_t>::max(),
std::numeric_limits<uint32_t>::max() }));
}
void QtProtobufNonPackedRepeatedTypesTest::RepeatedSFixedIntNonPackedMessageDeserializerTest()
{
RepeatedNonPackedSFixedIntMessage test;
test.deserialize(
m_serializer.get(),
QByteArray::fromHex("0d010000000d000000000d410100000d000000000d31fefeff0d6de101000"
"dfdffffff0d030000000d000000000d0080ffff0d00000080"));
QCOMPARE(test.testRepeatedInt().count(), 11);
QCOMPARE(test.testRepeatedInt(),
QtProtobuf::sfixed32List({ 1, 0, 321, 0, -65999, 123245, -3, 3, 0,
std::numeric_limits<int16_t>::min(),
std::numeric_limits<int32_t>::min() }));
}
void QtProtobufNonPackedRepeatedTypesTest::RepeatedFixedInt64NonPackedMessageDeserializerTest()
{
RepeatedNonPackedFixedInt64Message test;
test.deserialize(m_serializer.get(),
QByteArray::fromHex("090100000000000000090000000000000000094101000000000000090"
"000000000000000096de101000000"
"000009030000000000000009000000000000000009ffff00000000000"
"009ffffffffffffffff"));
QCOMPARE(test.testRepeatedInt().count(), 9);
QCOMPARE(test.testRepeatedInt(),
QtProtobuf::fixed64List({ 1, 0, 321, 0, 123245, 3, 0,
std::numeric_limits<uint16_t>::max(),
std::numeric_limits<uint64_t>::max() }));
}
void QtProtobufNonPackedRepeatedTypesTest::RepeatedSFixedInt64NonPackedMessageDeserializerTest()
{
RepeatedNonPackedSFixedInt64Message test;
test.deserialize(
m_serializer.get(),
QByteArray::fromHex(
"0901000000000000000900000000000000000941010000000000000900000000000000000931fe"
"feffffffffff096de101000000000009fdffffffffffffff090300000000000000090000000000"
"000000090080ffffffffffff090000000000000080"));
QCOMPARE(test.testRepeatedInt().count(), 11);
QCOMPARE(test.testRepeatedInt(),
QtProtobuf::sfixed64List({ 1, 0, 321, 0, -65999, 123245, -3, 3, 0,
std::numeric_limits<int16_t>::min(),
std::numeric_limits<int64_t>::min() }));
}
void QtProtobufNonPackedRepeatedTypesTest::RepeatedFloatNonPackedMessageDeserializerTest()
{
RepeatedNonPackedFloatMessage test;
test.deserialize(
m_serializer.get(),
QByteArray::fromHex("0d000000000dcdcccc3e0d9a99993f0d0000003f0d3333b33f0d9a99193f"));
QCOMPARE(test.testRepeatedFloat().count(), 6);
QCOMPARE(test.testRepeatedFloat(),
QtProtobuf::floatList({ 0.0, 0.4f, 1.2f, 0.5f, 1.4f, 0.6f }));
}
void QtProtobufNonPackedRepeatedTypesTest::RepeatedDoubleNonPackedMessageDeserializerTest()
{
RepeatedNonPackedDoubleMessage test;
test.deserialize(
m_serializer.get(),
QByteArray::fromHex("099a9999999999b93f099a9999999999c93f09333333333333d33f099a999"
"9999999d93f09000000000000e03f090000000000000000"));
QCOMPARE(test.testRepeatedDouble().count(), 6);
QCOMPARE(test.testRepeatedDouble(), QtProtobuf::doubleList({ 0.1, 0.2, 0.3, 0.4, 0.5, 0.0 }));
}
void QtProtobufNonPackedRepeatedTypesTest::RepeatedBoolNonPackedMessageDeserializerTest()
{
RepeatedNonPackedBoolMessage test;
test.deserialize(m_serializer.get(),
QByteArray::fromHex("0801080108010800080008010800080008000800080008000801"));
QCOMPARE(test.testRepeatedBool().count(), 13);
QCOMPARE(test.testRepeatedBool(),
QtProtobuf::boolList({ true, true, true, false, false, true, false, false, false,
false, false, false, true }));
}
QTEST_MAIN(QtProtobufNonPackedRepeatedTypesTest)
#include "tst_protobuf_non_packed_repeatedtypes.moc"