CBOR: Add QDebug operators for the Qt CBOR value-like types

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 <marten.nordheim@qt.io>
This commit is contained in:
Thiago Macieira 2018-01-25 14:11:33 -08:00
parent 9be00330af
commit 71e41d7230
9 changed files with 217 additions and 10 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -42,6 +42,7 @@
#include <QtCore/qobjectdefs.h>
#include <QtCore/qmetatype.h>
#include <QtCore/qdebug.h>
#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)

View File

@ -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

View File

@ -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

View File

@ -42,6 +42,7 @@
#include <private/qnumeric_p.h>
#include <private/qutfcodec_p.h>
#include <qbuffer.h>
#include <qdebug.h>
#include <qstack.h>
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 <QtCborCommon>
@ -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<QCborKnownTags>::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 <QtCborCommon>
@ -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

View File

@ -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 << "<invalid>";
}
if (v.isSimpleType())
return dbg << v.toSimpleType();
return dbg << "<unknown type " << hex << int(v.type()) << '>';
}
QDebug operator<<(QDebug dbg, const QCborValue &v)
{
QDebugStateSaver saver(dbg);
dbg.nospace() << "QCborValue(";
return debugContents(dbg, v) << ')';
}
#endif
QT_END_NAMESPACE
#include "qcborarray.cpp"

View File

@ -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