Browse Source

Update serializers interface

- Change type of additional type-field in SerializationHandler structure
  It contains pseudo type of value to be serialized (Object, List, Map)
- Introduce QProtobufMetaProperty as extension for QMetaProperty. It
  additionaly contains protoFieldIndex and passes combained information
  to serialization routines
- Rework serialization interfaces to work with pre-allocated buffers,
  still in the progress
Alexey Edelev 5 years ago
parent
commit
acdd0d17d4

+ 4 - 2
src/protobuf/CMakeLists.txt

@@ -21,7 +21,8 @@ file(GLOB SOURCES
     qprotobufserializerregistry.cpp
     qabstractprotobufserializer.cpp
     qprotobufjsonserializer.cpp
-    qprotobufserializer.cpp)
+    qprotobufserializer.cpp
+    qprotobufmetaproperty.cpp)
 
 file(GLOB HEADERS
     qtprotobufglobal.h
@@ -49,7 +50,8 @@ file(GLOB PUBLIC_HEADERS
     qprotobufserializer.h
     qprotobufjsonserializer.h
     qprotobufselfcheckiterator.h
-    qprotobufregistrationhelper.h)
+    qprotobufregistrationhelper.h
+    qprotobufmetaproperty.h)
 
 add_library(${TARGET} SHARED ${SOURCES})
 target_compile_definitions(${TARGET} PRIVATE QT_BUILD_PROTOBUF_LIB PUBLIC QTPROTOBUF_VERSION_MAJOR=${PROJECT_VERSION_MAJOR}

+ 13 - 9
src/protobuf/qabstractprotobufserializer.h

@@ -40,6 +40,8 @@
 #include "qtprotobufglobal.h"
 
 namespace QtProtobuf {
+
+class QProtobufMetaProperty;
 /*!
 *  \addtogroup QtProtobuf
 *  \{
@@ -125,15 +127,17 @@ public:
      * \param[in] object Pointer to object to be serialized
      * \param[in] propertyOrdering Protobuf order of QObject properties
      * \param[in] metaObject Meta object information for given \a object
+     * \param[in] metaProperty information about property to be serialized
      * \return Raw serialized data represented as byte array
      */
-    virtual QByteArray serializeObject(const QObject *object, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject, int fieldIndex) const = 0;
+    virtual QByteArray serializeObject(const QObject *object, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject, const QProtobufMetaProperty &metaProperty) const = 0;
 
     /*!
      * \brief deserializeObject Deserializes buffer to an \a object
      * \param[out] object Pointer to allocated object
      * \param[in] it Pointer to beging of buffer where object serialized data is located
      * \param[in] propertyOrdering Ordering of properties for given \a object
+     * \param[in] metaProperty information about property to be serialized
      * \param[in] metaObject Static meta object of given \a object. Static meta object usualy is used to get actual
      *        property value and write new property to \a object
      */
@@ -144,10 +148,10 @@ public:
      * \param[in] object Pointer to object that will be serialized
      * \param[in] propertyOrdering Ordering of properties for given \a object
      * \param[in] metaObject Static meta object of given \a object
-     * \param[in] fieldIndex Index of list property in target message
+     * \param[in] metaProperty information about property to be serialized
      * \return Raw serialized data represented as byte array
      */
-    virtual QByteArray serializeListObject(const QObject *object, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject, int fieldIndex) const = 0;
+    virtual QByteArray serializeListObject(const QObject *object, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject, const QProtobufMetaProperty &metaProperty) const = 0;
 
     /*!
      * \brief deserializeListObject Deserializes an \a object from byte stream as part of list property
@@ -163,12 +167,12 @@ public:
      * \brief serializeMapPair Serializes QMap pair of \a key and \a value to raw data buffer
      * \param[in] key Map key
      * \param[in] value Map value for given \a key
-     * \param[in] fieldIndex Index of map property in message
+     * \param[in] metaProperty information about property to be serialized
      * \return Raw serialized data represented as byte array
      *
      * \see https://developers.google.com/protocol-buffers/docs/proto3#maps for details
      */
-    virtual QByteArray serializeMapPair(const QVariant &key, const QVariant &value, int fieldIndex) const = 0;
+    virtual QByteArray serializeMapPair(const QVariant &key, const QVariant &value, const QProtobufMetaProperty &metaProperty) const = 0;
 
     /*!
      * \brief deserializeMapPair Deserializes QMap pair of \a key and \a value from raw data
@@ -195,9 +199,9 @@ public:
 template<typename T>
 static void qRegisterProtobufType() {
     QtProtobufPrivate::registerHandler(qMetaTypeId<T *>(), { QtProtobufPrivate::serializeObject<T>,
-            QtProtobufPrivate::deserializeObject<T>, QtProtobuf::LengthDelimited });
+            QtProtobufPrivate::deserializeObject<T>, QtProtobufPrivate::ObjectHandler });
     QtProtobufPrivate::registerHandler(qMetaTypeId<QList<QSharedPointer<T>>>(), { QtProtobufPrivate::serializeList<T>,
-            QtProtobufPrivate::deserializeList<T>, QtProtobuf::LengthDelimited });
+            QtProtobufPrivate::deserializeList<T>, QtProtobufPrivate::ListHandler });
 }
 
 /*!
@@ -209,7 +213,7 @@ template<typename K, typename V,
          typename std::enable_if_t<!std::is_base_of<QObject, V>::value, int> = 0>
 inline void qRegisterProtobufMapType() {
     QtProtobufPrivate::registerHandler(qMetaTypeId<QMap<K, V>>(), { QtProtobufPrivate::serializeMap<K, V>,
-    QtProtobufPrivate::deserializeMap<K, V>, QtProtobuf::LengthDelimited });
+    QtProtobufPrivate::deserializeMap<K, V>, QtProtobufPrivate::MapHandler });
 }
 
 /*!
@@ -222,5 +226,5 @@ template<typename K, typename V,
          typename std::enable_if_t<std::is_base_of<QObject, V>::value, int> = 0>
 inline void qRegisterProtobufMapType() {
     QtProtobufPrivate::registerHandler(qMetaTypeId<QMap<K, QSharedPointer<V>>>(), { QtProtobufPrivate::serializeMap<K, V>,
-    QtProtobufPrivate::deserializeMap<K, V>, QtProtobuf::LengthDelimited });
+    QtProtobufPrivate::deserializeMap<K, V>, QtProtobufPrivate::MapHandler });
 }

+ 21 - 24
src/protobuf/qabstractprotobufserializer_p.h

@@ -38,25 +38,32 @@
 namespace QtProtobuf {
     class QAbstractProtobufSerializer;
     class QProtobufSelfcheckIterator;
+    class QProtobufMetaProperty;
 }
 
 namespace QtProtobufPrivate {
 //! \private
 constexpr int NotUsedFieldIndex = -1;
 
-using Serializer = std::function<QByteArray(const QtProtobuf::QAbstractProtobufSerializer *, const QVariant &, int)>;
+using Serializer = std::function<void(const QtProtobuf::QAbstractProtobufSerializer *, const QVariant &, const QtProtobuf::QProtobufMetaProperty &, QByteArray &)>;
 /*!
  * \brief Deserializer is interface function for deserialize method
  */
 using Deserializer = std::function<void(const QtProtobuf::QAbstractProtobufSerializer *, QtProtobuf::QProtobufSelfcheckIterator &, QVariant &)>;
 
+enum HandlerType {
+    ObjectHandler,
+    ListHandler,
+    MapHandler
+};
+
 /*!
  * \brief SerializationHandlers contains set of objects that required for class serializaion/deserialization
  */
 struct SerializationHandler {
     Serializer serializer; /*!< serializer assigned to class */
     Deserializer deserializer;/*!< deserializer assigned to class */
-    QtProtobuf::WireTypes type;/*!< Serialization WireType */
+    HandlerType type;/*!< Serialization WireType */
 };
 
 extern Q_PROTOBUF_EXPORT SerializationHandler &findHandler(int userType);
@@ -69,9 +76,9 @@ extern Q_PROTOBUF_EXPORT void registerHandler(int userType, const SerializationH
  */
 template <typename T,
           typename std::enable_if_t<std::is_base_of<QObject, T>::value, int> = 0>
-QByteArray serializeObject(const QtProtobuf::QAbstractProtobufSerializer *serializer, const QVariant &value, int outFieldIndex) {
+void serializeObject(const QtProtobuf::QAbstractProtobufSerializer *serializer, const QVariant &value, const QtProtobuf::QProtobufMetaProperty &metaProperty, QByteArray &buffer) {
     Q_ASSERT_X(serializer != nullptr, "QAbstractProtobufSerializer", "serializer set is not setup");
-    return serializer->serializeObject(value.value<T *>(), T::propertyOrdering, T::staticMetaObject, outFieldIndex);
+    buffer.append(serializer->serializeObject(value.value<T *>(), T::propertyOrdering, T::staticMetaObject, metaProperty));
 }
 
 /*!
@@ -81,25 +88,23 @@ QByteArray serializeObject(const QtProtobuf::QAbstractProtobufSerializer *serial
  */
 template<typename V,
          typename std::enable_if_t<std::is_base_of<QObject, V>::value, int> = 0>
-QByteArray serializeList(const QtProtobuf::QAbstractProtobufSerializer *serializer, const QVariant &listValue, int outFieldIndex) {
+void serializeList(const QtProtobuf::QAbstractProtobufSerializer *serializer, const QVariant &listValue, const QtProtobuf::QProtobufMetaProperty &metaProperty, QByteArray &buffer) {
     Q_ASSERT_X(serializer != nullptr, "QAbstractProtobufSerializer", "serializer set is not setup");
     QList<QSharedPointer<V>> list = listValue.value<QList<QSharedPointer<V>>>();
 
-    qProtoDebug() << __func__ << "listValue.count" << list.count() << "outFiledIndex" << outFieldIndex;
+    qProtoDebug() << __func__ << "listValue.count" << list.count();
 
     if (list.count() <= 0) {
-        return QByteArray();
+        return;
     }
 
-    QByteArray serializedList;
     for (auto &value : list) {
         if (!value) {
             qProtoWarning() << "Null pointer in list";
             continue;
         }
-        serializedList.append(serializer->serializeListObject(value.data(), V::propertyOrdering, V::staticMetaObject, outFieldIndex));
+        buffer.append(serializer->serializeListObject(value.data(), V::propertyOrdering, V::staticMetaObject, metaProperty));
     }
-    return serializedList;
 }
 
 /*!
@@ -109,16 +114,12 @@ QByteArray serializeList(const QtProtobuf::QAbstractProtobufSerializer *serializ
  */
 template<typename K, typename V,
          typename std::enable_if_t<!std::is_base_of<QObject, V>::value, int> = 0>
-QByteArray serializeMap(const QtProtobuf::QAbstractProtobufSerializer *serializer, const QVariant &value, int outFieldIndex) {
+void serializeMap(const QtProtobuf::QAbstractProtobufSerializer *serializer, const QVariant &value, const QtProtobuf::QProtobufMetaProperty &metaProperty, QByteArray &buffer) {
     Q_ASSERT_X(serializer != nullptr, "QAbstractProtobufSerializer", "serializer set is not setup");
     QMap<K,V> mapValue = value.value<QMap<K,V>>();
-    using ItType = typename QMap<K,V>::const_iterator;
-    QByteArray mapResult;
-
-    for ( ItType it = mapValue.constBegin(); it != mapValue.constEnd(); it++) {
-        mapResult.append(serializer->serializeMapPair(QVariant::fromValue<K>(it.key()), QVariant::fromValue<V>(it.value()), outFieldIndex));
+    for (auto it = mapValue.constBegin(); it != mapValue.constEnd(); it++) {
+        buffer.append(serializer->serializeMapPair(QVariant::fromValue<K>(it.key()), QVariant::fromValue<V>(it.value()), metaProperty));
     }
-    return mapResult;
 }
 
 /*!
@@ -129,20 +130,16 @@ QByteArray serializeMap(const QtProtobuf::QAbstractProtobufSerializer *serialize
  */
 template<typename K, typename V,
          typename std::enable_if_t<std::is_base_of<QObject, V>::value, int> = 0>
-QByteArray serializeMap(const QtProtobuf::QAbstractProtobufSerializer *serializer, const QVariant &value, int outFieldIndex) {
+void serializeMap(const QtProtobuf::QAbstractProtobufSerializer *serializer, const QVariant &value, const QtProtobuf::QProtobufMetaProperty &metaProperty, QByteArray &buffer) {
     Q_ASSERT_X(serializer != nullptr, "QAbstractProtobufSerializer", "serializer set is not setup");
     QMap<K, QSharedPointer<V>> mapValue = value.value<QMap<K, QSharedPointer<V>>>();
-    using ItType = typename QMap<K, QSharedPointer<V>>::const_iterator;
-    QByteArray mapResult;
-
-    for ( ItType it = mapValue.constBegin(); it != mapValue.constEnd(); it++) {
+    for (auto it = mapValue.constBegin(); it != mapValue.constEnd(); it++) {
         if (it.value().isNull()) {
             qProtoWarning() << __func__ << "Trying to serialize map value that contains nullptr";
             continue;
         }
-        mapResult.append(serializer->serializeMapPair(QVariant::fromValue<K>(it.key()), QVariant::fromValue<V *>(it.value().data()), outFieldIndex));
+        buffer.append(serializer->serializeMapPair(QVariant::fromValue<K>(it.key()), QVariant::fromValue<V *>(it.value().data()), metaProperty));
     }
-    return mapResult;
 }
 
 /*!

+ 11 - 9
src/protobuf/qprotobufjsonserializer.cpp

@@ -24,6 +24,7 @@
  */
 
 #include "qprotobufjsonserializer.h"
+#include "qprotobufmetaproperty.h"
 #include <QMetaProperty>
 
 using namespace QtProtobuf;
@@ -37,11 +38,12 @@ public:
     QProtobufJsonSerializerPrivate(QProtobufJsonSerializer *q) : q_ptr(q) {}
     ~QProtobufJsonSerializerPrivate() = default;
 
-    QByteArray serializeProperty(const QVariant &propertyValue, int fieldIndex, const QMetaProperty &metaProperty) {
-        Q_UNUSED(fieldIndex)
+    QByteArray serializeProperty(const QVariant &propertyValue, const QProtobufMetaProperty &metaProperty) {
+        QByteArray buffer;
         auto &value = QtProtobufPrivate::findHandler(metaProperty.userType());
         if (value.serializer) {
-            return value.serializer(q_ptr, propertyValue, fieldIndex);
+            value.serializer(q_ptr, propertyValue, metaProperty, buffer);
+            return buffer;
         } else {
             QString result("\"%1\":%2");
             return result.arg(metaProperty.name(), propertyValue.toString()).toUtf8();
@@ -71,7 +73,7 @@ QByteArray QProtobufJsonSerializer::serializeMessage(const QObject *object, cons
         QMetaProperty metaProperty = metaObject.property(propertyIndex);
         const char *propertyName = metaProperty.name();
         const QVariant &propertyValue = object->property(propertyName);
-        result.append(d_ptr->serializeProperty(propertyValue, fieldIndex, metaProperty));
+        result.append(d_ptr->serializeProperty(propertyValue, QProtobufMetaProperty(metaProperty, fieldIndex)));
     }
 
     result.append("}");
@@ -86,7 +88,7 @@ void QProtobufJsonSerializer::deserializeMessage(QObject *object, const QByteArr
     Q_UNUSED(metaObject)
 }
 
-QByteArray QProtobufJsonSerializer::serializeObject(const QObject *object, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject, int /*fieldIndex*/) const
+QByteArray QProtobufJsonSerializer::serializeObject(const QObject *object, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject, const QProtobufMetaProperty &/*metaProperty*/) const
 {
     QByteArray result = "{";
     result.append(serializeMessage(object, propertyOrdering, metaObject));
@@ -102,12 +104,12 @@ void QProtobufJsonSerializer::deserializeObject(QObject *object, QProtobufSelfch
     Q_UNUSED(metaObject)
 }
 
-QByteArray QProtobufJsonSerializer::serializeListObject(const QObject *object, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject, int fieldIndex) const
+QByteArray QProtobufJsonSerializer::serializeListObject(const QObject *object, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject, const QProtobufMetaProperty &metaProperty) const
 {
     Q_UNUSED(object)
     Q_UNUSED(propertyOrdering)
     Q_UNUSED(metaObject)
-    Q_UNUSED(fieldIndex)
+    Q_UNUSED(metaProperty)
     return QByteArray();
 }
 
@@ -119,11 +121,11 @@ void QProtobufJsonSerializer::deserializeListObject(QObject *object, QProtobufSe
     Q_UNUSED(metaObject)
 }
 
-QByteArray QProtobufJsonSerializer::serializeMapPair(const QVariant &key, const QVariant &value, int fieldIndex) const
+QByteArray QProtobufJsonSerializer::serializeMapPair(const QVariant &key, const QVariant &value, const QProtobufMetaProperty &metaProperty) const
 {
     Q_UNUSED(key)
     Q_UNUSED(value)
-    Q_UNUSED(fieldIndex)
+    Q_UNUSED(metaProperty)
     return QByteArray();
 }
 

+ 3 - 3
src/protobuf/qprotobufjsonserializer.h

@@ -44,13 +44,13 @@ protected:
     QByteArray serializeMessage(const QObject *object, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject) const  override;
     void deserializeMessage(QObject *object, const QByteArray &data, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject) const override;
 
-    QByteArray serializeObject(const QObject *object, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject, int fieldIndex) const override;
+    QByteArray serializeObject(const QObject *object, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject, const QProtobufMetaProperty &metaProperty) const override;
     void deserializeObject(QObject *object, QProtobufSelfcheckIterator &it, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject) const override;
 
-    QByteArray serializeListObject(const QObject *object, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject, int fieldIndex) const override;
+    QByteArray serializeListObject(const QObject *object, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject, const QProtobufMetaProperty &metaProperty) const override;
     void deserializeListObject(QObject *object, QProtobufSelfcheckIterator &it, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject) const override;
 
-    QByteArray serializeMapPair(const QVariant &key, const QVariant &value, int fieldIndex) const override;
+    QByteArray serializeMapPair(const QVariant &key, const QVariant &value, const QProtobufMetaProperty &metaProperty) const override;
     void deserializeMapPair(QVariant &key, QVariant &value, QProtobufSelfcheckIterator &it) const override;
 private:
     std::unique_ptr<QProtobufJsonSerializerPrivate> d_ptr;

+ 33 - 0
src/protobuf/qprotobufmetaproperty.cpp

@@ -0,0 +1,33 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2019 Alexey Edelev <semlanik@gmail.com>
+ *
+ * This file is part of QtProtobuf project https://git.semlanik.org/semlanik/qtprotobuf
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this
+ * software and associated documentation files (the "Software"), to deal in the Software
+ * without restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+ * to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies
+ * or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "qprotobufmetaproperty.h"
+
+using namespace QtProtobuf;
+QProtobufMetaProperty::QProtobufMetaProperty(const QMetaProperty &metaProperty, int fieldIndex) : QMetaProperty(metaProperty)
+  , m_fieldIndex(fieldIndex)
+{
+
+}

+ 43 - 0
src/protobuf/qprotobufmetaproperty.h

@@ -0,0 +1,43 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2019 Alexey Edelev <semlanik@gmail.com>
+ *
+ * This file is part of QtProtobuf project https://git.semlanik.org/semlanik/qtprotobuf
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this
+ * software and associated documentation files (the "Software"), to deal in the Software
+ * without restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+ * to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies
+ * or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <QMetaProperty>
+
+#include "qtprotobufglobal.h"
+
+namespace QtProtobuf {
+
+class Q_PROTOBUF_EXPORT QProtobufMetaProperty : public QMetaProperty
+{
+public:
+    QProtobufMetaProperty(const QMetaProperty &, int fieldIndex);
+    int protoFieldIndex() const { return m_fieldIndex; }
+private:
+    QProtobufMetaProperty();
+    int m_fieldIndex;
+};
+}

+ 17 - 22
src/protobuf/qprotobufserializer.cpp

@@ -26,7 +26,7 @@
 #include "qprotobufserializer.h"
 #include "qprotobufserializer_p.h"
 
-#include <QMetaProperty>
+#include "qprotobufmetaproperty.h"
 
 using namespace QtProtobuf;
 
@@ -77,7 +77,7 @@ QByteArray QProtobufSerializer::serializeMessage(const QObject *object, const QP
         QMetaProperty metaProperty = metaObject.property(propertyIndex);
         const char *propertyName = metaProperty.name();
         const QVariant &propertyValue = object->property(propertyName);
-        result.append(d_ptr->serializeProperty(propertyValue, fieldIndex, metaProperty));
+        result.append(d_ptr->serializeProperty(propertyValue, QProtobufMetaProperty(metaProperty, fieldIndex)));
     }
 
     return result;
@@ -90,9 +90,9 @@ void QProtobufSerializer::deserializeMessage(QObject *object, const QByteArray &
     }
 }
 
-QByteArray QProtobufSerializer::serializeObject(const QObject *object, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject, int fieldIndex) const
+QByteArray QProtobufSerializer::serializeObject(const QObject *object, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject, const QProtobufMetaProperty &metaProperty) const
 {
-    QByteArray result = QProtobufSerializerPrivate::encodeHeader(fieldIndex, LengthDelimited);
+    QByteArray result = QProtobufSerializerPrivate::encodeHeader(metaProperty.protoFieldIndex(), LengthDelimited);
     result.append(QProtobufSerializerPrivate::prependLengthDelimitedSize(serializeMessage(object, propertyOrdering, metaObject)));
     return result;
 }
@@ -103,9 +103,9 @@ void QProtobufSerializer::deserializeObject(QObject *object, QProtobufSelfcheckI
     deserializeMessage(object, array, propertyOrdering, metaObject);
 }
 
-QByteArray QProtobufSerializer::serializeListObject(const QObject *object, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject, int fieldIndex) const
+QByteArray QProtobufSerializer::serializeListObject(const QObject *object, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject, const QProtobufMetaProperty &metaProperty) const
 {
-    return serializeObject(object, propertyOrdering, metaObject, fieldIndex);
+    return serializeObject(object, propertyOrdering, metaObject, metaProperty);
 }
 
 void QProtobufSerializer::deserializeListObject(QObject *object, QProtobufSelfcheckIterator &it, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject) const
@@ -113,10 +113,10 @@ void QProtobufSerializer::deserializeListObject(QObject *object, QProtobufSelfch
     deserializeObject(object, it, propertyOrdering, metaObject);
 }
 
-QByteArray QProtobufSerializer::serializeMapPair(const QVariant &key, const QVariant &value, int fieldIndex) const
+QByteArray QProtobufSerializer::serializeMapPair(const QVariant &key, const QVariant &value, const QProtobufMetaProperty &metaProperty) const
 {
-    QByteArray result = QProtobufSerializerPrivate::encodeHeader(fieldIndex, LengthDelimited);
-    result.append(QProtobufSerializerPrivate::prependLengthDelimitedSize(d_ptr->serializeProperty(key, 1, QMetaProperty()) + d_ptr->serializeProperty(value, 2, QMetaProperty())));
+    QByteArray result = QProtobufSerializerPrivate::encodeHeader(metaProperty.protoFieldIndex(), LengthDelimited);
+    result.append(QProtobufSerializerPrivate::prependLengthDelimitedSize(d_ptr->serializeProperty(key, QProtobufMetaProperty(metaProperty, 1)) + d_ptr->serializeProperty(value, QProtobufMetaProperty(metaProperty, 2))));
     return result;
 }
 
@@ -130,15 +130,10 @@ void QProtobufSerializer::deserializeMapPair(QVariant &key, QVariant &value, QPr
     while (it != last) {
         QProtobufSerializerPrivate::decodeHeader(it, mapIndex, type);
         if (mapIndex == 1) {
-            //TODO: replace with some common function
+            //Only simple types are supported as keys
             int userType = key.userType();
-            auto basicIt = QProtobufSerializerPrivate::handlers.find(userType);
-            if (basicIt != QProtobufSerializerPrivate::handlers.end()) {
-                basicIt->second.deserializer(it, key);
-            } else {
-                auto &handler = QtProtobufPrivate::findHandler(userType);
-                handler.deserializer(this, it, key);
-            }
+            auto &handler = QProtobufSerializerPrivate::handlers.at(userType);//throws if not found
+            handler.deserializer(it, key);
         } else {
             //TODO: replace with some common function
             int userType = value.userType();
@@ -199,9 +194,9 @@ int QProtobufSerializerPrivate::skipSerializedFieldBytes(QProtobufSelfcheckItera
 }
 
 
-QByteArray QProtobufSerializerPrivate::serializeProperty(const QVariant &propertyValue, int fieldIndex, const QMetaProperty &metaProperty)
+QByteArray QProtobufSerializerPrivate::serializeProperty(const QVariant &propertyValue, const QProtobufMetaProperty &metaProperty)
 {
-    qProtoDebug() << __func__ << "propertyValue" << propertyValue << "fieldIndex" << fieldIndex
+    qProtoDebug() << __func__ << "propertyValue" << propertyValue << "fieldIndex" << metaProperty.protoFieldIndex()
                   << static_cast<QMetaType::Type>(propertyValue.type());
 
     QByteArray result;
@@ -213,18 +208,18 @@ QByteArray QProtobufSerializerPrivate::serializeProperty(const QVariant &propert
     }
 
     //TODO: replace with some common function
+    int fieldIndex = metaProperty.protoFieldIndex();
     auto basicIt = QProtobufSerializerPrivate::handlers.find(userType);
     if (basicIt != QProtobufSerializerPrivate::handlers.end()) {
         type = basicIt->second.type;
         result.append(basicIt->second.serializer(propertyValue, fieldIndex));
         if (fieldIndex != QtProtobufPrivate::NotUsedFieldIndex
                 && type != UnknownWireType) {
-            result.prepend(QProtobufSerializerPrivate::encodeHeader(fieldIndex, type));
+            result.prepend(QProtobufSerializerPrivate::encodeHeader(metaProperty.protoFieldIndex(), type));
         }
     } else {
         auto &handler = QtProtobufPrivate::findHandler(userType);
-        type = handler.type;
-        result.append(handler.serializer(q_ptr, propertyValue, fieldIndex));//throws if not implemented
+        handler.serializer(q_ptr, propertyValue, QProtobufMetaProperty(metaProperty, metaProperty.protoFieldIndex()), result);
     }
     return result;
 }

+ 3 - 3
src/protobuf/qprotobufserializer.h

@@ -45,13 +45,13 @@ protected:
     QByteArray serializeMessage(const QObject *object, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject) const override;
     void deserializeMessage(QObject *object, const QByteArray &data, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject) const override;
 
-    QByteArray serializeObject(const QObject *object, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject, int fieldIndex) const override;
+    QByteArray serializeObject(const QObject *object, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject, const QProtobufMetaProperty &metaProperty) const override;
     void deserializeObject(QObject *object, QProtobufSelfcheckIterator &it, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject) const override;
 
-    QByteArray serializeListObject(const QObject *object, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject, int fieldIndex) const override;
+    QByteArray serializeListObject(const QObject *object, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject, const QProtobufMetaProperty &metaProperty) const override;
     void deserializeListObject(QObject *object, QProtobufSelfcheckIterator &it, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject) const override;
 
-    QByteArray serializeMapPair(const QVariant &key, const QVariant &value, int fieldIndex) const override;
+    QByteArray serializeMapPair(const QVariant &key, const QVariant &value, const QProtobufMetaProperty &metaProperty) const override;
     void deserializeMapPair(QVariant &key, QVariant &value, QProtobufSelfcheckIterator &it) const override;
 
     std::unique_ptr<QProtobufSerializerPrivate> d_ptr;

+ 1 - 1
src/protobuf/qprotobufserializer_p.h

@@ -478,7 +478,7 @@ public:
     static void skipVarint(QProtobufSelfcheckIterator &it);
     static void skipLengthDelimited(QProtobufSelfcheckIterator &it);
 
-    QByteArray serializeProperty(const QVariant &propertyValue, int fieldIndex, const QMetaProperty &metaProperty);
+    QByteArray serializeProperty(const QVariant &propertyValue, const QProtobufMetaProperty &metaProperty);
     void deserializeProperty(QObject *object, QProtobufSelfcheckIterator &it, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject);
 
 private: