diff options
| author | Marc Mutz <marc.mutz@qt.io> | 2024-07-18 22:57:10 +0200 |
|---|---|---|
| committer | Marc Mutz <marc.mutz@qt.io> | 2024-07-23 02:59:53 +0200 |
| commit | b57fac818b7fe028dc61f1196cfda397233edffe (patch) | |
| tree | 1a932bf3b7ead2e883ec6325de3af7d332a7d359 | |
| parent | b892b39a7a6c50eb5bbf03f0c9f01bdd07756f13 (diff) | |
Long live QDebug::toBytes()!
I've seen over and over again how test authors are plagued by the
impedance mismatch between their 8-bit actual data and the result of
QString::toString() being in UTF-16. They invariably ditch their 8-bit
inputs and go to QString, but the mere fact that they start out with
8-bit input and then run into problems means we have a gaping API hole
here. QTest::toString() also suffers from this.
So add the option to a) construct a QDebug object over a QByteArray
(already supported by underlying QTextStream) and b) to stream into
QByteArray like toString() streams into QString.
Finally, make QTest::toString() use the new toBytes() function instead
of the old toString() one.
This saves 1% (91122→90248) in tst_tostring exeutable size on
optimized Linux AMD64 GCC 9 builds.
[ChangeLog][QtCore][QDebug] Added ctor from QByteArray* and a static
toBytes() function.
Change-Id: I2b021513d6427a1a961f39e751eaf4faaf527ba8
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
| -rw-r--r-- | src/corelib/io/qdebug.cpp | 22 | ||||
| -rw-r--r-- | src/corelib/io/qdebug.h | 11 | ||||
| -rw-r--r-- | src/testlib/qtesttostring.h | 2 |
3 files changed, 34 insertions, 1 deletions
diff --git a/src/corelib/io/qdebug.cpp b/src/corelib/io/qdebug.cpp index 600b8b13b80..1c6aecaaabb 100644 --- a/src/corelib/io/qdebug.cpp +++ b/src/corelib/io/qdebug.cpp @@ -1000,6 +1000,8 @@ QDebug &QDebug::resetFormat() \since 6.0 \include qdebug-toString.qdocinc + + \sa toBytes() */ /*! \internal */ @@ -1014,6 +1016,26 @@ QString QDebug::toStringImpl(StreamTypeErased s, const void *obj) } /*! + \fn template <class T> QByteArray QDebug::toBytes(const T &object) + \since 6.9 + + This is equivalent to \c{QDebug::toString(object).toUtf8()}, but more efficient. + + \sa toString() +*/ + +/*! \internal */ +QByteArray QDebug::toBytesImpl(StreamTypeErased s, const void *obj) +{ + QByteArray result; + { + QDebug d(&result); + s(d.nospace(), obj); + } + return result; +} + +/*! \fn template <class T> QDebug operator<<(QDebug debug, const QList<T> &list) \relates QDebug diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h index fe3c66180c3..ab1f53afe77 100644 --- a/src/corelib/io/qdebug.h +++ b/src/corelib/io/qdebug.h @@ -51,6 +51,9 @@ class QT6_ONLY(Q_CORE_EXPORT) QDebug : public QIODeviceBase explicit Stream(QString *string) : ts(string, WriteOnly) {} + explicit Stream(QByteArray *ba) + : ts(ba, WriteOnly) + {} explicit Stream(QtMsgType t) : ts(&buffer, WriteOnly), type(t), @@ -78,6 +81,7 @@ class QT6_ONLY(Q_CORE_EXPORT) QDebug : public QIODeviceBase public: explicit QDebug(QIODevice *device) : stream(new Stream(device)) {} explicit QDebug(QString *string) : stream(new Stream(string)) {} + explicit QDebug(QByteArray *bytes) : stream(new Stream(bytes)) {} explicit QDebug(QtMsgType t) : stream(new Stream(t)) {} QDebug(const QDebug &o) : stream(o.stream) { ++stream->ref; } QDebug(QDebug &&other) noexcept : stream{std::exchange(other.stream, nullptr)} {} @@ -232,12 +236,19 @@ private: } using StreamTypeErased = void(*)(QDebug&, const void*); QT7_ONLY(Q_CORE_EXPORT) static QString toStringImpl(StreamTypeErased s, const void *obj); + QT7_ONLY(Q_CORE_EXPORT) static QByteArray toBytesImpl(StreamTypeErased s, const void *obj); public: template <typename T> static QString toString(const T &object) { return toStringImpl(&streamTypeErased<T>, &object); } + + template <typename T> + static QByteArray toBytes(const T &object) + { + return toBytesImpl(&streamTypeErased<T>, &object); + } }; Q_DECLARE_SHARED(QDebug) diff --git a/src/testlib/qtesttostring.h b/src/testlib/qtesttostring.h index 903392697d6..bcd70501f67 100644 --- a/src/testlib/qtesttostring.h +++ b/src/testlib/qtesttostring.h @@ -55,7 +55,7 @@ inline typename std::enable_if<!QtPrivate::IsQEnumHelper<T>::Value && !std::is_e char *result = nullptr; #ifndef QT_NO_DEBUG_STREAM if constexpr (QTypeTraits::has_ostream_operator_v<QDebug, T>) { - result = qstrdup(QDebug::toString(t).toUtf8().constData()); + result = qstrdup(QDebug::toBytes(t).constData()); } else { static_assert(!QMetaTypeId2<T>::IsBuiltIn, "Built-in type must implement debug streaming operator " |
