diff --git a/src/protobuf/qprotobufjsonserializer.cpp b/src/protobuf/qprotobufjsonserializer.cpp index e9f15fce..c16b2e10 100644 --- a/src/protobuf/qprotobufjsonserializer.cpp +++ b/src/protobuf/qprotobufjsonserializer.cpp @@ -676,8 +676,8 @@ void QProtobufJsonSerializer::serializeMapPair(const QVariant &key, const QVaria auto store = d_ptr->activeValue.toObject(); QJsonObject mapObject = store.value(fieldName).toObject(); d_ptr->activeValue = QJsonObject(); - d_ptr->serializeProperty(value, fieldInfo.infoForMapValue()); - mapObject.insert(key.toString(), d_ptr->activeValue.toObject().value(fieldName)); + d_ptr->serializeProperty(value, QProtobufSerializerPrivate::mapValueOrdering); + mapObject.insert(key.toString(), d_ptr->activeValue.toObject().value("value"_L1)); store.insert(fieldName, mapObject); d_ptr->activeValue = store; } diff --git a/src/protobuf/qprotobufserializer.cpp b/src/protobuf/qprotobufserializer.cpp index 50ff4037..24d5d482 100644 --- a/src/protobuf/qprotobufserializer.cpp +++ b/src/protobuf/qprotobufserializer.cpp @@ -108,6 +108,48 @@ using SerializerRegistryType = std::array; namespace { + +static constexpr struct { + QtProtobufPrivate::QProtobufPropertyOrdering::Data data; + const std::array qt_protobuf_Maptest_uint_data; + const char qt_protobuf_Maptest_char_data[23]; +} qt_protobuf_Maptest_metadata { + // data + { + 0, /* = version */ + 2, /* = num fields */ + 3, /* = field number offset */ + 5, /* = property index offset */ + 7, /* = field flags offset */ + 4, /* = message full name length */ + }, + // uint_data + { + // JSON name offsets: + 5, /* = key */ + 9, /* = value */ + 15, /* = end-of-string-marker */ + // Field numbers: + 1, /* = key */ + 2, /* = value */ + // Property indices: + 0, /* = key */ + 2, /* = value */ + // Field flags: + QtProtobufPrivate::Optional, /* = key */ + QtProtobufPrivate::Optional, /* = value */ + }, + // char_data + /* metadata char_data: */ + "pair\0" /* = full message name */ + /* field char_data: */ + "key\0value\0" +}; + +const QtProtobufPrivate::QProtobufPropertyOrdering mapPropertyOrdering = { + &qt_protobuf_Maptest_metadata.data +}; + #define QT_CONSTRUCT_PROTOBUF_SERIALIZATION_HANDLER(Type, WireType) \ { \ QMetaType::fromType(), \ @@ -266,6 +308,10 @@ QByteArray QProtobufSerializer::serializeMessage( return d_ptr->result; } +const QProtobufPropertyOrderingInfo QProtobufSerializerPrivate::mapValueOrdering{ + mapPropertyOrdering, 1 +}; + void QProtobufSerializerPrivate::serializeMessage(const QProtobufMessage *message, const QtProtobufPrivate::QProtobufPropertyOrdering &ordering) @@ -375,7 +421,7 @@ void QProtobufSerializer::serializeMapPair(const QVariant &key, const QVariant & ->serializer(key, QProtobufSerializerPrivate::encodeHeader(1, keyHandler->wireType))); - d_ptr->serializeProperty(value, fieldInfo.infoForMapValue()); + d_ptr->serializeProperty(value, QProtobufSerializerPrivate::mapValueOrdering); store.append(QProtobufSerializerPrivate::encodeHeader(fieldInfo.getFieldNumber(), QtProtobuf::WireTypes::LengthDelimited)); store.append(QProtobufSerializerPrivate::serializeVarintCommon(d_ptr->result.size())); diff --git a/src/protobuf/qprotobufserializer_p.h b/src/protobuf/qprotobufserializer_p.h index 93e7ab48..d0453167 100644 --- a/src/protobuf/qprotobufserializer_p.h +++ b/src/protobuf/qprotobufserializer_p.h @@ -523,6 +523,9 @@ public: QByteArray result; bool preserveUnknownFields = true; + + static const QtProtobufPrivate::QProtobufPropertyOrderingInfo mapValueOrdering; + private: Q_DISABLE_COPY_MOVE(QProtobufSerializerPrivate) QProtobufSerializer *q_ptr; diff --git a/src/protobuf/qtprotobuftypes.h b/src/protobuf/qtprotobuftypes.h index dfcf2763..ae4b9f2a 100644 --- a/src/protobuf/qtprotobuftypes.h +++ b/src/protobuf/qtprotobuftypes.h @@ -68,10 +68,6 @@ struct QProtobufPropertyOrderingInfo int getPropertyIndex() const { return ordering.getPropertyIndex(index); } uint getFieldFlags() const { return ordering.getFieldFlags(index); } - // Needed for maps, which uses field number 1 and 2 for key and value respectively - QProtobufPropertyOrderingInfo infoForMapKey() const { return { ordering, index, 1 }; } - QProtobufPropertyOrderingInfo infoForMapValue() const { return { ordering, index, 2 }; } - private: QProtobufPropertyOrderingInfo(QProtobufPropertyOrdering ord, int ind, int fieldNumber) : ordering(ord), index(ind), overrideFieldNumber(fieldNumber) diff --git a/tests/auto/protobuf/json/tst_protobuf_serialization_json_maptypes.cpp b/tests/auto/protobuf/json/tst_protobuf_serialization_json_maptypes.cpp index 43d389de..680699ea 100644 --- a/tests/auto/protobuf/json/tst_protobuf_serialization_json_maptypes.cpp +++ b/tests/auto/protobuf/json/tst_protobuf_serialization_json_maptypes.cpp @@ -50,7 +50,6 @@ void QtProtobufJsonMapTypesSerializationTest::SimpleFixed32StringMapSerializeTes { 15, { "fifteen" } }, { 0, { "" } } }); QByteArray result = test.serialize(m_serializer.get()); - QEXPECT_FAIL("", "Map value with no presence are ignored by json serializer.", Continue); QCOMPARE( result, "{\"mapField\":{\"0\":\"\",\"10\":\"ten\",\"15\":\"fifteen\",\"42\":\"fourty two\"}}"_ba);