summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qdebug_p.h
blob: d6d2e660720be4554f0738866815923f4f359f40 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Qt-Security score:critical reason:data-parsing

#ifndef QDEBUG_P_H
#define QDEBUG_P_H

//
//  W A R N I N G
//  -------------
//
// This file is not part of the Qt API.  It exists for the convenience
// of other Qt classes.  This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//

#include <QtCore/private/qglobal_p.h>
#include "QtCore/qdebug.h"
#include "QtCore/qmetaobject.h"
#include "QtCore/qflags.h"
#include "QtCore/qbytearray.h"

QT_BEGIN_NAMESPACE

class QRect;

namespace QtDebugUtils {

Q_CORE_EXPORT QByteArray toPrintable(const char *data, qint64 len, qsizetype maxSize);

// inline helpers for formatting basic classes.

template <class Point>
static inline void formatQPoint(QDebug &debug, const Point &point)
{
    debug << point.x() << ',' << point.y();
}

template <class Size>
static inline void formatQSize(QDebug &debug, const Size &size)
{
    debug << size.width() << ", " << size.height();
}

template <class Rect>
static inline void formatQRect(QDebug &debug, const Rect &rect)
{
    debug << rect.x() << ',' << rect.y() << ' ';
    if constexpr (std::is_same_v<Rect, QRect>) {
        // QRect may overflow. Calculate width and height in higher precision.
        const qint64 w = qint64(rect.right()) - rect.left() + 1;
        const qint64 h = qint64(rect.bottom()) - rect.top() + 1;
        debug << w << 'x' << h;

        constexpr qint64 M = (std::numeric_limits<int>::max)();
        if (w > M || h > M)
            debug << " (oversized)";
    } else {
        debug << rect.width() << 'x' << rect.height();
    }
}

template <class Margins>
static inline void formatQMargins(QDebug &debug, const Margins &margins)
{
    debug << margins.left() << ", " << margins.top() << ", " << margins.right()
        << ", " << margins.bottom();
}

#ifndef QT_NO_QOBJECT
template <class QEnum>
static inline void formatQEnum(QDebug &debug, QEnum value)
{
    const QMetaObject *metaObject = qt_getEnumMetaObject(value);
    const QMetaEnum me = metaObject->enumerator(metaObject->indexOfEnumerator(qt_getEnumName(value)));
    if (const char *key = me.valueToKey(int(value)))
        debug << key;
    else
        debug << int(value);
}

template <class QEnum>
static inline void formatNonNullQEnum(QDebug &debug, const char *prefix, QEnum value)
{
    if (value) {
         debug << prefix;
         formatQEnum(debug, value);
    }
}

template <class Enum>
static inline void formatQFlags(QDebug &debug, const QFlags<Enum> &value)
{
    const QMetaEnum me = QMetaEnum::fromType<QFlags<Enum>>();
    const QDebugStateSaver saver(debug);
    debug.noquote();
    debug << me.valueToKeys(value.toInt());
}

template <class Enum>
static inline void formatNonNullQFlags(QDebug &debug, const char *prefix, const QFlags<Enum> &value)
{
    if (value) {
        debug << prefix;
        formatQFlags(debug, value);
    }
}

#endif // !QT_NO_QOBJECT

} // namespace QtDebugUtils

QT_END_NAMESPACE

#endif // QDEBUG_P_H