summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qdebug.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/io/qdebug.cpp')
-rw-r--r--src/corelib/io/qdebug.cpp170
1 files changed, 170 insertions, 0 deletions
diff --git a/src/corelib/io/qdebug.cpp b/src/corelib/io/qdebug.cpp
index 5c77ccdcbf..9ed29c38af 100644
--- a/src/corelib/io/qdebug.cpp
+++ b/src/corelib/io/qdebug.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Intel Corporation.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -40,9 +41,13 @@
#include "qdebug.h"
#include <private/qtextstream_p.h>
+#include <private/qtools_p.h>
QT_BEGIN_NAMESPACE
+using QtMiscUtils::toHexUpper;
+using QtMiscUtils::fromHex;
+
// This file is needed to force compilation of QDebug into the kernel library.
/*!
@@ -148,6 +153,171 @@ QDebug::~QDebug()
}
/*!
+ \internal
+*/
+void QDebug::putUcs4(uint ucs4)
+{
+ maybeQuote('\'');
+ if (ucs4 < 0x20) {
+ stream->ts << hex << "\\x" << ucs4 << reset;
+ } else if (ucs4 < 0x80) {
+ stream->ts << char(ucs4);
+ } else {
+ stream->ts << hex << qSetPadChar(QLatin1Char('0'));
+ if (ucs4 < 0x10000)
+ stream->ts << qSetFieldWidth(4) << "\\u";
+ else
+ stream->ts << qSetFieldWidth(8) << "\\U";
+ stream->ts << ucs4 << reset;
+ }
+ maybeQuote('\'');
+}
+
+template <typename Char>
+static inline void putEscapedString(QTextStreamPrivate *d, const Char *begin, int length, bool isUnicode = true)
+{
+ QChar quote(QLatin1Char('"'));
+ d->write(&quote, 1);
+
+ bool lastWasHexEscape = false;
+ const Char *end = begin + length;
+ for (const Char *p = begin; p != end; ++p) {
+ // check if we need to insert "" to break an hex escape sequence
+ if (Q_UNLIKELY(lastWasHexEscape)) {
+ if (fromHex(*p) != -1) {
+ // yes, insert it
+ QChar quotes[] = { QLatin1Char('"'), QLatin1Char('"') };
+ d->write(quotes, 2);
+ }
+ lastWasHexEscape = false;
+ }
+
+ if (sizeof(Char) == sizeof(QChar)) {
+ int runLength = 0;
+ while (p + runLength != end &&
+ p[runLength] < 0x7f && p[runLength] >= 0x20 && p[runLength] != '\\' && p[runLength] != '"')
+ ++runLength;
+ if (runLength) {
+ d->write(reinterpret_cast<const QChar *>(p), runLength);
+ p += runLength - 1;
+ continue;
+ }
+ } else if (*p < 0x7f && *p >= 0x20 && *p != '\\' && *p != '"') {
+ QChar c = QLatin1Char(*p);
+ d->write(&c, 1);
+ continue;
+ }
+
+ // print as an escape sequence
+ int buflen = 2;
+ ushort buf[sizeof "\\U12345678" - 1];
+ buf[0] = '\\';
+
+ switch (*p) {
+ case '"':
+ case '\\':
+ buf[1] = *p;
+ break;
+ case '\b':
+ buf[1] = 'b';
+ break;
+ case '\f':
+ buf[1] = 'f';
+ break;
+ case '\n':
+ buf[1] = 'n';
+ break;
+ case '\r':
+ buf[1] = 'r';
+ break;
+ case '\t':
+ buf[1] = 't';
+ break;
+ default:
+ if (!isUnicode) {
+ // print as hex escape
+ buf[1] = 'x';
+ buf[2] = toHexUpper(uchar(*p) >> 4);
+ buf[3] = toHexUpper(uchar(*p));
+ buflen = 4;
+ lastWasHexEscape = true;
+ break;
+ }
+ if (QChar::isHighSurrogate(*p)) {
+ if ((p + 1) != end && QChar::isLowSurrogate(p[1])) {
+ // properly-paired surrogates
+ uint ucs4 = QChar::surrogateToUcs4(*p, p[1]);
+ ++p;
+ buf[1] = 'U';
+ buf[2] = '0'; // toHexUpper(ucs4 >> 32);
+ buf[3] = '0'; // toHexUpper(ucs4 >> 28);
+ buf[4] = toHexUpper(ucs4 >> 20);
+ buf[5] = toHexUpper(ucs4 >> 16);
+ buf[6] = toHexUpper(ucs4 >> 12);
+ buf[7] = toHexUpper(ucs4 >> 8);
+ buf[8] = toHexUpper(ucs4 >> 4);
+ buf[9] = toHexUpper(ucs4);
+ buflen = 10;
+ break;
+ }
+ // improperly-paired surrogates, fall through
+ }
+ buf[1] = 'u';
+ if (sizeof(Char) == 1) {
+ buf[2] = buf[3] = '0';
+ } else {
+ buf[2] = toHexUpper(*p >> 12);
+ buf[3] = toHexUpper(*p >> 8);
+ }
+ buf[4] = toHexUpper(*p >> 4);
+ buf[5] = toHexUpper(*p);
+ buflen = 6;
+ }
+ d->write(reinterpret_cast<QChar *>(buf), buflen);
+ }
+
+ d->write(&quote, 1);
+}
+
+/*!
+ \internal
+ Duplicated from QtTest::toPrettyUnicode().
+*/
+void QDebug::putString(const QChar *begin, size_t length)
+{
+ if (stream->testFlag(Stream::NoQuotes)) {
+ // no quotes, write the string directly too (no pretty-printing)
+ // this respects the QTextStream state, though
+ stream->ts.d_ptr->putString(begin, length);
+ } else {
+ // we'll reset the QTextStream formatting mechanisms, so save the state
+ QDebugStateSaver saver(*this);
+ stream->ts.d_ptr->params.reset();
+ putEscapedString(stream->ts.d_ptr.data(), reinterpret_cast<const ushort *>(begin), length);
+ }
+}
+
+/*!
+ \internal
+ Duplicated from QtTest::toPrettyCString().
+*/
+void QDebug::putByteArray(const char *begin, size_t length, Latin1Content content)
+{
+ if (stream->testFlag(Stream::NoQuotes)) {
+ // no quotes, write the string directly too (no pretty-printing)
+ // this respects the QTextStream state, though
+ QString string = content == ContainsLatin1 ? QString::fromLatin1(begin, length) : QString::fromUtf8(begin, length);
+ stream->ts.d_ptr->putString(string);
+ } else {
+ // we'll reset the QTextStream formatting mechanisms, so save the state
+ QDebugStateSaver saver(*this);
+ stream->ts.d_ptr->params.reset();
+ putEscapedString(stream->ts.d_ptr.data(), reinterpret_cast<const uchar *>(begin),
+ length, content == ContainsLatin1);
+ }
+}
+
+/*!
\fn QDebug::swap(QDebug &other)
\since 5.0