diff --git a/src/protobuf/qprotobufserializer.cpp b/src/protobuf/qprotobufserializer.cpp index cca4d927..3d7c3372 100644 --- a/src/protobuf/qprotobufserializer.cpp +++ b/src/protobuf/qprotobufserializer.cpp @@ -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(), \ + QProtobufSerializerPrivate::serializeWrapper< \ + ListType, \ + QProtobufSerializerPrivate::serializeNonPackedListTypeCommon>, \ + QProtobufSerializerPrivate::deserializeNonPackedList, 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::optional findIntegratedTypeHandlerImpl(QMetaType metaType, const SerializerRegistryType ®istry) @@ -261,8 +298,11 @@ findIntegratedTypeHandlerImpl(QMetaType metaType, const SerializerRegistryType -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 { diff --git a/src/protobuf/qprotobufserializer_p.h b/src/protobuf/qprotobufserializer_p.h index 670e23cc..37220369 100644 --- a/src/protobuf/qprotobufserializer_p.h +++ b/src/protobuf/qprotobufserializer_p.h @@ -259,6 +259,35 @@ public: return serializedList; } + template::value + || std::is_same::value + || std::is_same::value + || std::is_same::value + || std::is_same::value + || std::is_same::value + || std::is_same::value + || std::is_same::value + || std::is_same::value, + int> = 0> + static QByteArray serializeNonPackedListTypeCommon(const QList &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(value, outFieldIndex); + if (element.isEmpty()) + element.append('\0'); + serializedList.append(element); + } + return serializedList; + } + //########################################################################### // Deserializers //########################################################################### @@ -406,6 +435,21 @@ public: return true; } + template + Q_REQUIRED_RESULT static bool deserializeNonPackedList(QProtobufSelfcheckIterator &it, + QVariant &previousValue) + { + qProtoDebug("currentByte: 0x%x", *it); + QVariant variantValue; + if (deserializeBasic(it, variantValue)) { + auto out = previousValue.value>(); + qProtoDebug() << out; + out.append(variantValue.value()); + previousValue.setValue(out); + } + return false; + } + //########################################################################### // Common functions //########################################################################### diff --git a/src/protobuf/qtprotobuftypes.h b/src/protobuf/qtprotobuftypes.h index 603e7148..91fceb97 100644 --- a/src/protobuf/qtprotobuftypes.h +++ b/src/protobuf/qtprotobuftypes.h @@ -22,7 +22,7 @@ QT_BEGIN_NAMESPACE namespace QtProtobufPrivate { -enum FieldFlag : uint { NoFlags = 0x0 }; +enum FieldFlag : uint { NoFlags = 0x0, NonPacked = 0x1 }; struct QProtobufPropertyOrdering { diff --git a/src/tools/qtprotobufgen/generatorcommon.cpp b/src/tools/qtprotobufgen/generatorcommon.cpp index 4d23ff05..95788673 100644 --- a/src/tools/qtprotobufgen/generatorcommon.cpp +++ b/src/tools/qtprotobufgen/generatorcommon.cpp @@ -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; } diff --git a/tests/auto/protobuf/basic/CMakeLists.txt b/tests/auto/protobuf/basic/CMakeLists.txt index 42205522..68d968e6 100644 --- a/tests/auto/protobuf/basic/CMakeLists.txt +++ b/tests/auto/protobuf/basic/CMakeLists.txt @@ -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 diff --git a/tests/auto/protobuf/basic/proto/repeatednonpackedmessages.proto b/tests/auto/protobuf/basic/proto/repeatednonpackedmessages.proto new file mode 100644 index 00000000..40fe6f31 --- /dev/null +++ b/tests/auto/protobuf/basic/proto/repeatednonpackedmessages.proto @@ -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; +} diff --git a/tests/auto/protobuf/basic/tst_protobuf_non_packed_repeatedtypes.cpp b/tests/auto/protobuf/basic/tst_protobuf_non_packed_repeatedtypes.cpp new file mode 100644 index 00000000..e95d9382 --- /dev/null +++ b/tests/auto/protobuf/basic/tst_protobuf_non_packed_repeatedtypes.cpp @@ -0,0 +1,424 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// Copyright (C) 2022 Alexey Edelev +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "repeatednonpackedmessages.qpb.h" + +#include +#include + +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 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::min(), + std::numeric_limits::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::min(), + std::numeric_limits::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::max(), + std::numeric_limits::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::min(), + std::numeric_limits::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::min(), + std::numeric_limits::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::max(), + std::numeric_limits::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::max(), + std::numeric_limits::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::min(), + std::numeric_limits::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::max(), + std::numeric_limits::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::min(), + std::numeric_limits::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::min(), + std::numeric_limits::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::min(), + std::numeric_limits::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::max(), + std::numeric_limits::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::min(), + std::numeric_limits::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::min(), + std::numeric_limits::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::max(), + std::numeric_limits::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::max(), + std::numeric_limits::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::min(), + std::numeric_limits::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::max(), + std::numeric_limits::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::min(), + std::numeric_limits::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"