ソースを参照

Add logging for support library

- Define qt logging category for qtprotobuflibrary
- Add debug traces to serialization/deserialization
TODO: Add function parameters print to output
Alexey Edelev 6 年 前
コミット
a4d64f75d7

+ 6 - 1
src/lib/CMakeLists.txt

@@ -11,7 +11,12 @@ if (Qt5_POSITION_INDEPENDENT_CODE)
   set(CMAKE_POSITION_INDEPENDENT_CODE ON)
 endif()
 
-add_library(qtprotobufsupport universallistmodelbase.cpp universallistmodel.cpp protobufobject.cpp qtprotobuf.cpp)
+add_library(qtprotobufsupport
+    universallistmodelbase.cpp
+    universallistmodel.cpp
+    protobufobject.cpp
+    qtprotobuf.cpp
+    qtprotobuflogging.cpp)
 
 set_target_properties(qtprotobufsupport PROPERTIES PUBLIC_HEADER "universallistmodelbase.h;universallistmodel.h;protobufobject.h;qtprotobuftypes.h;qtprotobuf.h")
 

+ 28 - 4
src/lib/protobufobject.h

@@ -26,7 +26,6 @@
 #pragma once
 
 #include <QObject>
-#include <QDebug>
 #include <QMetaObject>
 #include <QMetaProperty>
 #include <QBitArray>
@@ -34,7 +33,10 @@
 #include <unordered_map>
 #include <memory>
 #include <type_traits>
+#include <typeinfo>
+
 #include <qtprotobuftypes.h>
+#include <qtprotobuflogging.h>
 
 #define ASSERT_FIELD_NUMBER(X) Q_ASSERT_X(X < 128 && X > 0 && X != NotUsedFieldIndex, T::staticMetaObject.className(), "fieldIndex is out of range")
 
@@ -60,7 +62,6 @@ protected:
      *  meaning |  Field index  |   Type
      */
     inline static unsigned char encodeHeaderByte(int fieldIndex, WireTypes wireType) {
-
         unsigned char header = (fieldIndex << 3) | wireType;
         return *(char *)&header;
     }
@@ -75,6 +76,7 @@ protected:
     }
 
     QByteArray serializeValue(const QVariant& propertyValue, int fieldIndex, bool isFixed = false) {
+        qProtoDebug() << __func__;
         QByteArray result;
         WireTypes type = UnknownWireType;
         switch (propertyValue.type()) {
@@ -142,6 +144,7 @@ protected:
     }
 
     QByteArray serializeLengthDelimited(const QByteArray &data) {
+        qProtoDebug() << __func__;
         //Varint serialize field size and apply result as starting point
         QByteArray result = serializeVarint(static_cast<unsigned int>(data.size()));
         result.append(data);
@@ -149,6 +152,7 @@ protected:
     }
 
     QByteArray serializeUserType(const QVariant &propertyValue, int &fieldIndex) {
+        qProtoDebug() << __func__;
         int userType = propertyValue.userType();
         if (userType == qMetaTypeId<IntList>()) {
             return serializeListType(propertyValue.value<IntList>(), fieldIndex);
@@ -171,6 +175,7 @@ protected:
              typename std::enable_if_t<std::is_integral<V>::value
                                        || std::is_floating_point<V>::value, int> = 0>
     QByteArray serializeListType(const QList<V> &listValue, int &outFieldIndex) {
+        qProtoDebug() << __func__;
         if (listValue.count() <= 0) {
             outFieldIndex = NotUsedFieldIndex;
             return QByteArray();
@@ -189,6 +194,7 @@ protected:
              typename std::enable_if_t<std::is_same<V, QString>::value
                                        || std::is_same<V, QByteArray>::value, int> = 0>
     QByteArray serializeListType(const QList<V> &listValue, int &outFieldIndex) {
+        qProtoDebug() << __func__;
         if (listValue.count() <= 0) {
             outFieldIndex = NotUsedFieldIndex;
             return QByteArray();
@@ -206,6 +212,7 @@ protected:
     //TODO: This specialization is deprecated and won't be used in future
     QByteArray serializeListType(const QVariantList &listValue, int &outFieldIndex)
     {
+        qProtoDebug() << __func__;
         if (listValue.count() <= 0) {
             outFieldIndex = NotUsedFieldIndex;
             return QByteArray();
@@ -233,6 +240,7 @@ protected:
                                         || std::is_same<V, unsigned int>::value
                                         || std::is_same<V, qulonglong>::value, int> = 0>
     QByteArray serializeFixed(V value) {
+        qProtoDebug() << __func__;
         //Reserve required amount of bytes
         QByteArray result(sizeof(V), '\0');
         *(V*)(result.data()) = value;
@@ -242,6 +250,7 @@ protected:
     template <typename V,
               typename std::enable_if_t<std::is_signed<V>::value, int> = 0>
     QByteArray serializeVarint(V value) {
+        qProtoDebug() << __func__;
         using UV = typename std::make_unsigned<V>::type;
         //Use ZigZag convertion first and apply unsigned variant next
         value = (value << 1) ^ (value >> (sizeof(UV) * 8 - 1));
@@ -252,6 +261,7 @@ protected:
     template <typename V,
               typename std::enable_if_t<std::is_unsigned<V>::value, int> = 0>
     QByteArray serializeVarint(V value) {
+        qProtoDebug() << __func__;
         QByteArray result;
         //Reserve maximum required amount of bytes
         result.reserve(sizeof(V));
@@ -277,6 +287,7 @@ protected:
 //####################################################
     void deserializeProperty(WireTypes wireType, const QMetaProperty &metaProperty, QByteArray::const_iterator &it)
     {
+        qProtoDebug() << __func__ << " wireType: " << wireType << " metaProperty: " << metaProperty.typeName();
         QVariant newPropertyValue;
         int type = metaProperty.type();
         switch(type) {
@@ -335,6 +346,7 @@ protected:
                                         || std::is_same<V, unsigned int>::value
                                         || std::is_same<V, qulonglong>::value, int> = 0>
     QVariant deserializeFixed(QByteArray::const_iterator &it) {
+        qProtoDebug() << __func__;
         QVariant newPropertyValue(QVariant::fromValue(*(V*)it));
         it += sizeof(V);
         return newPropertyValue;
@@ -343,12 +355,14 @@ protected:
     template <typename V,
               typename std::enable_if_t<std::is_unsigned<V>::value, int> = 0>
     QVariant deserializeVarint(QByteArray::const_iterator &it) {
+        qProtoDebug() << __func__;
         return QVariant::fromValue(deserializeVarintCommon<V>(it));
     }
 
     template <typename V,
               typename std::enable_if_t<std::is_signed<V>::value, int> = 0>
     QVariant deserializeVarint(QByteArray::const_iterator &it) {
+        qProtoDebug() << __func__;
         using UV = typename std::make_unsigned<V>::type;
         UV unsignedValue = deserializeVarintCommon<UV>(it);
         V value = (unsignedValue >> 1) ^ (-(unsignedValue & 1));
@@ -358,6 +372,7 @@ protected:
 
     template <typename V>
     V deserializeVarintCommon(QByteArray::const_iterator &it) {
+        qProtoDebug() << __func__;
         V value = 0;
         int k = 0;
         while((*it) & 0x80) {
@@ -371,6 +386,7 @@ protected:
     }
 
     QByteArray deserializeLengthDelimited(QByteArray::const_iterator &it) {
+        qProtoDebug() << __func__;
         unsigned int length = deserializeVarint<unsigned int>(it).toUInt();
         QByteArray result(it, length);
         it += length;
@@ -379,6 +395,7 @@ protected:
 
     void deserializeUserType(int userType, QByteArray::const_iterator& it, QVariant &newValue)
     {
+        qProtoDebug() << __func__;
         if (userType == qMetaTypeId<IntList>()) {
             newValue = deserializeVarintListType<int>(it);
         } else if(userType == qMetaTypeId<FloatList>()) {
@@ -396,6 +413,7 @@ protected:
               typename std::enable_if_t<std::is_same<V, QString>::value
                                         || std::is_same<V, QByteArray>::value, int> = 0>
     QByteArray deserializeListType(QByteArray::const_iterator& it) {
+        qProtoDebug() << __func__;
         return deserializeLengthDelimited(it);
     }
 
@@ -404,6 +422,7 @@ protected:
                                         || std::is_same<V, unsigned int>::value
                                         || std::is_same<V, qulonglong>::value, int> = 0>
     QVariant deserializeListType(QByteArray::const_iterator& it) {
+        qProtoDebug() << __func__;
         QList<V> out;
         unsigned int count = deserializeVarint<unsigned int>(it).toUInt() / sizeof(V);
         for (int i = 0; i < count; i++) {
@@ -416,6 +435,7 @@ protected:
     template <typename V,
               typename std::enable_if_t<std::is_same<V, int>::value, int> = 0>
     QVariant deserializeVarintListType(QByteArray::const_iterator& it) {
+        qProtoDebug() << __func__;
         QList<V> out;
         unsigned int count = deserializeVarint<unsigned int>(it).toUInt();
         QByteArray::const_iterator lastVarint = it + count;
@@ -436,10 +456,12 @@ class ProtobufObject : public ProtobufObjectPrivate
 {
 protected:
     QByteArray serializePrivate() override {
+        qProtoDebug() << T::staticMetaObject.className() << "serializePrivate";
         return serialize();
     }
 
     void deserializePrivate(const QByteArray &data) override {
+        qProtoDebug() << T::staticMetaObject.className() << "deserializePrivate";
         deserialize(data);
     }
 
@@ -447,6 +469,7 @@ public:
     explicit ProtobufObject(QObject *parent = nullptr) : ProtobufObjectPrivate(parent) {}
 
     QByteArray serialize() {
+        qProtoDebug() << T::staticMetaObject.className() << "serialize";
         QByteArray result;
         T *instance = dynamic_cast<T *>(this);
         for (auto field : T::propertyOrdering) {
@@ -465,6 +488,7 @@ public:
     }
 
     void deserialize(const QByteArray &array) {
+        qProtoDebug() << T::staticMetaObject.className() << "deserialize";
         T *instance = dynamic_cast<T *>(this);
 
         for(QByteArray::const_iterator it = array.begin(); it != array.end();) {
@@ -473,7 +497,7 @@ public:
             WireTypes wireType = UnknownWireType;
             if (!decodeHeaderByte(*it, fieldNumber, wireType)) {
                 ++it;
-                qCritical() << "Message received doesn't contains valid header byte. "
+                qProtoCritical() << "Message received doesn't contains valid header byte. "
                                "Trying next, but seems stream is broken";
                 continue;
             }
@@ -481,7 +505,7 @@ public:
             auto propertyNumberIt = T::propertyOrdering.find(fieldNumber);
             if (propertyNumberIt == std::end(T::propertyOrdering)) {
                 ++it;
-                qCritical() << "Message received contains invalid field number. "
+                qProtoCritical() << "Message received contains invalid field number. "
                                "Trying next, but seems stream is broken";
                 continue;
             }

+ 0 - 2
src/lib/qtprotobuf.h

@@ -27,8 +27,6 @@
 
 #include <qtprotobuftypes.h>
 
-#include <QDebug>
-
 namespace qtprotobuf {
 
 class QtProtobuf {

+ 28 - 0
src/lib/qtprotobuflogging.cpp

@@ -0,0 +1,28 @@
+/*
+ * 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 "qtprotobuflogging.h"
+
+Q_LOGGING_CATEGORY(qtprotobuflog, "qtprotobuflog")

+ 34 - 0
src/lib/qtprotobuflogging.h

@@ -0,0 +1,34 @@
+/*
+ * 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 <QLoggingCategory>
+
+Q_DECLARE_LOGGING_CATEGORY(qtprotobuflog)
+
+#define qProtoDebug(...) qCDebug(qtprotobuflog, __VA_ARGS__)
+#define qProtoInfo(...) qCInfo(qtprotobuflog, __VA_ARGS__)
+#define qProtoWarning(...) qCWarning(qtprotobuflog, __VA_ARGS__)
+#define qProtoCritical(...) qCCritical(qtprotobuflog, __VA_ARGS__)