Browse Source

Make compact serializater and deserializater

- Put all basic types serializators to serializaters registry
- Make common function to specify serializers
Alexey Edelev 6 years ago
parent
commit
5fd4a30370

+ 5 - 5
src/generator/templates.cpp

@@ -47,11 +47,11 @@ const char *Templates::ComplexTypeRegistrationMethodTemplate = "static void regi
 const char *Templates::ComplexTypeRegistrationTemplate = "void $classname$::registerTypes()\n{\n"
                                                          "    static bool registationDone = false;\n"
                                                          "    if (!registationDone) {\n\n"
-                                                         "        int metaTypeId = qRegisterMetaType<$classname$>(\"$classname$\");\n"
-                                                         "        int listMetaTypeId = qRegisterMetaType<$classname$List>(\"$classname$List\");\n"
-                                                         "        qRegisterMetaType<$namespaces$::$classname$>(\"$namespaces$::$classname$\");\n"
-                                                         "        qRegisterMetaType<$namespaces$::$classname$List>(\"$namespaces$::$classname$List\");\n"
-                                                         "        registerSerializers(metaTypeId, listMetaTypeId);\n";
+                                                         "        qRegisterMetaType<$classname$>(\"$classname$\");\n"
+                                                         "        qRegisterMetaType<$classname$List>(\"$classname$List\");\n"
+                                                         "        qRegisterMetaType<$classname$>(\"$namespaces$::$classname$\");\n"
+                                                         "        qRegisterMetaType<$classname$List>(\"$namespaces$::$classname$List\");\n"
+                                                         "        registerSerializers();\n";
 const char *Templates::ComplexListTypeUsingTemplate = "using $classname$List = QList<$classname$>;\n";
 const char *Templates::MapTypeUsingTemplate = "using $classname$ = QMap<$key$, $value$>;\n";
 

+ 3 - 3
src/protobuf/protobufobject.h

@@ -41,11 +41,11 @@ public:
     void deserialize(const QByteArray &array);
 
 protected:
-    static void registerSerializers(int metaTypeId, int listMetaTypeId);
+    static void registerSerializers();
 
 private:
-    static QByteArray serializeComplexType(const QVariant &variantValue, int &outFieldIndex);
-    static void deserializeComplexType(QByteArray::const_iterator &it, QVariant &previous);
+    static QByteArray serializeComplexType(const T &variantValue, int &outFieldIndex);
+    static QVariant deserializeComplexType(QByteArray::const_iterator &it);
     static QByteArray serializeComplexListType(const QVariant &listValue, int &outFieldIndex);
     static void deserializeComplexListType(QByteArray::const_iterator &it, QVariant &previous);
 };

+ 8 - 8
src/protobuf/protobufobject.inc

@@ -50,7 +50,7 @@ QByteArray ProtobufObject<T>::serialize() const {
         QMetaProperty metaProperty = T::staticMetaObject.property(propertyIndex);
         const char *propertyName = metaProperty.name();
         const QVariant &propertyValue = instance->property(propertyName);
-        result.append(ProtobufObjectPrivate::serializeValue(this, propertyValue, fieldIndex, metaProperty));
+        result.append(ProtobufObjectPrivate::serializeValue(propertyValue, fieldIndex, metaProperty));
     }
 
     return result;
@@ -88,22 +88,22 @@ void ProtobufObject<T>::deserialize(const QByteArray &array) {
 }
 
 template<typename T>
-void ProtobufObject<T>::registerSerializers(int metaTypeId, int listMetaTypeId) {
-    ProtobufObjectPrivate::serializers[listMetaTypeId] = {ProtobufObjectPrivate::Serializer(serializeComplexListType), ProtobufObjectPrivate::Deserializer(deserializeComplexListType)};
-    ProtobufObjectPrivate::serializers[metaTypeId] = {ProtobufObjectPrivate::Serializer(serializeComplexType), ProtobufObjectPrivate::Deserializer(deserializeComplexType)};
+void ProtobufObject<T>::registerSerializers() {
+    ProtobufObjectPrivate::wrapSerializer<T>(serializeComplexType, deserializeComplexType, LengthDelimited);
+    ProtobufObjectPrivate::serializers[qMetaTypeId<QList<T>>()] = {ProtobufObjectPrivate::Serializer(serializeComplexListType),
+            ProtobufObjectPrivate::Deserializer(deserializeComplexListType), LengthDelimited};
 }
 
 template<typename T>
-QByteArray ProtobufObject<T>::serializeComplexType(const QVariant &variantValue, int &/*outFieldIndex*/) {
-    T value = variantValue.value<T>();
+QByteArray ProtobufObject<T>::serializeComplexType(const T &value, int &/*outFieldIndex*/) {
     return ProtobufObjectPrivate::serializeLengthDelimited(value.serialize());
 }
 
 template<typename T>
-void ProtobufObject<T>::deserializeComplexType(QByteArray::const_iterator &it, QVariant &previous) {
+QVariant ProtobufObject<T>::deserializeComplexType(QByteArray::const_iterator &it) {
     T value;
     value.deserialize(ProtobufObjectPrivate::deserializeLengthDelimited(it));
-    previous = QVariant::fromValue(value);
+    return QVariant::fromValue<T>(value);
 }
 
 template<typename T>

+ 64 - 197
src/protobuf/protobufobject_p.cpp

@@ -29,43 +29,63 @@ using namespace qtprotobuf;
 
 ProtobufObjectPrivate::SerializerRegistry ProtobufObjectPrivate::serializers = {};
 
-QByteArray ProtobufObjectPrivate::serializeValue(const QObject* object, const QVariant &propertyValue, int fieldIndex, const QMetaProperty &metaProperty)
+void ProtobufObjectPrivate::registerSerializers()
 {
+    wrapSerializer<float>(ProtobufObjectPrivate::serializeBasic<float>, ProtobufObjectPrivate::deserializeBasic<float>, Fixed32);
+    wrapSerializer<double>(ProtobufObjectPrivate::serializeBasic<double>, ProtobufObjectPrivate::deserializeBasic<double>, Fixed64);
+    wrapSerializer<int32>(ProtobufObjectPrivate::serializeBasic<int64>, ProtobufObjectPrivate::deserializeBasic<int64>, Varint);
+    wrapSerializer<int64>(ProtobufObjectPrivate::serializeBasic<int64>, ProtobufObjectPrivate::deserializeBasic<int64>, Varint);
+    wrapSerializer<uint32>(ProtobufObjectPrivate::serializeBasic<uint32>, ProtobufObjectPrivate::deserializeBasic<uint32>, Varint);
+    wrapSerializer<uint64>(ProtobufObjectPrivate::serializeBasic<uint64>, ProtobufObjectPrivate::deserializeBasic<uint64>, Varint);
+    wrapSerializer<sint32>(ProtobufObjectPrivate::serializeBasic<sint32>, ProtobufObjectPrivate::deserializeBasic<sint32>, Varint);
+    wrapSerializer<sint64>(ProtobufObjectPrivate::serializeBasic<sint64>, ProtobufObjectPrivate::deserializeBasic<sint64>, Varint);
+    wrapSerializer<fint32>(ProtobufObjectPrivate::serializeBasic<fint32>, ProtobufObjectPrivate::deserializeBasic<fint32>, Fixed32);
+    wrapSerializer<fint64>(ProtobufObjectPrivate::serializeBasic<fint64>, ProtobufObjectPrivate::deserializeBasic<fint64>, Fixed64);
+    wrapSerializer<sfint32>(ProtobufObjectPrivate::serializeBasic<sfint32>, ProtobufObjectPrivate::deserializeBasic<sfint32>, Fixed32);
+    wrapSerializer<sfint64>(ProtobufObjectPrivate::serializeBasic<sfint64>, ProtobufObjectPrivate::deserializeBasic<sfint64>, Fixed64);
+    wrapSerializer<bool>(ProtobufObjectPrivate::serializeBasic<uint32>, ProtobufObjectPrivate::deserializeBasic<uint32>, Varint);
+
+    wrapSerializer<QString>([](const QString &data, int &/*fieldIndex*/) {
+        return serializeLengthDelimited(data);
+    }, [](QByteArray::const_iterator &it){
+        return QVariant::fromValue(QString::fromUtf8(deserializeLengthDelimited(it)));
+    }, LengthDelimited);
+
+    wrapSerializer<QByteArray>([](const QByteArray &data, int &/*fieldIndex*/) {
+        return serializeLengthDelimited(data);
+    }, ProtobufObjectPrivate::deserializeLengthDelimited, LengthDelimited);
+
+    wrapSerializer<FloatList>(ProtobufObjectPrivate::serializeListType<float>, ProtobufObjectPrivate::deserializeListType<float>, LengthDelimited);
+    wrapSerializer<DoubleList>(ProtobufObjectPrivate::serializeListType<double>, ProtobufObjectPrivate::deserializeListType<double>, LengthDelimited);
+    wrapSerializer<fint32List>(ProtobufObjectPrivate::serializeListType<fint32>, ProtobufObjectPrivate::deserializeListType<fint32>, LengthDelimited);
+    wrapSerializer<fint64List>(ProtobufObjectPrivate::serializeListType<fint64>, ProtobufObjectPrivate::deserializeListType<fint64>, LengthDelimited);
+    wrapSerializer<sfint32List>(ProtobufObjectPrivate::serializeListType<sfint32>, ProtobufObjectPrivate::deserializeListType<sfint32>, LengthDelimited);
+    wrapSerializer<sfint64List>(ProtobufObjectPrivate::serializeListType<sfint64>, ProtobufObjectPrivate::deserializeListType<sfint64>, LengthDelimited);
+    wrapSerializer<int32List>(ProtobufObjectPrivate::serializeListType<int32>, ProtobufObjectPrivate::deserializeListType<int32>, LengthDelimited);
+    wrapSerializer<int64List>(ProtobufObjectPrivate::serializeListType<int64>, ProtobufObjectPrivate::deserializeListType<int64>, LengthDelimited);
+    wrapSerializer<sint32List>(ProtobufObjectPrivate::serializeListType<sint32>, ProtobufObjectPrivate::deserializeListType<sint32>, LengthDelimited);
+    wrapSerializer<sint64List>(ProtobufObjectPrivate::serializeListType<sint64>, ProtobufObjectPrivate::deserializeListType<sint64>, LengthDelimited);
+    wrapSerializer<uint32List>(ProtobufObjectPrivate::serializeListType<uint32>, ProtobufObjectPrivate::deserializeListType<uint32>, LengthDelimited);
+    wrapSerializer<uint64List>(ProtobufObjectPrivate::serializeListType<uint64>, ProtobufObjectPrivate::deserializeListType<uint64>, LengthDelimited);
+    wrapSerializer<QStringList>(ProtobufObjectPrivate::serializeListType<QString>, ProtobufObjectPrivate::deserializeListType<QString>, LengthDelimited);
+    wrapSerializer<QByteArrayList>(ProtobufObjectPrivate::serializeListType<QByteArray>, ProtobufObjectPrivate::deserializeListType<QByteArray>, LengthDelimited);
+}
+
+QByteArray ProtobufObjectPrivate::serializeValue(const QVariant &propertyValue, int fieldIndex, const QMetaProperty &metaProperty)
+{
+    qProtoDebug() << __func__ << "propertyValue" << propertyValue << "fieldIndex" << fieldIndex
+                  << "typeName" << metaProperty.typeName() << static_cast<QMetaType::Type>(propertyValue.type());
+
     QByteArray result;
     WireTypes type = UnknownWireType;
-    qProtoDebug() << __func__ << "propertyValue" << propertyValue << "fieldIndex" << fieldIndex << "typeName"
-                  << metaProperty.typeName() << static_cast<QMetaType::Type>(propertyValue.type());
 
-    switch (metaProperty.userType()) {
-    case QMetaType::QString:
-        type = LengthDelimited;
-        result.append(serializeLengthDelimited(propertyValue.toString()));
-        break;
-    case QMetaType::QByteArray:
-        type = LengthDelimited;
-        result.append(serializeLengthDelimited(propertyValue.toByteArray()));
-        break;
-    case QMetaType::QStringList:
-        type = LengthDelimited;
-        result.append(serializeListType(propertyValue.toStringList(), fieldIndex));
-        break;
-    case QMetaType::QByteArrayList:
-        type = LengthDelimited;
-        result.append(serializeListType(propertyValue.value<QByteArrayList>(), fieldIndex));
-        break;
-    case QMetaType::Bool:
+    if (metaProperty.isEnumType()) {
         type = Varint;
-        result.append(serializeBasic(propertyValue.toUInt(), fieldIndex));
-        break;
-    default:
-        if(metaProperty.isEnumType()) {
-            type = Varint;
-            result.append(serializeBasic(propertyValue.toLongLong(), fieldIndex));
-        } else {
-            result.append(serializeUserType(propertyValue, fieldIndex, type));
-        }
-        break;
+        result.append(serializeBasic(propertyValue.toLongLong(), fieldIndex));
+    } else {
+        result.append(serializeUserType(propertyValue, fieldIndex, type));
     }
+
     if (fieldIndex != NotUsedFieldIndex
             && type != UnknownWireType) {
         result.prepend(encodeHeaderByte(fieldIndex, type));
@@ -75,121 +95,24 @@ QByteArray ProtobufObjectPrivate::serializeValue(const QObject* object, const QV
 
 QByteArray ProtobufObjectPrivate::serializeUserType(const QVariant &propertyValue, int &fieldIndex, WireTypes &type)
 {
-
     qProtoDebug() << __func__ << "propertyValue" << propertyValue << "fieldIndex" << fieldIndex;
-    type = LengthDelimited;
-    int userType = propertyValue.userType();
-
-    //First looking type serializer in registred serializers
-    auto it = serializers.find(userType);
-    if (it != std::end(serializers)) {
-        return (it->second).serializer(propertyValue, fieldIndex);
-    }
-
-    //Check if it's special type
-    if (userType == qMetaTypeId<float>()) {
-        type = Fixed32;
-        return serializeBasic(propertyValue.toFloat(), fieldIndex);
-    }
-    if (userType == qMetaTypeId<double>()) {
-        type = Fixed64;
-        return serializeBasic(propertyValue.toDouble(), fieldIndex);
-    }
-    if (userType == qMetaTypeId<int32>()) {
-        type = Varint;
-        //FIXME: Current implmentation serializes to int64_t bacause of issue in reference implementation
-        return serializeBasic(propertyValue.value<int64>(), fieldIndex);
-    }
-    if (userType == qMetaTypeId<int64>()) {
-        type = Varint;
-        return serializeBasic(propertyValue.value<int64>(), fieldIndex);
-    }
-    if (userType == qMetaTypeId<uint32>()) {
-        type = Varint;
-        return serializeBasic(propertyValue.value<uint32>(), fieldIndex);
-    }
-    if (userType == qMetaTypeId<uint64>()) {
-        type = Varint;
-        return serializeBasic(propertyValue.value<uint64>(), fieldIndex);
-    }
-    if (userType == qMetaTypeId<sint32>()) {
-        type = Varint;
-        return serializeBasic(propertyValue.value<sint32>(), fieldIndex);
-    }
-    if (userType == qMetaTypeId<sint64>()) {
-        type = Varint;
-        return serializeBasic(propertyValue.value<sint64>(), fieldIndex);
-    }
-    if (userType == qMetaTypeId<fint32>()) {
-        type = Fixed32;
-        return serializeBasic(propertyValue.value<fint32>(), fieldIndex);
-    }
-    if (userType == qMetaTypeId<fint64>()) {
-        type = Fixed64;
-        return serializeBasic(propertyValue.value<fint64>(), fieldIndex);
-    }
-    if (userType == qMetaTypeId<sfint32>()) {
-        type = Fixed32;
-        return serializeBasic(propertyValue.value<sfint32>(), fieldIndex);
-    }
-    if (userType == qMetaTypeId<sfint64>()) {
-        type = Fixed64;
-        return serializeBasic(propertyValue.value<sfint64>(), fieldIndex);
-    }
-    if (userType == qMetaTypeId<fint32List>()) {
-        return serializeListType(propertyValue.value<fint32List>(), fieldIndex);
-    }
-    if (userType == qMetaTypeId<fint64List>()) {
-        return serializeListType(propertyValue.value<fint64List>(), fieldIndex);
-    }
-    if (userType == qMetaTypeId<sfint32List>()) {
-        return serializeListType(propertyValue.value<sfint32List>(), fieldIndex);
-    }
-    if (userType == qMetaTypeId<sfint64List>()) {
-        return serializeListType(propertyValue.value<sfint64List>(), fieldIndex);
-    }
-    if (userType == qMetaTypeId<int32List>()) {
-        return serializeListType(propertyValue.value<int32List>(), fieldIndex);
-    }
-    if (userType == qMetaTypeId<int64List>()) {
-        return serializeListType(propertyValue.value<int64List>(), fieldIndex);
-    }
-    if (userType == qMetaTypeId<sint32List>()) {
-        return serializeListType(propertyValue.value<sint32List>(), fieldIndex);
-    }
-    if (userType == qMetaTypeId<sint64List>()) {
-        return serializeListType(propertyValue.value<sint64List>(), fieldIndex);
-    }
-    if (userType == qMetaTypeId<uint32List>()) {
-        return serializeListType(propertyValue.value<uint32List>(), fieldIndex);
-    }
-    if (userType == qMetaTypeId<uint64List>()) {
-        return serializeListType(propertyValue.value<uint64List>(), fieldIndex);
-    }
-    if (userType == qMetaTypeId<FloatList>()) {
-        return serializeListType(propertyValue.value<FloatList>(), fieldIndex);
-    }
-    if (userType == qMetaTypeId<DoubleList>()) {
-        return serializeListType(propertyValue.value<DoubleList>(), fieldIndex);
-    }
 
+    int userType = propertyValue.userType();
     auto serializer = serializers[userType].serializer;
-    Q_ASSERT_X(serializer, "ProtobufObjectPrivate", "Serialization of unknown type is impossible");
+    Q_ASSERT_X(serializer, "ProtobufObjectPrivate", "Serialization of unknown type is impossible. QtProtobuf::init() missed?");
+
+    type = serializers[userType].type;
     return serializer(propertyValue, fieldIndex);
 }
 
 void ProtobufObjectPrivate::deserializeProperty(QObject *object, WireTypes wireType, const QMetaProperty &metaProperty, QByteArray::const_iterator &it)
 {
-    QLatin1Literal typeName(metaProperty.typeName());
-    qProtoDebug() << __func__ << " wireType: " << wireType << " metaProperty: " << typeName << "currentByte:" << QString::number((*it), 16);
+    qProtoDebug() << __func__ << " wireType: " << wireType << " metaProperty: " << metaProperty.typeName()
+                  << "currentByte:" << QString::number((*it), 16);
+
     QVariant newPropertyValue;
+    //TODO: this switch should be removed in future and replaced by wrapped serializer
     switch (metaProperty.userType()) {
-    case QMetaType::QString:
-        newPropertyValue = QString::fromUtf8(deserializeLengthDelimited(it));
-        break;
-    case QMetaType::QByteArray:
-        newPropertyValue = deserializeLengthDelimited(it);
-        break;
     case QMetaType::QByteArrayList: {
         QByteArrayList currentValue = metaProperty.read(object).value<QByteArrayList>();
         currentValue.append(deserializeLengthDelimited(it));
@@ -202,9 +125,6 @@ void ProtobufObjectPrivate::deserializeProperty(QObject *object, WireTypes wireT
         metaProperty.write(object, currentValue);
     }
         return;
-    case QMetaType::Bool:
-        newPropertyValue = deserializeBasic<uint32>(it);
-        break;
     default:
         if (metaProperty.isEnumType()) {
             newPropertyValue = deserializeBasic<int32>(it);
@@ -219,64 +139,11 @@ void ProtobufObjectPrivate::deserializeProperty(QObject *object, WireTypes wireT
 
 void ProtobufObjectPrivate::deserializeUserType(const QMetaProperty &metaType, QByteArray::const_iterator& it, QVariant &newValue)
 {
-    int userType = metaType.userType();
-    qProtoDebug() << __func__ << "userType" << userType << "typeName" << metaType.typeName() << "currentByte:" << QString::number((*it), 16);
+    qProtoDebug() << __func__ << "userType" << metaType.userType() << "typeName" << metaType.typeName()
+                  << "currentByte:" << QString::number((*it), 16);
 
-    auto serializerIt = serializers.find(userType);
-    if (serializerIt != std::end(serializers)) {
-        (serializerIt->second).deserializer(it, newValue);
-        return;
-    }
+    auto deserializer = serializers[metaType.userType()].deserializer;
+    Q_ASSERT_X(deserializer, "ProtobufObjectPrivate", "Deserialization of unknown type is impossible. QtProtobuf::init() missed?");
 
-    if (userType == qMetaTypeId<float>()) {
-        newValue = deserializeBasic<float>(it);
-    } else if (userType == qMetaTypeId<double>()) {
-        newValue = deserializeBasic<double>(it);
-    } else if (userType == qMetaTypeId<int32>()) {
-        newValue = deserializeBasic<int32>(it);
-    } else if (userType == qMetaTypeId<int64>()) {
-        newValue = deserializeBasic<int64>(it);
-    } else if (userType == qMetaTypeId<sint32>()) {
-        newValue = deserializeBasic<sint32>(it);
-    } else if (userType == qMetaTypeId<sint64>()) {
-        newValue = deserializeBasic<sint64>(it);
-    } else if (userType == qMetaTypeId<uint32>()) {
-        newValue = deserializeBasic<uint32>(it);
-    } else if (userType == qMetaTypeId<uint64>()) {
-        newValue = deserializeBasic<uint64>(it);
-    } else if (userType == qMetaTypeId<fint32>()) {
-        newValue = deserializeBasic<fint32>(it);
-    } else if (userType == qMetaTypeId<fint32>()) {
-        newValue = deserializeBasic<fint32>(it);
-    } else if (userType == qMetaTypeId<fint64>()) {
-        newValue = deserializeBasic<fint64>(it);
-    } else if (userType == qMetaTypeId<sfint32>()) {
-        newValue = deserializeBasic<sfint32>(it);
-    } else if (userType == qMetaTypeId<sfint64>()) {
-        newValue = deserializeBasic<sfint64>(it);
-    } else if (userType == qMetaTypeId<fint32List>()) {
-        newValue = deserializeListType<fint32>(it);
-    } else if (userType == qMetaTypeId<fint64List>()) {
-        newValue = deserializeListType<fint64>(it);
-    } else if(userType == qMetaTypeId<sfint32List>()) {
-        newValue = deserializeListType<sfint32>(it);
-    } else if(userType == qMetaTypeId<sfint64List>()) {
-        newValue = deserializeListType<sfint64>(it);
-    } else if (userType == qMetaTypeId<int32List>()) {
-        newValue = deserializeListType<int32>(it);
-    } else if (userType == qMetaTypeId<int64List>()) {
-        newValue = deserializeListType<int64>(it);
-    } else if (userType == qMetaTypeId<sint32List>()) {
-        newValue = deserializeListType<sint32>(it);
-    } else if (userType == qMetaTypeId<sint64List>()) {
-        newValue = deserializeListType<sint64>(it);
-    } else if (userType == qMetaTypeId<uint32List>()) {
-        newValue = deserializeListType<uint32>(it);
-    } else if (userType == qMetaTypeId<uint64List>()) {
-        newValue = deserializeListType<uint64>(it);
-    } else if (userType == qMetaTypeId<FloatList>()) {
-        newValue = deserializeListType<float>(it);
-    } else if (userType == qMetaTypeId<DoubleList>()) {
-        newValue = deserializeListType<double>(it);
-    }
+    deserializer(it, newValue);
 }

+ 22 - 5
src/protobuf/protobufobject_p.h

@@ -52,22 +52,39 @@ struct make_unsigned<sint64> { typedef typename std::make_unsigned<decltype(sint
 class ProtobufObjectPrivate
 {
 public:
-    static unsigned char encodeHeaderByte(int fieldIndex, WireTypes wireType);
-    static bool decodeHeaderByte(unsigned char typeByte, int &fieldIndex, WireTypes &wireType);
-
     using Serializer = std::function<QByteArray(const QVariant &, int &)>;
     using Deserializer = std::function<void(QByteArray::const_iterator &, QVariant &)>;
     struct SerializationHandlers {
         Serializer serializer;
         Deserializer deserializer;
+        WireTypes type;
     };
-
     using SerializerRegistry = std::unordered_map<int/*metatypeid*/, SerializationHandlers>;
     static SerializerRegistry serializers;
 
     ProtobufObjectPrivate() {}
 
-    static QByteArray serializeValue(const QObject *object, const QVariant &propertyValue, int fieldIndex, const QMetaProperty &metaProperty);
+    static void registerSerializers();
+
+    template <typename T>
+    static void wrapSerializer(std::function<QByteArray(const T &, int &)> s, std::function<QVariant(QByteArray::const_iterator &)> d, WireTypes type)
+    {
+        serializers[qMetaTypeId<T>()] = {
+            [s](const QVariant &value, int &fieldIndex) {
+                return s(value.value<T>(), fieldIndex);
+            },
+            [d](QByteArray::const_iterator &it, QVariant & value){
+                value = d(it);
+            },
+            type
+        };
+    }
+
+
+    static unsigned char encodeHeaderByte(int fieldIndex, WireTypes wireType);
+    static bool decodeHeaderByte(unsigned char typeByte, int &fieldIndex, WireTypes &wireType);
+
+    static QByteArray serializeValue(const QVariant &propertyValue, int fieldIndex, const QMetaProperty &metaProperty);
     static QByteArray serializeUserType(const QVariant &propertyValue, int &fieldIndex, WireTypes &type);
 
     static void deserializeProperty(QObject *object, WireTypes wireType, const QMetaProperty &metaProperty, QByteArray::const_iterator &it);

+ 2 - 0
src/protobuf/qtprotobuf.h

@@ -26,6 +26,7 @@
 #pragma once
 
 #include <qtprotobuftypes.h>
+#include <protobufobject.h>
 #include <qtprotobuflogging.h>
 #include <QDebug>
 
@@ -64,6 +65,7 @@ public:
 
             registerProtobufType(DoubleList);
             registerProtobufType(FloatList);
+            ProtobufObjectPrivate::registerSerializers();
             registationDone = true;
         }
     }