Browse Source

Code cleanup

- Move some class fields to private section and hide under interface methods
- Add comments and sectioning to QProtobufSerializerPrivate
- Add methods description to QProtobufSerializerRegistry
Alexey Edelev 5 years ago
parent
commit
c20ba2786c

+ 6 - 2
CMakeLists.txt

@@ -73,14 +73,18 @@ export(PACKAGE ${PROJECT_NAME})
 
 # add a target to generate API documentation with Doxygen
 find_package(Doxygen)
-if(DOXYGEN_FOUND)
+if(NOT DOXYGEN_FOUND)
+    find_program(DOXYGEN_EXECUTABLE doxygen)
+endif(DOXYGEN_FOUND)
+if(DEFINED DOXYGEN_EXECUTABLE)
+    message(STATUS "DOXYGEN_EXECUTABLE: ${DOXYGEN_EXECUTABLE}")
     configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY)
     add_custom_target(doc
         ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
         WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
         COMMENT "Generating API documentation with Doxygen" VERBATIM
     )
-endif(DOXYGEN_FOUND)
+endif()
 
 if(DEFINED $ENV{MAKE_TESTS})
     set(MAKE_TESTS $ENV{MAKE_TESTS})

+ 4 - 1
src/protobuf/qabstractprotobufserializer.h

@@ -68,7 +68,10 @@ public:
     QByteArray serializeObjectCommon(const QObject *object, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject);
     void deserializeObjectCommon(QObject *object, const QByteArray &array, const QProtobufPropertyOrdering &propertyOrdering, const QMetaObject &metaObject);
 
-    SerializerRegistry serializers;
+    const SerializerRegistry& handlers() { return m_handlers; }
+
+protected:
+    SerializerRegistry m_handlers;//TODO: move to d-prointer
 };
 
 

+ 1 - 1
src/protobuf/qprotobufobject.h

@@ -36,5 +36,5 @@
 
 #define Q_PROTOBUF_OBJECT\
     public:\
-        static const std::unordered_map<int/*field number*/, int/*property number*/> propertyOrdering;\
+        static const qtprotobuf::QProtobufPropertyOrdering propertyOrdering;\
     private:

+ 30 - 30
src/protobuf/qprotobufserializer.cpp

@@ -33,36 +33,36 @@ using namespace qtprotobuf;
 
 QProtobufSerializer::QProtobufSerializer()
 {
-    QProtobufSerializerPrivate::wrapSerializer<float>(this, QProtobufSerializerPrivate::serializeBasic<float>, QProtobufSerializerPrivate::deserializeBasic<float>, Fixed32);
-    QProtobufSerializerPrivate::wrapSerializer<double>(this, QProtobufSerializerPrivate::serializeBasic<double>, QProtobufSerializerPrivate::deserializeBasic<double>, Fixed64);
-    QProtobufSerializerPrivate::wrapSerializer<int32>(this, QProtobufSerializerPrivate::serializeBasic<int32>, QProtobufSerializerPrivate::deserializeBasic<int32>, Varint);
-    QProtobufSerializerPrivate::wrapSerializer<int64>(this, QProtobufSerializerPrivate::serializeBasic<int64>, QProtobufSerializerPrivate::deserializeBasic<int64>, Varint);
-    QProtobufSerializerPrivate::wrapSerializer<uint32>(this, QProtobufSerializerPrivate::serializeBasic<uint32>, QProtobufSerializerPrivate::deserializeBasic<uint32>, Varint);
-    QProtobufSerializerPrivate::wrapSerializer<uint64>(this, QProtobufSerializerPrivate::serializeBasic<uint64>, QProtobufSerializerPrivate::deserializeBasic<uint64>, Varint);
-    QProtobufSerializerPrivate::wrapSerializer<sint32>(this, QProtobufSerializerPrivate::serializeBasic<sint32>, QProtobufSerializerPrivate::deserializeBasic<sint32>, Varint);
-    QProtobufSerializerPrivate::wrapSerializer<sint64>(this, QProtobufSerializerPrivate::serializeBasic<sint64>, QProtobufSerializerPrivate::deserializeBasic<sint64>, Varint);
-    QProtobufSerializerPrivate::wrapSerializer<fixed32>(this, QProtobufSerializerPrivate::serializeBasic<fixed32>, QProtobufSerializerPrivate::deserializeBasic<fixed32>, Fixed32);
-    QProtobufSerializerPrivate::wrapSerializer<fixed64>(this, QProtobufSerializerPrivate::serializeBasic<fixed64>, QProtobufSerializerPrivate::deserializeBasic<fixed64>, Fixed64);
-    QProtobufSerializerPrivate::wrapSerializer<sfixed32>(this, QProtobufSerializerPrivate::serializeBasic<sfixed32>, QProtobufSerializerPrivate::deserializeBasic<sfixed32>, Fixed32);
-    QProtobufSerializerPrivate::wrapSerializer<sfixed64>(this, QProtobufSerializerPrivate::serializeBasic<sfixed64>, QProtobufSerializerPrivate::deserializeBasic<sfixed64>, Fixed64);
-    QProtobufSerializerPrivate::wrapSerializer<bool>(this, QProtobufSerializerPrivate::serializeBasic<uint32>, QProtobufSerializerPrivate::deserializeBasic<uint32>, Varint);
-    QProtobufSerializerPrivate::wrapSerializer<QString>(this, QProtobufSerializerPrivate::serializeBasic<QString>, QProtobufSerializerPrivate::deserializeBasic<QString>, LengthDelimited);
-    QProtobufSerializerPrivate::wrapSerializer<QByteArray>(this, QProtobufSerializerPrivate::serializeBasic<QByteArray>, QProtobufSerializerPrivate::deserializeBasic<QByteArray>, LengthDelimited);
-
-    QProtobufSerializerPrivate::wrapSerializer<FloatList>(this, QProtobufSerializerPrivate::serializeListType<float>, QProtobufSerializerPrivate::deserializeList<float>, LengthDelimited);
-    QProtobufSerializerPrivate::wrapSerializer<DoubleList>(this, QProtobufSerializerPrivate::serializeListType<double>, QProtobufSerializerPrivate::deserializeList<double>, LengthDelimited);
-    QProtobufSerializerPrivate::wrapSerializer<fixed32List>(this, QProtobufSerializerPrivate::serializeListType<fixed32>, QProtobufSerializerPrivate::deserializeList<fixed32>, LengthDelimited);
-    QProtobufSerializerPrivate::wrapSerializer<fixed64List>(this, QProtobufSerializerPrivate::serializeListType<fixed64>, QProtobufSerializerPrivate::deserializeList<fixed64>, LengthDelimited);
-    QProtobufSerializerPrivate::wrapSerializer<sfixed32List>(this, QProtobufSerializerPrivate::serializeListType<sfixed32>, QProtobufSerializerPrivate::deserializeList<sfixed32>, LengthDelimited);
-    QProtobufSerializerPrivate::wrapSerializer<sfixed64List>(this, QProtobufSerializerPrivate::serializeListType<sfixed64>, QProtobufSerializerPrivate::deserializeList<sfixed64>, LengthDelimited);
-    QProtobufSerializerPrivate::wrapSerializer<int32List>(this, QProtobufSerializerPrivate::serializeListType<int32>, QProtobufSerializerPrivate::deserializeList<int32>, LengthDelimited);
-    QProtobufSerializerPrivate::wrapSerializer<int64List>(this, QProtobufSerializerPrivate::serializeListType<int64>, QProtobufSerializerPrivate::deserializeList<int64>, LengthDelimited);
-    QProtobufSerializerPrivate::wrapSerializer<sint32List>(this, QProtobufSerializerPrivate::serializeListType<sint32>, QProtobufSerializerPrivate::deserializeList<sint32>, LengthDelimited);
-    QProtobufSerializerPrivate::wrapSerializer<sint64List>(this, QProtobufSerializerPrivate::serializeListType<sint64>, QProtobufSerializerPrivate::deserializeList<sint64>, LengthDelimited);
-    QProtobufSerializerPrivate::wrapSerializer<uint32List>(this, QProtobufSerializerPrivate::serializeListType<uint32>, QProtobufSerializerPrivate::deserializeList<uint32>, LengthDelimited);
-    QProtobufSerializerPrivate::wrapSerializer<uint64List>(this, QProtobufSerializerPrivate::serializeListType<uint64>, QProtobufSerializerPrivate::deserializeList<uint64>, LengthDelimited);
-    QProtobufSerializerPrivate::wrapSerializer<QStringList>(this, QProtobufSerializerPrivate::serializeListType<QString>, QProtobufSerializerPrivate::deserializeList<QString>, LengthDelimited);
-    QProtobufSerializerPrivate::wrapSerializer<QByteArrayList>(this, QProtobufSerializerPrivate::serializeListType<QByteArray>, QProtobufSerializerPrivate::deserializeList<QByteArray>, LengthDelimited);
+    QProtobufSerializerPrivate::wrapSerializer<float>(m_handlers, QProtobufSerializerPrivate::serializeBasic<float>, QProtobufSerializerPrivate::deserializeBasic<float>, Fixed32);
+    QProtobufSerializerPrivate::wrapSerializer<double>(m_handlers, QProtobufSerializerPrivate::serializeBasic<double>, QProtobufSerializerPrivate::deserializeBasic<double>, Fixed64);
+    QProtobufSerializerPrivate::wrapSerializer<int32>(m_handlers, QProtobufSerializerPrivate::serializeBasic<int32>, QProtobufSerializerPrivate::deserializeBasic<int32>, Varint);
+    QProtobufSerializerPrivate::wrapSerializer<int64>(m_handlers, QProtobufSerializerPrivate::serializeBasic<int64>, QProtobufSerializerPrivate::deserializeBasic<int64>, Varint);
+    QProtobufSerializerPrivate::wrapSerializer<uint32>(m_handlers, QProtobufSerializerPrivate::serializeBasic<uint32>, QProtobufSerializerPrivate::deserializeBasic<uint32>, Varint);
+    QProtobufSerializerPrivate::wrapSerializer<uint64>(m_handlers, QProtobufSerializerPrivate::serializeBasic<uint64>, QProtobufSerializerPrivate::deserializeBasic<uint64>, Varint);
+    QProtobufSerializerPrivate::wrapSerializer<sint32>(m_handlers, QProtobufSerializerPrivate::serializeBasic<sint32>, QProtobufSerializerPrivate::deserializeBasic<sint32>, Varint);
+    QProtobufSerializerPrivate::wrapSerializer<sint64>(m_handlers, QProtobufSerializerPrivate::serializeBasic<sint64>, QProtobufSerializerPrivate::deserializeBasic<sint64>, Varint);
+    QProtobufSerializerPrivate::wrapSerializer<fixed32>(m_handlers, QProtobufSerializerPrivate::serializeBasic<fixed32>, QProtobufSerializerPrivate::deserializeBasic<fixed32>, Fixed32);
+    QProtobufSerializerPrivate::wrapSerializer<fixed64>(m_handlers, QProtobufSerializerPrivate::serializeBasic<fixed64>, QProtobufSerializerPrivate::deserializeBasic<fixed64>, Fixed64);
+    QProtobufSerializerPrivate::wrapSerializer<sfixed32>(m_handlers, QProtobufSerializerPrivate::serializeBasic<sfixed32>, QProtobufSerializerPrivate::deserializeBasic<sfixed32>, Fixed32);
+    QProtobufSerializerPrivate::wrapSerializer<sfixed64>(m_handlers, QProtobufSerializerPrivate::serializeBasic<sfixed64>, QProtobufSerializerPrivate::deserializeBasic<sfixed64>, Fixed64);
+    QProtobufSerializerPrivate::wrapSerializer<bool>(m_handlers, QProtobufSerializerPrivate::serializeBasic<uint32>, QProtobufSerializerPrivate::deserializeBasic<uint32>, Varint);
+    QProtobufSerializerPrivate::wrapSerializer<QString>(m_handlers, QProtobufSerializerPrivate::serializeBasic<QString>, QProtobufSerializerPrivate::deserializeBasic<QString>, LengthDelimited);
+    QProtobufSerializerPrivate::wrapSerializer<QByteArray>(m_handlers, QProtobufSerializerPrivate::serializeBasic<QByteArray>, QProtobufSerializerPrivate::deserializeBasic<QByteArray>, LengthDelimited);
+
+    QProtobufSerializerPrivate::wrapSerializer<FloatList>(m_handlers, QProtobufSerializerPrivate::serializeListType<float>, QProtobufSerializerPrivate::deserializeList<float>, LengthDelimited);
+    QProtobufSerializerPrivate::wrapSerializer<DoubleList>(m_handlers, QProtobufSerializerPrivate::serializeListType<double>, QProtobufSerializerPrivate::deserializeList<double>, LengthDelimited);
+    QProtobufSerializerPrivate::wrapSerializer<fixed32List>(m_handlers, QProtobufSerializerPrivate::serializeListType<fixed32>, QProtobufSerializerPrivate::deserializeList<fixed32>, LengthDelimited);
+    QProtobufSerializerPrivate::wrapSerializer<fixed64List>(m_handlers, QProtobufSerializerPrivate::serializeListType<fixed64>, QProtobufSerializerPrivate::deserializeList<fixed64>, LengthDelimited);
+    QProtobufSerializerPrivate::wrapSerializer<sfixed32List>(m_handlers, QProtobufSerializerPrivate::serializeListType<sfixed32>, QProtobufSerializerPrivate::deserializeList<sfixed32>, LengthDelimited);
+    QProtobufSerializerPrivate::wrapSerializer<sfixed64List>(m_handlers, QProtobufSerializerPrivate::serializeListType<sfixed64>, QProtobufSerializerPrivate::deserializeList<sfixed64>, LengthDelimited);
+    QProtobufSerializerPrivate::wrapSerializer<int32List>(m_handlers, QProtobufSerializerPrivate::serializeListType<int32>, QProtobufSerializerPrivate::deserializeList<int32>, LengthDelimited);
+    QProtobufSerializerPrivate::wrapSerializer<int64List>(m_handlers, QProtobufSerializerPrivate::serializeListType<int64>, QProtobufSerializerPrivate::deserializeList<int64>, LengthDelimited);
+    QProtobufSerializerPrivate::wrapSerializer<sint32List>(m_handlers, QProtobufSerializerPrivate::serializeListType<sint32>, QProtobufSerializerPrivate::deserializeList<sint32>, LengthDelimited);
+    QProtobufSerializerPrivate::wrapSerializer<sint64List>(m_handlers, QProtobufSerializerPrivate::serializeListType<sint64>, QProtobufSerializerPrivate::deserializeList<sint64>, LengthDelimited);
+    QProtobufSerializerPrivate::wrapSerializer<uint32List>(m_handlers, QProtobufSerializerPrivate::serializeListType<uint32>, QProtobufSerializerPrivate::deserializeList<uint32>, LengthDelimited);
+    QProtobufSerializerPrivate::wrapSerializer<uint64List>(m_handlers, QProtobufSerializerPrivate::serializeListType<uint64>, QProtobufSerializerPrivate::deserializeList<uint64>, LengthDelimited);
+    QProtobufSerializerPrivate::wrapSerializer<QStringList>(m_handlers, QProtobufSerializerPrivate::serializeListType<QString>, QProtobufSerializerPrivate::deserializeList<QString>, LengthDelimited);
+    QProtobufSerializerPrivate::wrapSerializer<QByteArrayList>(m_handlers, QProtobufSerializerPrivate::serializeListType<QByteArray>, QProtobufSerializerPrivate::deserializeList<QByteArray>, LengthDelimited);
 
 }
 

+ 305 - 285
src/protobuf/qprotobufserializer_p.h

@@ -33,6 +33,11 @@
 
 namespace qtprotobuf {
 
+/**
+ * @private
+ *
+ * @brief The QProtobufSerializerPrivate class
+ */
 class QProtobufSerializerPrivate {
     QProtobufSerializerPrivate() = delete;
     ~QProtobufSerializerPrivate() = delete;
@@ -40,6 +45,10 @@ class QProtobufSerializerPrivate {
     QProtobufSerializerPrivate(QProtobufSerializerPrivate &&) = delete;
     QProtobufSerializerPrivate &operator =(QProtobufSerializerPrivate &&) = delete;
 public:
+    //###########################################################################
+    //                               Serializers
+    //###########################################################################
+
     template <typename V,
               typename std::enable_if_t<std::is_integral<V>::value
                                         && std::is_unsigned<V>::value, int> = 0>
@@ -63,57 +72,8 @@ public:
         return result;
     }
 
-    template <typename V,
-              typename std::enable_if_t<std::is_integral<V>::value
-                                        && std::is_unsigned<V>::value, int> = 0>
-    static V deserializeVarintCommon(SelfcheckIterator &it) {
-        qProtoDebug() << __func__ << "currentByte:" << QString::number((*it), 16);
-
-        V value = 0;
-        int k = 0;
-        while (true) {
-            uint64_t byte = static_cast<uint64_t>(*it);
-            value += (byte & 0b01111111) << k;
-            k += 7;
-            if (((*it) & 0b10000000) == 0) {
-                break;
-            }
-            ++it;
-        }
-        ++it;
-        return value;
-    }
-
-    template <typename T,
-              typename std::enable_if_t<!std::is_base_of<QObject, T>::value, int> = 0>
-    static void wrapSerializer(QProtobufSerializer *owner,const std::function<QByteArray(const T &, int &)> &s, const std::function<QVariant(SelfcheckIterator &)> &d, WireTypes type)
-    {
-        owner->serializers[qMetaTypeId<T>()] = {
-                [s](const QVariant &value, int &fieldIndex) {
-            return s(value.value<T>(), fieldIndex);
-        },
-        [d](SelfcheckIterator &it, QVariant & value){
-            value = d(it);
-        },
-        type
-    };
-}
-
-template <typename T,
-typename std::enable_if_t<!std::is_base_of<QObject, T>::value, int> = 0>
-static void wrapSerializer(QProtobufSerializer *owner, const std::function<QByteArray(const T &, int &)> &s, const std::function<void(SelfcheckIterator &it, QVariant & value)> &d, WireTypes type)
-{
-    owner->serializers[qMetaTypeId<T>()] = {
-            [s](const QVariant &value, int &fieldIndex) {
-        return s(value.value<T>(), fieldIndex);
-    },
-    d,
-    type
-};
-}
-
-//----------------Serialize basic integral and floating point----------------
-/**
+    //---------------Integral and floating point types serializers---------------
+    /**
      * @brief Serialization of fixed-length primitive types
      *
      * Natural layout of bits is used: value is encoded in a byte array same way as it is located in memory
@@ -122,18 +82,18 @@ static void wrapSerializer(QProtobufSerializer *owner, const std::function<QByte
      * @param[out] outFieldIndex Index of the value in parent structure (ignored)
      * @return Byte array with value encoded
      */
-template <typename V,
-          typename std::enable_if_t<std::is_floating_point<V>::value, int> = 0>
-static QByteArray serializeBasic(const V &value, int &/*outFieldIndex*/) {
-    qProtoDebug() << __func__ << "value" << value;
-
-    //Reserve required number of bytes
-    QByteArray result(sizeof(V), '\0');
-    *reinterpret_cast<V *>(result.data()) = value;
-    return result;
-}
+    template <typename V,
+              typename std::enable_if_t<std::is_floating_point<V>::value, int> = 0>
+    static QByteArray serializeBasic(const V &value, int &/*outFieldIndex*/) {
+        qProtoDebug() << __func__ << "value" << value;
 
-/**
+        //Reserve required number of bytes
+        QByteArray result(sizeof(V), '\0');
+        *reinterpret_cast<V *>(result.data()) = value;
+        return result;
+    }
+
+    /**
      * @brief Serialization of fixed length integral types
      *
      * @details Natural layout of bits is employed
@@ -142,21 +102,21 @@ static QByteArray serializeBasic(const V &value, int &/*outFieldIndex*/) {
      * @param[out] outFieldIndex Index of the value in parent structure (ignored)
      * @return Byte array with value encoded
      */
-template <typename V,
-          typename std::enable_if_t<std::is_same<V, fixed32>::value
-                                    || std::is_same<V, fixed64>::value
-                                    || std::is_same<V, sfixed32>::value
-                                    || std::is_same<V, sfixed64>::value, int> = 0>
-static QByteArray serializeBasic(const V &value, int &/*outFieldIndex*/) {
-    qProtoDebug() << __func__ << "value" << value;
-
-    //Reserve required number of bytes
-    QByteArray result(sizeof(V), '\0');
-    *reinterpret_cast<V *>(result.data()) = value;
-    return result;
-}
+    template <typename V,
+              typename std::enable_if_t<std::is_same<V, fixed32>::value
+                                        || std::is_same<V, fixed64>::value
+                                        || std::is_same<V, sfixed32>::value
+                                        || std::is_same<V, sfixed64>::value, int> = 0>
+    static QByteArray serializeBasic(const V &value, int &/*outFieldIndex*/) {
+        qProtoDebug() << __func__ << "value" << value;
 
-/**
+        //Reserve required number of bytes
+        QByteArray result(sizeof(V), '\0');
+        *reinterpret_cast<V *>(result.data()) = value;
+        return result;
+    }
+
+    /**
      *@brief Serialization of signed integral types
      *
      * Use <a href="https://developers.google.com/protocol-buffers/docs/encoding">ZigZag encoding</a> first,
@@ -167,30 +127,30 @@ static QByteArray serializeBasic(const V &value, int &/*outFieldIndex*/) {
      * @param[out] outFieldIndex Index of the value in parent structure
      * @return Byte array with value encoded
      */
-template <typename V,
-          typename std::enable_if_t<std::is_integral<V>::value
-                                    && std::is_signed<V>::value, int> = 0>
-static QByteArray serializeBasic(const V &value, int &outFieldIndex) {
-    qProtoDebug() << __func__ << "value" << value;
-    using UV = typename std::make_unsigned<V>::type;
-    UV uValue = 0;
-
-    //Use ZigZag convertion first and apply unsigned variant next
-    V zigZagValue = (value << 1) ^ (value >> (sizeof(UV) * 8 - 1));
-    uValue = static_cast<UV>(zigZagValue);
-    return serializeBasic(uValue, outFieldIndex);
-}
+    template <typename V,
+              typename std::enable_if_t<std::is_integral<V>::value
+                                        && std::is_signed<V>::value, int> = 0>
+    static QByteArray serializeBasic(const V &value, int &outFieldIndex) {
+        qProtoDebug() << __func__ << "value" << value;
+        using UV = typename std::make_unsigned<V>::type;
+        UV uValue = 0;
 
-template <typename V,
-          typename std::enable_if_t<std::is_same<V, int32>::value
-                                    || std::is_same<V, int64>::value, int> = 0>
-static QByteArray serializeBasic(const V &value, int &outFieldIndex) {
-    qProtoDebug() << __func__ << "value" << value;
-    using UV = typename std::make_unsigned<V>::type;
-    return serializeBasic(static_cast<UV>(value), outFieldIndex);
-}
+        //Use ZigZag convertion first and apply unsigned variant next
+        V zigZagValue = (value << 1) ^ (value >> (sizeof(UV) * 8 - 1));
+        uValue = static_cast<UV>(zigZagValue);
+        return serializeBasic(uValue, outFieldIndex);
+    }
 
-/**
+    template <typename V,
+              typename std::enable_if_t<std::is_same<V, int32>::value
+                                        || std::is_same<V, int64>::value, int> = 0>
+    static QByteArray serializeBasic(const V &value, int &outFieldIndex) {
+        qProtoDebug() << __func__ << "value" << value;
+        using UV = typename std::make_unsigned<V>::type;
+        return serializeBasic(static_cast<UV>(value), outFieldIndex);
+    }
+
+    /**
     *@brief Serialization of unsigned integral types
     *
     * Use <a href="https://developers.google.com/protocol-buffers/docs/encoding">Varint encoding</a>:
@@ -201,240 +161,301 @@ static QByteArray serializeBasic(const V &value, int &outFieldIndex) {
     * @param[out] outFieldIndex Index of the value in parent structure
     * @return Byte array with value encoded
     */
-template <typename V,
-          typename std::enable_if_t<std::is_integral<V>::value
-                                    && std::is_unsigned<V>::value, int> = 0>
-static QByteArray serializeBasic(const V &value, int &outFieldIndex) {
-    qProtoDebug() << __func__ << "value" << value;
-    V varint = value;
-    QByteArray result;
-
-    while (varint != 0) {
-        //Put 7 bits to result buffer and mark as "not last" (0b10000000)
-        result.append((varint & 0b01111111) | 0b10000000);
-        //Divide values to chunks of 7 bits and move to next chunk
-        varint >>= 7;
+    template <typename V,
+              typename std::enable_if_t<std::is_integral<V>::value
+                                        && std::is_unsigned<V>::value, int> = 0>
+    static QByteArray serializeBasic(const V &value, int &outFieldIndex) {
+        qProtoDebug() << __func__ << "value" << value;
+        V varint = value;
+        QByteArray result;
+
+        while (varint != 0) {
+            //Put 7 bits to result buffer and mark as "not last" (0b10000000)
+            result.append((varint & 0b01111111) | 0b10000000);
+            //Divide values to chunks of 7 bits and move to next chunk
+            varint >>= 7;
+        }
+
+        // Invalidate field index in case if serialized result is empty
+        // NOTE: the field will not be sent if its index is equal to NotUsedFieldIndex
+        if (result.size() == 0) {
+            outFieldIndex = NotUsedFieldIndex;
+        } else {
+            //Mark last chunk as last by clearing last bit
+            result.data()[result.size() - 1] &= ~0b10000000;
+        }
+        return result;
     }
 
-    // Invalidate field index in case if serialized result is empty
-    // NOTE: the field will not be sent if its index is equal to NotUsedFieldIndex
-    if (result.size() == 0) {
-        outFieldIndex = NotUsedFieldIndex;
-    } else {
-        //Mark last chunk as last by clearing last bit
-        result.data()[result.size() - 1] &= ~0b10000000;
+    //------------------QString and QByteArray types serializers-----------------
+    template <typename V,
+              typename std::enable_if_t<std::is_same<V, QString>::value, int> = 0>
+    static QByteArray serializeBasic(const V &value, int &/*outFieldIndex*/) {
+        return serializeLengthDelimited(value.toUtf8());
     }
-    return result;
-}
 
-template <typename V,
-          typename std::enable_if_t<std::is_same<V, QString>::value, int> = 0>
-static QByteArray serializeBasic(const V &value, int &/*outFieldIndex*/) {
-    return serializeLengthDelimited(value.toUtf8());
-}
+    template <typename V,
+              typename std::enable_if_t<std::is_same<V, QByteArray>::value, int> = 0>
+    static QByteArray serializeBasic(const V &value, int &/*outFieldIndex*/) {
+        return serializeLengthDelimited(value);
+    }
 
-template <typename V,
-          typename std::enable_if_t<std::is_same<V, QByteArray>::value, int> = 0>
-static QByteArray serializeBasic(const V &value, int &/*outFieldIndex*/) {
-    return serializeLengthDelimited(value);
-}
+    //--------------------------List types serializers---------------------------
+    template<typename V,
+             typename std::enable_if_t<!(std::is_same<V, QString>::value
+                                       || std::is_same<V, QByteArray>::value
+                                       || std::is_base_of<QObject, V>::value), int> = 0>
+    static QByteArray serializeListType(const QList<V> &listValue, int &outFieldIndex) {
+        qProtoDebug() << __func__ << "listValue.count" << listValue.count() << "outFiledIndex" << outFieldIndex;
+
+        if (listValue.count() <= 0) {
+            outFieldIndex = NotUsedFieldIndex;
+            return QByteArray();
+        }
 
-//---------------Deserialize basic integral and floating point---------------
-template <typename V,
-          typename std::enable_if_t<std::is_floating_point<V>::value
-                                    || std::is_same<V, fixed32>::value
-                                    || std::is_same<V, fixed64>::value
-                                    || std::is_same<V, sfixed32>::value
-                                    || std::is_same<V, sfixed64>::value, int> = 0>
-static QVariant deserializeBasic(SelfcheckIterator &it) {
-    qProtoDebug() << __func__ << "currentByte:" << QString::number((*it), 16);
-
-    QVariant newPropertyValue(QVariant::fromValue(*(V *)((QByteArray::const_iterator&)it)));
-    it += sizeof(V);
-    return newPropertyValue;
-}
+        int empty = NotUsedFieldIndex;
+        QByteArray serializedList;
+        for (auto &value : listValue) {
+            serializedList.append(serializeBasic<V>(value, empty));
+        }
+        //If internal field type is not LengthDelimited, exact amount of fields to be specified
+        serializedList = prependLengthDelimitedSize(serializedList);
+        return serializedList;
+    }
 
-template <typename V,
-          typename std::enable_if_t<std::is_integral<V>::value
-                                    && std::is_unsigned<V>::value, int> = 0>
-static QVariant deserializeBasic(SelfcheckIterator &it) {
-    qProtoDebug() << __func__ << "currentByte:" << QString::number((*it), 16);
+    template<typename V,
+             typename std::enable_if_t<std::is_same<V, QString>::value, int> = 0>
+    static QByteArray serializeListType(const QList<V> &listValue, int &outFieldIndex) {
+        qProtoDebug() << __func__ << "listValue.count" << listValue.count() << "outFiledIndex" << outFieldIndex;
 
-    return QVariant::fromValue(deserializeVarintCommon<V>(it));
-}
+        if (listValue.count() <= 0) {
+            outFieldIndex = NotUsedFieldIndex;
+            return QByteArray();
+        }
 
-template <typename V,
-          typename std::enable_if_t<std::is_integral<V>::value
-                                    && std::is_signed<V>::value,int> = 0>
-static QVariant deserializeBasic(SelfcheckIterator &it) {
-    qProtoDebug() << __func__ << "currentByte:" << QString::number((*it), 16);
-    using  UV = typename std::make_unsigned<V>::type;
-    UV unsignedValue = deserializeVarintCommon<UV>(it);
-    V value = (unsignedValue >> 1) ^ (-1 * (unsignedValue & 1));
-    return QVariant::fromValue<V>(value);
-}
+        QByteArray serializedList;
+        for (auto &value : listValue) {
+            serializedList.append(QProtobufSerializerPrivate::encodeHeader(outFieldIndex, LengthDelimited));
+            serializedList.append(serializeLengthDelimited(value.toUtf8()));
+        }
 
-template <typename V,
-          typename std::enable_if_t<std::is_same<int32, V>::value
-                                    || std::is_same<int64, V>::value, int> = 0>
-static QVariant deserializeBasic(SelfcheckIterator &it) {
-    qProtoDebug() << __func__ << "currentByte:" << QString::number((*it), 16);
-    using  UV = typename std::make_unsigned<V>::type;
-    UV unsignedValue = deserializeVarintCommon<UV>(it);
-    V value = static_cast<V>(unsignedValue);
-    return QVariant::fromValue(value);
-}
+        outFieldIndex = NotUsedFieldIndex;
+        return serializedList;
+    }
 
-template <typename V,
-          typename std::enable_if_t<std::is_same<QByteArray, V>::value, int> = 0>
-static QVariant deserializeBasic(SelfcheckIterator &it) {
-    return QVariant::fromValue(deserializeLengthDelimited(it));
-}
+    template<typename V,
+             typename std::enable_if_t<std::is_same<V, QByteArray>::value, int> = 0>
+    static QByteArray serializeListType(const QList<V> &listValue, int &outFieldIndex) {
+        qProtoDebug() << __func__ << "listValue.count" << listValue.count() << "outFiledIndex" << outFieldIndex;
 
-template <typename V,
-          typename std::enable_if_t<std::is_same<QString, V>::value, int> = 0>
-static QVariant deserializeBasic(SelfcheckIterator &it) {
-    return QVariant::fromValue(QString::fromUtf8(deserializeLengthDelimited(it)));
-}
+        if (listValue.count() <= 0) {
+            outFieldIndex = NotUsedFieldIndex;
+            return QByteArray();
+        }
 
-template<typename V,
-         typename std::enable_if_t<!(std::is_same<V, QString>::value
-                                   || std::is_same<V, QByteArray>::value
-                                   || std::is_base_of<QObject, V>::value), int> = 0>
-static QByteArray serializeListType(const QList<V> &listValue, int &outFieldIndex) {
-    qProtoDebug() << __func__ << "listValue.count" << listValue.count() << "outFiledIndex" << outFieldIndex;
+        QByteArray serializedList;
+        for (auto &value : listValue) {
+            serializedList.append(QProtobufSerializerPrivate::encodeHeader(outFieldIndex, LengthDelimited));
+            serializedList.append(serializeLengthDelimited(value));
+        }
 
-    if (listValue.count() <= 0) {
         outFieldIndex = NotUsedFieldIndex;
-        return QByteArray();
+        return serializedList;
     }
 
-    int empty = NotUsedFieldIndex;
-    QByteArray serializedList;
-    for (auto &value : listValue) {
-        serializedList.append(serializeBasic<V>(value, empty));
+    //###########################################################################
+    //                               Deserializers
+    //###########################################################################
+    template <typename V,
+              typename std::enable_if_t<std::is_integral<V>::value
+                                        && std::is_unsigned<V>::value, int> = 0>
+    static V deserializeVarintCommon(SelfcheckIterator &it) {
+        qProtoDebug() << __func__ << "currentByte:" << QString::number((*it), 16);
+
+        V value = 0;
+        int k = 0;
+        while (true) {
+            uint64_t byte = static_cast<uint64_t>(*it);
+            value += (byte & 0b01111111) << k;
+            k += 7;
+            if (((*it) & 0b10000000) == 0) {
+                break;
+            }
+            ++it;
+        }
+        ++it;
+        return value;
     }
-    //If internal field type is not LengthDelimited, exact amount of fields to be specified
-    serializedList = prependLengthDelimitedSize(serializedList);
-    return serializedList;
-}
 
-template<typename V,
-         typename std::enable_if_t<std::is_same<V, QString>::value, int> = 0>
-static QByteArray serializeListType(const QList<V> &listValue, int &outFieldIndex) {
-    qProtoDebug() << __func__ << "listValue.count" << listValue.count() << "outFiledIndex" << outFieldIndex;
+    //-------------Integral and floating point types deserializers---------------
+    template <typename V,
+              typename std::enable_if_t<std::is_floating_point<V>::value
+                                        || std::is_same<V, fixed32>::value
+                                        || std::is_same<V, fixed64>::value
+                                        || std::is_same<V, sfixed32>::value
+                                        || std::is_same<V, sfixed64>::value, int> = 0>
+    static QVariant deserializeBasic(SelfcheckIterator &it) {
+        qProtoDebug() << __func__ << "currentByte:" << QString::number((*it), 16);
 
-    if (listValue.count() <= 0) {
-        outFieldIndex = NotUsedFieldIndex;
-        return QByteArray();
+        QVariant newPropertyValue(QVariant::fromValue(*(V *)((QByteArray::const_iterator&)it)));
+        it += sizeof(V);
+        return newPropertyValue;
     }
 
-    QByteArray serializedList;
-    for (auto &value : listValue) {
-        serializedList.append(QProtobufSerializerPrivate::encodeHeader(outFieldIndex, LengthDelimited));
-        serializedList.append(serializeLengthDelimited(value.toUtf8()));
+    template <typename V,
+              typename std::enable_if_t<std::is_integral<V>::value
+                                        && std::is_unsigned<V>::value, int> = 0>
+    static QVariant deserializeBasic(SelfcheckIterator &it) {
+        qProtoDebug() << __func__ << "currentByte:" << QString::number((*it), 16);
+
+        return QVariant::fromValue(deserializeVarintCommon<V>(it));
     }
 
-    outFieldIndex = NotUsedFieldIndex;
-    return serializedList;
-}
+    template <typename V,
+              typename std::enable_if_t<std::is_integral<V>::value
+                                        && std::is_signed<V>::value,int> = 0>
+    static QVariant deserializeBasic(SelfcheckIterator &it) {
+        qProtoDebug() << __func__ << "currentByte:" << QString::number((*it), 16);
+        using  UV = typename std::make_unsigned<V>::type;
+        UV unsignedValue = deserializeVarintCommon<UV>(it);
+        V value = (unsignedValue >> 1) ^ (-1 * (unsignedValue & 1));
+        return QVariant::fromValue<V>(value);
+    }
 
-template<typename V,
-         typename std::enable_if_t<std::is_same<V, QByteArray>::value, int> = 0>
-static QByteArray serializeListType(const QList<V> &listValue, int &outFieldIndex) {
-    qProtoDebug() << __func__ << "listValue.count" << listValue.count() << "outFiledIndex" << outFieldIndex;
+    template <typename V,
+              typename std::enable_if_t<std::is_same<int32, V>::value
+                                        || std::is_same<int64, V>::value, int> = 0>
+    static QVariant deserializeBasic(SelfcheckIterator &it) {
+        qProtoDebug() << __func__ << "currentByte:" << QString::number((*it), 16);
+        using  UV = typename std::make_unsigned<V>::type;
+        UV unsignedValue = deserializeVarintCommon<UV>(it);
+        V value = static_cast<V>(unsignedValue);
+        return QVariant::fromValue(value);
+    }
 
-    if (listValue.count() <= 0) {
-        outFieldIndex = NotUsedFieldIndex;
-        return QByteArray();
+    //-----------------QString and QByteArray types deserializers----------------
+    template <typename V,
+              typename std::enable_if_t<std::is_same<QByteArray, V>::value, int> = 0>
+    static QVariant deserializeBasic(SelfcheckIterator &it) {
+        return QVariant::fromValue(deserializeLengthDelimited(it));
     }
 
-    QByteArray serializedList;
-    for (auto &value : listValue) {
-        serializedList.append(QProtobufSerializerPrivate::encodeHeader(outFieldIndex, LengthDelimited));
-        serializedList.append(serializeLengthDelimited(value));
+    template <typename V,
+              typename std::enable_if_t<std::is_same<QString, V>::value, int> = 0>
+    static QVariant deserializeBasic(SelfcheckIterator &it) {
+        return QVariant::fromValue(QString::fromUtf8(deserializeLengthDelimited(it)));
     }
 
-    outFieldIndex = NotUsedFieldIndex;
-    return serializedList;
-}
+    //-------------------------List types deserializers--------------------------
+    template <typename V,
+              typename std::enable_if_t<std::is_same<V, QByteArray>::value, int> = 0>
+    static void deserializeList(SelfcheckIterator &it, QVariant &previous) {
+        qProtoDebug() << __func__ << "currentByte:" << QString::number((*it), 16);
 
-template <typename V,
-          typename std::enable_if_t<std::is_same<V, QByteArray>::value, int> = 0>
-static void deserializeList(SelfcheckIterator &it, QVariant &previous) {
-    qProtoDebug() << __func__ << "currentByte:" << QString::number((*it), 16);
+        QByteArrayList list = previous.value<QByteArrayList>();
+        list.append(deserializeLengthDelimited(it));
+        previous.setValue(list);
+    }
 
-    QByteArrayList list = previous.value<QByteArrayList>();
-    list.append(deserializeLengthDelimited(it));
-    previous.setValue(list);
-}
+    template <typename V,
+              typename std::enable_if_t<std::is_same<V, QString>::value, int> = 0>
+    static void deserializeList(SelfcheckIterator &it, QVariant &previous) {
+        qProtoDebug() << __func__ << "currentByte:" << QString::number((*it), 16);
 
-template <typename V,
-          typename std::enable_if_t<std::is_same<V, QString>::value, int> = 0>
-static void deserializeList(SelfcheckIterator &it, QVariant &previous) {
-    qProtoDebug() << __func__ << "currentByte:" << QString::number((*it), 16);
+        QStringList list = previous.value<QStringList>();
+        QByteArray value = deserializeLengthDelimited(it);
+        list.append(QString::fromUtf8(value));
+        previous.setValue(list);
+    }
 
-    QStringList list = previous.value<QStringList>();
-    QByteArray value = deserializeLengthDelimited(it);
-    list.append(QString::fromUtf8(value));
-    previous.setValue(list);
-}
+    template <typename V,
+              typename std::enable_if_t<!(std::is_same<V, QString>::value
+                                        || std::is_same<V, QByteArray>::value
+                                        || std::is_base_of<QObject, V>::value), int> = 0>
+    static void deserializeList(SelfcheckIterator &it, QVariant &previous) {
+        qProtoDebug() << __func__ << "currentByte:" << QString::number((*it), 16);
 
-template <typename V,
-          typename std::enable_if_t<!(std::is_same<V, QString>::value
-                                    || std::is_same<V, QByteArray>::value
-                                    || std::is_base_of<QObject, V>::value), int> = 0>
-static void deserializeList(SelfcheckIterator &it, QVariant &previous) {
-    qProtoDebug() << __func__ << "currentByte:" << QString::number((*it), 16);
-
-    QList<V> out;
-    unsigned int count = deserializeVarintCommon<uint32>(it);
-    SelfcheckIterator lastVarint = it + count;
-    while (it != lastVarint) {
-        QVariant variant = deserializeBasic<V>(it);
-        out.append(variant.value<V>());
+        QList<V> out;
+        unsigned int count = deserializeVarintCommon<uint32>(it);
+        SelfcheckIterator lastVarint = it + count;
+        while (it != lastVarint) {
+            QVariant variant = deserializeBasic<V>(it);
+            out.append(variant.value<V>());
+        }
+        previous.setValue(out);
     }
-    previous.setValue(out);
-}
 
-static QByteArray deserializeLengthDelimited(SelfcheckIterator &it) {
-    qProtoDebug() << __func__ << "currentByte:" << QString::number((*it), 16);
+    //###########################################################################
+    //                             Common functions
+    //###########################################################################
+    static QByteArray deserializeLengthDelimited(SelfcheckIterator &it) {
+        qProtoDebug() << __func__ << "currentByte:" << QString::number((*it), 16);
 
-    unsigned int length = deserializeVarintCommon<uint32>(it);
-    QByteArray result((QByteArray::const_iterator&)it, length); //TODO it's possible to void buffeer copying by setupimg new "end of QByteArray";
-    it += length;
-    return result;
-}
+        unsigned int length = deserializeVarintCommon<uint32>(it);
+        QByteArray result((QByteArray::const_iterator&)it, length); //TODO it's possible to void buffeer copying by setupimg new "end of QByteArray";
+        it += length;
+        return result;
+    }
 
-static QByteArray serializeLengthDelimited(const QByteArray &data) {
-    qProtoDebug() << __func__ << "data.size" << data.size() << "data" << data.toHex();
-    QByteArray result(data);
-    //Varint serialize field size and apply result as starting point
-    result = prependLengthDelimitedSize(result);
-    return result;
-}
+    static QByteArray serializeLengthDelimited(const QByteArray &data) {
+        qProtoDebug() << __func__ << "data.size" << data.size() << "data" << data.toHex();
+        QByteArray result(data);
+        //Varint serialize field size and apply result as starting point
+        result = prependLengthDelimitedSize(result);
+        return result;
+    }
 
-static bool decodeHeader(SelfcheckIterator &it, int &fieldIndex, WireTypes &wireType);
-static QByteArray encodeHeader(int fieldIndex, WireTypes wireType);
+    static bool decodeHeader(SelfcheckIterator &it, int &fieldIndex, WireTypes &wireType);
+    static QByteArray encodeHeader(int fieldIndex, WireTypes wireType);
 
-/**
+    /**
      * @brief Gets length of a byte-array and prepends to it its serialized length value
      *      using the appropriate serialization algorithm
      *
      *
      * @param[in, out] serializedList Byte-array to be prepended
      */
-static QByteArray prependLengthDelimitedSize(const QByteArray &data)
-{
-    return serializeVarintCommon<uint32_t>(data.size()) + data;
-}
+    static QByteArray prependLengthDelimitedSize(const QByteArray &data)
+    {
+        return serializeVarintCommon<uint32_t>(data.size()) + data;
+    }
+
+    // this set of 3 methods is used to skip bytes corresponding to an unexpected property
+    // in a serialized message met while the message being deserialized
+    static int skipSerializedFieldBytes(SelfcheckIterator &it, WireTypes type);
+
+    static void deserializeMapField(QVariant &value, SelfcheckIterator &it);
 
-// this set of 3 methods is used to skip bytes corresponding to an unexpected property
-// in a serialized message met while the message being deserialized
-static void skipVarint(SelfcheckIterator &it);
-static void skipLengthDelimited(SelfcheckIterator &it);
-static int skipSerializedFieldBytes(SelfcheckIterator &it, WireTypes type);
-static void deserializeMapField(QVariant &value, SelfcheckIterator &it);
+    template <typename T,
+              typename std::enable_if_t<!std::is_base_of<QObject, T>::value, int> = 0>
+    static void wrapSerializer(QAbstractProtobufSerializer::SerializerRegistry &handlers, const std::function<QByteArray(const T &, int &)> &s, const std::function<QVariant(SelfcheckIterator &)> &d, WireTypes type)
+    {
+        handlers[qMetaTypeId<T>()] = {
+            [s](const QVariant &value, int &fieldIndex) {
+                return s(value.value<T>(), fieldIndex);
+            },
+            [d](SelfcheckIterator &it, QVariant & value){
+                value = d(it);
+            },
+            type
+        };
+    }
+
+    template <typename T,
+    typename std::enable_if_t<!std::is_base_of<QObject, T>::value, int> = 0>
+    static void wrapSerializer(QAbstractProtobufSerializer::SerializerRegistry &handlers, const std::function<QByteArray(const T &, int &)> &s, const std::function<void(SelfcheckIterator &it, QVariant & value)> &d, WireTypes type)
+    {
+        handlers[qMetaTypeId<T>()] = {
+            [s](const QVariant &value, int &fieldIndex) {
+                return s(value.value<T>(), fieldIndex);
+            },
+            d,
+            type
+        };
+    }
+protected:
+    static void skipVarint(SelfcheckIterator &it);
+    static void skipLengthDelimited(SelfcheckIterator &it);
 };
 
 //###########################################################################
@@ -481,4 +502,3 @@ inline bool QProtobufSerializerPrivate::decodeHeader(SelfcheckIterator &it, int
 }
 
 }
-

+ 6 - 6
src/protobuf/qprotobufserializerregistry.cpp

@@ -27,23 +27,23 @@
 
 using namespace qtprotobuf;
 
-QAbstractProtobufSerializer::SerializerRegistry QProtobufSerializerRegistry::serializers = {};
+QAbstractProtobufSerializer::SerializerRegistry QProtobufSerializerRegistry::handlers = {};
 std::unique_ptr<QAbstractProtobufSerializer> QProtobufSerializerRegistry::basicSerializer = std::make_unique<QProtobufSerializer>();
 QAbstractProtobufSerializer::SerializationHandlers QProtobufSerializerRegistry::empty;
 
 const QAbstractProtobufSerializer::SerializationHandlers &QProtobufSerializerRegistry::handler(int userType)
 {
-    auto it = serializers.find(userType);
-    if (it != serializers.end()) {
+    QAbstractProtobufSerializer::SerializerRegistry::const_iterator it = handlers.find(userType);
+    if (it != handlers.end()) {
         return it->second;
     }
 
     if (basicSerializer != nullptr) {
-        it = basicSerializer->serializers.find(userType);
-        if (it != basicSerializer->serializers.end()) {
+        it = basicSerializer->handlers().find(userType);
+        if (it != basicSerializer->handlers().end()) {
             return it->second;
         }
     }
-
+    qProtoCritical() << "Serializer for user type: " << QMetaType::typeName(userType) << " is not found";
     return empty;
 }

+ 105 - 38
src/protobuf/qprotobufserializerregistry.h

@@ -39,26 +39,45 @@
 
 namespace qtprotobuf {
 
+/**
+ * @brief The QProtobufSerializerRegistry class provides api to register serializers of QObjects
+ *
+ * @details The QProtobufSerializerRegistry class registers serializers/deserializers for classes inherited of QObject.
+ *          To register serializers for user-defined class it has to be inherited of QObjec contain macro's.
+ *          @code{.cpp}
+ *          class MyType : public QObject
+ *          {
+ *              Q_OBJECT
+ *              Q_PROTOBUF_OBJECT
+ *              Q_PROPERTY(qprotobuf::sint32 prop READ prop WRITE setProp NOTIFY propChanged)
+ *              ...
+ *              Q_DECLARE_PROTOBUF_SERIALIZERS(MyType)
+ *          };
+ *          @endcode
+ *          Practically code above is generated automaticaly by running qtprotobufgenerator or using cmake build macro
+ *          generate_qtprotobuf, based on .proto files. But it's still possible to reuse manually written code if needed.
+ */
 class QTPROTOBUFSHARED_EXPORT QProtobufSerializerRegistry
 {
     QProtobufSerializerRegistry() = delete;
     ~QProtobufSerializerRegistry() = delete;
+
     Q_DISABLE_COPY(QProtobufSerializerRegistry)
     QProtobufSerializerRegistry(QProtobufSerializerRegistry &&) = delete;
     QProtobufSerializerRegistry &operator =(QProtobufSerializerRegistry &&) = delete;
-    static QAbstractProtobufSerializer::SerializerRegistry serializers;
 
+    static QAbstractProtobufSerializer::SerializerRegistry handlers;
     static std::unique_ptr<QAbstractProtobufSerializer> basicSerializer;
     static QAbstractProtobufSerializer::SerializationHandlers empty;
 public:
     static const QAbstractProtobufSerializer::SerializationHandlers &handler(int userType);
     /**
-    * @brief Serialization of a registered qtproto message object into byte-array
-    *
-    *
-    * @param[in] object Pointer to QObject containing message to be serialized
-    * @result serialized message bytes
-    */
+     * @brief Serialization of a registered qtproto message object into byte-array
+     *
+     *
+     * @param[in] object Pointer to QObject containing message to be serialized
+     * @result serialized message bytes
+     */
     template<typename T>
     static QByteArray serialize(const QObject *object) {
         qProtoDebug() << T::staticMetaObject.className() << "serialize";
@@ -66,54 +85,76 @@ public:
     }
 
     /**
-    * @brief Deserialization of a byte-array into a registered qtproto message object
-    *
-    * @details Properties in a message are identified via ProtobufObjectPrivate::decodeHeader.
-    *          Bytes corresponding to unexpected properties are skipped without any exception
-    *
-    * @param[out] object Pointer to memory where result of deserialization should be injected
-    * @param[in] array Bytes with serialized message
-    */
+     * @brief Deserialization of a byte-array into a registered qtproto message object
+     *
+     * @details Properties in a message are identified via ProtobufObjectPrivate::decodeHeader.
+     *          Bytes corresponding to unexpected properties are skipped without any exception
+     *
+     * @param[out] object Pointer to memory where result of deserialization should be injected
+     * @param[in] array Bytes with serialized message
+     */
     template<typename T>
     static void deserialize(QObject *object, const QByteArray &array) {
         qProtoDebug() << T::staticMetaObject.className() << "deserialize";
         basicSerializer->deserializeObjectCommon(object, array, T::propertyOrdering, T::staticMetaObject);
     }
 
-    //----------------------Functions to work with QObjects------------------------
+
+    /**
+     * @brief Registers serializers for type T in QProtobufSerializerRegistry
+     *
+     * @details generates default serializers for type T. Type T has to be inherited of QObject.
+     */
     template<typename T>
     static void registerSerializers() {
-        serializers[qMetaTypeId<T *>()] = { serializeComplexType<T>,
+        handlers[qMetaTypeId<T *>()] = { serializeComplexType<T>,
                 deserializeComplexType<T>, LengthDelimited };
-        serializers[qMetaTypeId<QList<QSharedPointer<T>>>()] = { serializeList<T>,
+        handlers[qMetaTypeId<QList<QSharedPointer<T>>>()] = { serializeList<T>,
                 deserializeList<T>, LengthDelimited };
     }
 
+    /**
+     * @brief Registers serializers for type QMap<K, V> in QProtobufSerializerRegistry
+     *
+     * @details generates default serializers for QMap<K, V>.
+     */
     template<typename K, typename V,
              typename std::enable_if_t<!std::is_base_of<QObject, V>::value, int> = 0>
     static void registerMap() {
-        serializers[qMetaTypeId<QMap<K, V>>()] = { serializeMap<K, V>,
+        handlers[qMetaTypeId<QMap<K, V>>()] = { serializeMap<K, V>,
         deserializeMap<K, V>, LengthDelimited };
     }
 
+    /**
+     * @brief Registers serializers for type QMap<K, V> in QProtobufSerializerRegistry
+     *
+     * @details generates default serializers for QMap<K, V>. Specialization for V type
+     *          inherited of QObject.
+     */
     template<typename K, typename V,
              typename std::enable_if_t<std::is_base_of<QObject, V>::value, int> = 0>
     static void registerMap() {
-        serializers[qMetaTypeId<QMap<K, QSharedPointer<V>>>()] = { serializeMap<K, V>,
+        handlers[qMetaTypeId<QMap<K, QSharedPointer<V>>>()] = { serializeMap<K, V>,
         deserializeMap<K, V>, LengthDelimited };
     }
 
 private:
-    //###########################################################################
-    //                           Serialization helpers
-    //###########################################################################
+    /**
+     * @private
+     *
+     * @brief default serializer template for type T inherited of QObject
+     */
     template <typename T,
               typename std::enable_if_t<std::is_base_of<QObject, T>::value, int> = 0>
     static QByteArray serializeComplexType(const QVariant &value, int &/*outFieldIndex*/) {
         return basicSerializer->serializeObject(value.value<T *>(), T::propertyOrdering, T::staticMetaObject);
     }
 
-    //------------------Serialize lists of QObject based classes-----------------
+    /**
+     * @private
+     *
+     * @brief default serializer template for list of type T objects inherited of QObject
+     */
     template<typename V,
              typename std::enable_if_t<std::is_base_of<QObject, V>::value, int> = 0>
     static QByteArray serializeList(const QVariant &listValue, int &outFieldIndex) {
@@ -140,7 +181,11 @@ private:
         return serializedList;
     }
 
-    //-------------------------Serialize maps of any type------------------------
+    /**
+     * @private
+     *
+     * @brief default serializer template for map of key K, value V
+     */
     template<typename K, typename V,
              typename std::enable_if_t<!std::is_base_of<QObject, V>::value, int> = 0>
     static QByteArray serializeMap(const QVariant &value, int &outFieldIndex) {
@@ -155,6 +200,12 @@ private:
         return mapResult;
     }
 
+    /**
+     * @private
+     *
+     * @brief default serializer template for map of type key K, value V. Specialization for V
+     *        inherited of QObject
+     */
     template<typename K, typename V,
              typename std::enable_if_t<std::is_base_of<QObject, V>::value, int> = 0>
     static QByteArray serializeMap(const QVariant &value, int &outFieldIndex) {
@@ -173,10 +224,24 @@ private:
         return mapResult;
     }
 
-    //###########################################################################
-    //                           Deserialization helpers
-    //###########################################################################
-    //-----------------Deserialize lists of QObject based classes----------------
+    /**
+     * @private
+     *
+     * @brief default deserializer template for type T inherited of QObject
+     */
+    template <typename T,
+              typename std::enable_if_t<std::is_base_of<QObject, T>::value, int> = 0>
+    static void deserializeComplexType(SelfcheckIterator &it, QVariant &to) {
+        T *value = new T;
+        basicSerializer->deserializeObject(value, it, T::propertyOrdering, T::staticMetaObject);
+        to = QVariant::fromValue<T *>(value);
+    }
+
+    /**
+     * @private
+     *
+     * @brief default deserializer template for list of type T objects inherited of QObject
+     */
     template <typename V,
               typename std::enable_if_t<std::is_base_of<QObject, V>::value, int> = 0>
     static void deserializeList(SelfcheckIterator &it, QVariant &previous) {
@@ -189,7 +254,11 @@ private:
         previous.setValue(list);
     }
 
-    //-----------------------Deserialize maps of any type------------------------
+    /**
+     * @private
+     *
+     * @brief default deserializer template for map of key K, value V
+     */
     template <typename K, typename V,
               typename std::enable_if_t<!std::is_base_of<QObject, V>::value, int> = 0>
     static void deserializeMap(SelfcheckIterator &it, QVariant &previous) {
@@ -204,6 +273,12 @@ private:
         previous = QVariant::fromValue<QMap<K, V>>(out);
     }
 
+    /**
+     * @private
+     *
+     * @brief default deserializer template for map of type key K, value V. Specialization for V
+     *        inherited of QObject
+     */
     template <typename K, typename V,
               typename std::enable_if_t<std::is_base_of<QObject, V>::value, int> = 0>
     static void deserializeMap(SelfcheckIterator &it, QVariant &previous) {
@@ -217,14 +292,6 @@ private:
         out[key.value<K>()] = QSharedPointer<V>(value.value<V *>());
         previous = QVariant::fromValue<QMap<K, QSharedPointer<V>>>(out);
     }
-
-    template <typename T,
-              typename std::enable_if_t<std::is_base_of<QObject, T>::value, int> = 0>
-    static void deserializeComplexType(SelfcheckIterator &it, QVariant &to) {
-        T *value = new T;
-        basicSerializer->deserializeObject(value, it, T::propertyOrdering, T::staticMetaObject);
-        to = QVariant::fromValue<T *>(value);
-    }
 };
 
 }

+ 33 - 4
src/protobuf/qtprotobuftypes.h

@@ -32,6 +32,12 @@
 
 namespace qtprotobuf {
 
+/**
+ * @brief The WireTypes enumeration reflects protobuf default wiretypes
+ *
+ * @details Look at https://developers.google.com/protocol-buffers/docs/encoding for details.
+ *
+ */
 enum WireTypes {
     UnknownWireType = -1,
     Varint = 0,
@@ -40,8 +46,17 @@ enum WireTypes {
     Fixed32 = 5
 };
 
+//! @private
+using QProtobufPropertyOrdering = std::unordered_map<int, int>;
+
+//! @private
 constexpr int NotUsedFieldIndex = -1;
 
+/**
+ * @private
+ *
+ * @brief the transparent class is template to define set of extra types for integral types, to cover protobuf needs
+ */
 template<typename T, int = 0>
 struct transparent {
     transparent(T t = T()) : _t(t){}
@@ -107,45 +122,59 @@ Q_DECLARE_METATYPE(qtprotobuf::sfixed64List)
 Q_DECLARE_METATYPE(qtprotobuf::FloatList)
 Q_DECLARE_METATYPE(qtprotobuf::DoubleList)
 
+//! @private
 template<>
 struct std::make_unsigned<qtprotobuf::int32> { typedef typename std::make_unsigned<decltype(qtprotobuf::int32::_t)>::type type; };
+//! @private
 template<>
 struct std::make_unsigned<qtprotobuf::int64> { typedef typename std::make_unsigned<decltype(qtprotobuf::int64::_t)>::type type; };
+//! @private
 template<>
 struct std::make_unsigned<qtprotobuf::fixed32> { typedef typename std::make_unsigned<decltype(qtprotobuf::fixed32::_t)>::type type; };
+//! @private
 template<>
 struct std::make_unsigned<qtprotobuf::fixed64> { typedef typename std::make_unsigned<decltype(qtprotobuf::fixed64::_t)>::type type; };
+//! @private
 template<>
 struct std::make_unsigned<qtprotobuf::sfixed32> { typedef typename std::make_unsigned<decltype(qtprotobuf::sfixed32::_t)>::type type; };
+//! @private
 template<>
 struct std::make_unsigned<qtprotobuf::sfixed64> { typedef typename std::make_unsigned<decltype(qtprotobuf::sfixed64::_t)>::type type; };
 
+//! @private
 template<>
 struct std::make_signed<qtprotobuf::int32> { typedef typename std::make_signed<decltype(qtprotobuf::int32::_t)>::type type; };
+//! @private
 template<>
 struct std::make_signed<qtprotobuf::int64> { typedef typename std::make_signed<decltype(qtprotobuf::int64::_t)>::type type; };
+//! @private
 template<>
 struct std::make_signed<qtprotobuf::fixed32> { typedef typename std::make_signed<decltype(qtprotobuf::fixed32::_t)>::type type; };
+//! @private
 template<>
 struct std::make_signed<qtprotobuf::fixed64> { typedef typename std::make_signed<decltype(qtprotobuf::fixed64::_t)>::type type; };
+//! @private
 template<>
 struct std::make_signed<qtprotobuf::sfixed32> { typedef typename std::make_signed<decltype(qtprotobuf::sfixed32::_t)>::type type; };
+//! @private
 template<>
 struct std::make_signed<qtprotobuf::sfixed64> { typedef typename std::make_signed<decltype(qtprotobuf::sfixed64::_t)>::type type; };
 
+//! @private
 template<>
 struct std::is_signed<qtprotobuf::int32> : public is_signed<decltype(qtprotobuf::int32::_t)> {};
+//! @private
 template<>
 struct std::is_signed<qtprotobuf::int64> : public is_signed<decltype(qtprotobuf::int64::_t)> {};
+//! @private
 template<>
 struct std::is_signed<qtprotobuf::fixed32> : public is_signed<decltype(qtprotobuf::fixed32::_t)> {};
+//! @private
 template<>
 struct std::is_signed<qtprotobuf::fixed64> : public is_signed<decltype(qtprotobuf::fixed64::_t)> {};
+//! @private
 template<>
 struct std::is_signed<qtprotobuf::sfixed32> : public is_signed<decltype(qtprotobuf::sfixed32::_t)> {};
+//! @private
 template<>
 struct std::is_signed<qtprotobuf::sfixed64> : public is_signed<decltype(qtprotobuf::sfixed64::_t)> {};
-
-namespace qtprotobuf {
-using QProtobufPropertyOrdering = std::unordered_map<int, int>;
-}