From 71e41d7230650e4b25cfe0f2ac8e3c87e8e4119e Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 25 Jan 2018 14:11:33 -0800 Subject: [PATCH] CBOR: Add QDebug operators for the Qt CBOR value-like types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I added a function that returns the string identifiers for QCborKnownTags and QCborSimpleType, in order to facilitate writing a QTest::toString for those types, as neither enum is part of a Q_OBJECT or Q_GADGET class. Change-Id: I56b444f9d6274221a3b7fffd150d2d26a1925c19 Reviewed-by: MÃ¥rten Nordheim --- .../serialization/convert/cborconverter.cpp | 10 -- src/corelib/serialization/qcborarray.cpp | 14 +++ src/corelib/serialization/qcborarray.h | 4 + src/corelib/serialization/qcborcommon.h | 7 ++ src/corelib/serialization/qcbormap.cpp | 14 +++ src/corelib/serialization/qcbormap.h | 4 + src/corelib/serialization/qcborstream.cpp | 113 ++++++++++++++++++ src/corelib/serialization/qcborvalue.cpp | 57 +++++++++ src/corelib/serialization/qcborvalue.h | 4 + 9 files changed, 217 insertions(+), 10 deletions(-) diff --git a/examples/corelib/serialization/convert/cborconverter.cpp b/examples/corelib/serialization/convert/cborconverter.cpp index 5c034680c2..c872753ffd 100644 --- a/examples/corelib/serialization/convert/cborconverter.cpp +++ b/examples/corelib/serialization/convert/cborconverter.cpp @@ -97,11 +97,6 @@ QDataStream &operator>>(QDataStream &ds, QCborSimpleType &st) return ds; } -QDebug &operator<<(QDebug &d, QCborSimpleType st) -{ - return d << quint8(st); -} - QDataStream &operator<<(QDataStream &ds, QCborTag tag) { return ds << quint64(tag); @@ -115,11 +110,6 @@ QDataStream &operator>>(QDataStream &ds, QCborTag &tag) return ds; } -QDebug &operator<<(QDebug &d, QCborTag tag) -{ - return d << quint64(tag); -} - QT_END_NAMESPACE // We can't use QCborValue::toVariant directly because that would destroy diff --git a/src/corelib/serialization/qcborarray.cpp b/src/corelib/serialization/qcborarray.cpp index 71a1ad2e9a..020841d604 100644 --- a/src/corelib/serialization/qcborarray.cpp +++ b/src/corelib/serialization/qcborarray.cpp @@ -1138,4 +1138,18 @@ void QCborArray::detach(qsizetype reserved) Returns the offset of this iterator relative to \a other. */ +#if !defined(QT_NO_DEBUG_STREAM) +QDebug operator<<(QDebug dbg, const QCborArray &a) +{ + QDebugStateSaver saver(dbg); + dbg.nospace() << "QCborArray{"; + const char *comma = ""; + for (auto v : a) { + dbg << comma << v; + comma = ", "; + } + return dbg << '}'; +} +#endif + QT_END_NAMESPACE diff --git a/src/corelib/serialization/qcborarray.h b/src/corelib/serialization/qcborarray.h index c3c319b8dd..f10fcac2cb 100644 --- a/src/corelib/serialization/qcborarray.h +++ b/src/corelib/serialization/qcborarray.h @@ -273,6 +273,10 @@ inline QCborArray QCborValueRef::toArray(const QCborArray &a) const return concrete().toArray(a); } +#if !defined(QT_NO_DEBUG_STREAM) +Q_CORE_EXPORT QDebug operator<<(QDebug, const QCborArray &a); +#endif + QT_END_NAMESPACE #endif // QCBORARRAY_H diff --git a/src/corelib/serialization/qcborcommon.h b/src/corelib/serialization/qcborcommon.h index fe77e65a67..95e40ccedc 100644 --- a/src/corelib/serialization/qcborcommon.h +++ b/src/corelib/serialization/qcborcommon.h @@ -42,6 +42,7 @@ #include #include +#include #if 0 #pragma qt_class(QtCborCommon) @@ -119,6 +120,12 @@ public: QString toString() const; }; +#if !defined(QT_NO_DEBUG_STREAM) +Q_CORE_EXPORT QDebug operator<<(QDebug, QCborSimpleType st); +Q_CORE_EXPORT QDebug operator<<(QDebug, QCborKnownTags tg); +Q_CORE_EXPORT QDebug operator<<(QDebug, QCborTag tg); +#endif + QT_END_NAMESPACE Q_DECLARE_METATYPE(QCborSimpleType) diff --git a/src/corelib/serialization/qcbormap.cpp b/src/corelib/serialization/qcbormap.cpp index f7d58ca90b..46ac9c1ec8 100644 --- a/src/corelib/serialization/qcbormap.cpp +++ b/src/corelib/serialization/qcbormap.cpp @@ -1550,4 +1550,18 @@ void QCborMap::detach(qsizetype reserved) \sa operator+=(), operator-() */ +#if !defined(QT_NO_DEBUG_STREAM) +QDebug operator<<(QDebug dbg, const QCborMap &m) +{ + QDebugStateSaver saver(dbg); + dbg.nospace() << "QCborMap{"; + const char *open = "{"; + for (auto pair : m) { + dbg << open << pair.first << ", " << pair.second << '}'; + open = ", {"; + } + return dbg << '}'; +} +#endif + QT_END_NAMESPACE diff --git a/src/corelib/serialization/qcbormap.h b/src/corelib/serialization/qcbormap.h index 63bfa154fa..9499f46ace 100644 --- a/src/corelib/serialization/qcbormap.h +++ b/src/corelib/serialization/qcbormap.h @@ -322,6 +322,10 @@ inline QCborMap QCborValueRef::toMap(const QCborMap &m) const return concrete().toMap(m); } +#if !defined(QT_NO_DEBUG_STREAM) +Q_CORE_EXPORT QDebug operator<<(QDebug, const QCborMap &m); +#endif + QT_END_NAMESPACE #endif // QCBORMAP_H diff --git a/src/corelib/serialization/qcborstream.cpp b/src/corelib/serialization/qcborstream.cpp index 3cc725e111..f4b96646e4 100644 --- a/src/corelib/serialization/qcborstream.cpp +++ b/src/corelib/serialization/qcborstream.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include QT_BEGIN_NAMESPACE @@ -171,6 +172,33 @@ Q_STATIC_ASSERT(int(QCborStreamReader::Invalid) == CborInvalidType); QCborStreamReader::toSimpleType(), QCborValue::isSimpleType(), QCborValue::toSimpleType() */ +Q_CORE_EXPORT const char *qt_cbor_simpletype_id(QCborSimpleType st) +{ + switch (st) { + case QCborSimpleType::False: + return "False"; + case QCborSimpleType::True: + return "True"; + case QCborSimpleType::Null: + return "Null"; + case QCborSimpleType::Undefined: + return "Undefined"; + } + return nullptr; +} + +#if !defined(QT_NO_DEBUG_STREAM) +QDebug operator<<(QDebug dbg, QCborSimpleType st) +{ + QDebugStateSaver saver(dbg); + const char *id = qt_cbor_simpletype_id(st); + if (id) + return dbg.nospace() << "QCborSimpleType::" << id; + + return dbg.nospace() << "QCborSimpleType(" << uint(st) << ')'; +} +#endif + /*! \enum QCborTag \relates @@ -195,6 +223,79 @@ Q_STATIC_ASSERT(int(QCborStreamReader::Invalid) == CborInvalidType); QCborValue::isTag(), QCborValue::tag() */ +Q_CORE_EXPORT const char *qt_cbor_tag_id(QCborTag tag) +{ + // Casting to QCborKnownTags's underlying type will make the comparison + // below fail if the tag value is out of range. + auto n = std::underlying_type::type(tag); + if (QCborTag(n) == tag) { + switch (QCborKnownTags(n)) { + case QCborKnownTags::DateTimeString: + return "DateTimeString"; + case QCborKnownTags::UnixTime_t: + return "UnixTime_t"; + case QCborKnownTags::PositiveBignum: + return "PositiveBignum"; + case QCborKnownTags::NegativeBignum: + return "NegativeBignum"; + case QCborKnownTags::Decimal: + return "Decimal"; + case QCborKnownTags::Bigfloat: + return "Bigfloat"; + case QCborKnownTags::COSE_Encrypt0: + return "COSE_Encrypt0"; + case QCborKnownTags::COSE_Mac0: + return "COSE_Mac0"; + case QCborKnownTags::COSE_Sign1: + return "COSE_Sign1"; + case QCborKnownTags::ExpectedBase64url: + return "ExpectedBase64url"; + case QCborKnownTags::ExpectedBase64: + return "ExpectedBase64"; + case QCborKnownTags::ExpectedBase16: + return "ExpectedBase16"; + case QCborKnownTags::EncodedCbor: + return "EncodedCbor"; + case QCborKnownTags::Url: + return "Url"; + case QCborKnownTags::Base64url: + return "Base64url"; + case QCborKnownTags::Base64: + return "Base64"; + case QCborKnownTags::RegularExpression: + return "RegularExpression"; + case QCborKnownTags::MimeMessage: + return "MimeMessage"; + case QCborKnownTags::Uuid: + return "Uuid"; + case QCborKnownTags::COSE_Encrypt: + return "COSE_Encrypt"; + case QCborKnownTags::COSE_Mac: + return "COSE_Mac"; + case QCborKnownTags::COSE_Sign: + return "COSE_Sign"; + case QCborKnownTags::Signature: + return "Signature"; + } + } + return nullptr; +} + +#if !defined(QT_NO_DEBUG_STREAM) +QDebug operator<<(QDebug dbg, QCborTag tag) +{ + QDebugStateSaver saver(dbg); + const char *id = qt_cbor_tag_id(tag); + dbg.nospace() << "QCborTag("; + if (id) + dbg.nospace() << "QCborKnownTags::" << id; + else + dbg.nospace() << quint64(tag); + + return dbg << ')'; +} +#endif + /*! \enum QCborKnownTags \relates @@ -273,6 +374,18 @@ Q_STATIC_ASSERT(int(QCborStreamReader::Invalid) == CborInvalidType); QCborValue::isTag(), QCborValue::tag() */ +#if !defined(QT_NO_DEBUG_STREAM) +QDebug operator<<(QDebug dbg, QCborKnownTags tag) +{ + QDebugStateSaver saver(dbg); + const char *id = qt_cbor_tag_id(QCborTag(int(tag))); + if (id) + return dbg.nospace() << "QCborKnownTags::" << id; + + return dbg.nospace() << "QCborKnownTags(" << int(tag) << ')'; +} +#endif + /*! \class QCborError \inmodule QtCore diff --git a/src/corelib/serialization/qcborvalue.cpp b/src/corelib/serialization/qcborvalue.cpp index 970ae23352..db5dc938df 100644 --- a/src/corelib/serialization/qcborvalue.cpp +++ b/src/corelib/serialization/qcborvalue.cpp @@ -2564,6 +2564,63 @@ inline QCborMap::QCborMap(QCborContainerPrivate &dd) Q_DECL_NOTHROW { } +#if !defined(QT_NO_DEBUG_STREAM) +static QDebug debugContents(QDebug &dbg, const QCborValue &v) +{ + switch (v.type()) { + case QCborValue::Integer: + return dbg << v.toInteger(); + case QCborValue::ByteArray: + return dbg << "QByteArray(" << v.toByteArray() << ')'; + case QCborValue::String: + return dbg << v.toString(); + case QCborValue::Array: + return dbg << v.toArray(); + case QCborValue::Map: + return dbg << v.toMap(); + case QCborValue::Tag: + dbg << v.tag() << ", "; + return debugContents(dbg, v.taggedValue()); + case QCborValue::SimpleType: + break; + case QCborValue::True: + return dbg << true; + case QCborValue::False: + return dbg << false; + case QCborValue::Null: + return dbg << "nullptr"; + case QCborValue::Undefined: + return dbg; + case QCborValue::Double: { + qint64 i = qint64(v.toDouble()); + if (i == v.toDouble()) + return dbg << i << ".0"; + else + return dbg << v.toDouble(); + } + case QCborValue::DateTime: + return dbg << v.toDateTime(); + case QCborValue::Url: + return dbg << v.toUrl(); + case QCborValue::RegularExpression: + return dbg << v.toRegularExpression(); + case QCborValue::Uuid: + return dbg << v.toUuid(); + case QCborValue::Invalid: + return dbg << ""; + } + if (v.isSimpleType()) + return dbg << v.toSimpleType(); + return dbg << "'; +} +QDebug operator<<(QDebug dbg, const QCborValue &v) +{ + QDebugStateSaver saver(dbg); + dbg.nospace() << "QCborValue("; + return debugContents(dbg, v) << ')'; +} +#endif + QT_END_NAMESPACE #include "qcborarray.cpp" diff --git a/src/corelib/serialization/qcborvalue.h b/src/corelib/serialization/qcborvalue.h index 64db66bc28..d2adc0a88b 100644 --- a/src/corelib/serialization/qcborvalue.h +++ b/src/corelib/serialization/qcborvalue.h @@ -430,6 +430,10 @@ private: qsizetype i; }; +#if !defined(QT_NO_DEBUG_STREAM) +Q_CORE_EXPORT QDebug operator<<(QDebug, const QCborValue &v); +#endif + QT_END_NAMESPACE #endif // QCBORVALUE_H