Coverage Report

Created: 2026-10-28 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qtbase/src/dbus/qdbusargument.h
Line
Count
Source
1
// Copyright (C) 2016 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
// Qt-Security score:significant reason:default
4
5
#ifndef QDBUSARGUMENT_H
6
#define QDBUSARGUMENT_H
7
8
#include <QtDBus/qtdbusglobal.h>
9
#include <QtCore/qbytearray.h>
10
#include <QtCore/qhash.h>
11
#include <QtCore/qglobal.h>
12
#include <QtCore/qlist.h>
13
#include <QtCore/qmap.h>
14
#include <QtCore/qstring.h>
15
#include <QtCore/qstringlist.h>
16
#include <QtCore/qvariant.h>
17
#include <QtDBus/qdbusextratypes.h>
18
19
#include <tuple>
20
21
#ifndef QT_NO_DBUS
22
23
QT_BEGIN_NAMESPACE
24
25
26
class QDBusUnixFileDescriptor;
27
28
class QDBusArgumentPrivate;
29
class QDBusDemarshaller;
30
class QDBusMarshaller;
31
class Q_DBUS_EXPORT QDBusArgument
32
{
33
public:
34
    enum ElementType {
35
        BasicType,
36
        VariantType,
37
        ArrayType,
38
        StructureType,
39
        MapType,
40
        MapEntryType,
41
        UnknownType = -1
42
    };
43
44
    QDBusArgument();
45
    QDBusArgument(const QDBusArgument &other);
46
0
    QDBusArgument(QDBusArgument &&other) noexcept : d(other.d) { other.d = nullptr; }
47
0
    QDBusArgument &operator=(QDBusArgument &&other) noexcept { swap(other); return *this; }
48
    QDBusArgument &operator=(const QDBusArgument &other);
49
    ~QDBusArgument();
50
51
0
    void swap(QDBusArgument &other) noexcept { qt_ptr_swap(d, other.d); }
52
53
    // used for marshalling (Qt -> D-Bus)
54
    QDBusArgument &operator<<(uchar arg);
55
    QDBusArgument &operator<<(bool arg);
56
    QDBusArgument &operator<<(short arg);
57
    QDBusArgument &operator<<(ushort arg);
58
    QDBusArgument &operator<<(int arg);
59
    QDBusArgument &operator<<(uint arg);
60
    QDBusArgument &operator<<(qlonglong arg);
61
    QDBusArgument &operator<<(qulonglong arg);
62
    QDBusArgument &operator<<(double arg);
63
    QDBusArgument &operator<<(const QString &arg);
64
    QDBusArgument &operator<<(const QDBusVariant &arg);
65
    QDBusArgument &operator<<(const QDBusObjectPath &arg);
66
    QDBusArgument &operator<<(const QDBusSignature &arg);
67
    QDBusArgument &operator<<(const QDBusUnixFileDescriptor &arg);
68
    QDBusArgument &operator<<(const QStringList &arg);
69
    QDBusArgument &operator<<(const QByteArray &arg);
70
71
    void beginStructure();
72
    void endStructure();
73
    void beginArray(int elementMetaTypeId)
74
0
    { beginArray(QMetaType(elementMetaTypeId)); }
75
    void beginArray(QMetaType elementMetaType);
76
    void endArray();
77
    void beginMap(int keyMetaTypeId, int valueMetaTypeId)
78
0
    { beginMap(QMetaType(keyMetaTypeId), QMetaType(valueMetaTypeId)); }
79
    void beginMap(QMetaType keyMetaType, QMetaType valueMetaType);
80
    void endMap();
81
    void beginMapEntry();
82
    void endMapEntry();
83
84
    void appendVariant(const QVariant &v);
85
86
    // used for de-marshalling (D-Bus -> Qt)
87
    QString currentSignature() const;
88
    ElementType currentType() const;
89
90
    const QDBusArgument &operator>>(uchar &arg) const;
91
    const QDBusArgument &operator>>(bool &arg) const;
92
    const QDBusArgument &operator>>(short &arg) const;
93
    const QDBusArgument &operator>>(ushort &arg) const;
94
    const QDBusArgument &operator>>(int &arg) const;
95
    const QDBusArgument &operator>>(uint &arg) const;
96
    const QDBusArgument &operator>>(qlonglong &arg) const;
97
    const QDBusArgument &operator>>(qulonglong &arg) const;
98
    const QDBusArgument &operator>>(double &arg) const;
99
    const QDBusArgument &operator>>(QString &arg) const;
100
    const QDBusArgument &operator>>(QDBusVariant &arg) const;
101
    const QDBusArgument &operator>>(QDBusObjectPath &arg) const;
102
    const QDBusArgument &operator>>(QDBusSignature &arg) const;
103
    const QDBusArgument &operator>>(QDBusUnixFileDescriptor &arg) const;
104
    const QDBusArgument &operator>>(QStringList &arg) const;
105
    const QDBusArgument &operator>>(QByteArray &arg) const;
106
107
    void beginStructure() const;
108
    void endStructure() const;
109
    void beginArray() const;
110
    void endArray() const;
111
    void beginMap() const;
112
    void endMap() const;
113
    void beginMapEntry() const;
114
    void endMapEntry() const;
115
    bool atEnd() const;
116
117
    QVariant asVariant() const;
118
119
protected:
120
    QDBusArgument(QDBusArgumentPrivate *d);
121
    friend class QDBusArgumentPrivate;
122
    mutable QDBusArgumentPrivate *d;
123
124
private:
125
    template <typename... T>
126
    friend QDBusArgument &operator<<(QDBusArgument &argument, const std::tuple<T...> &tuple)
127
    {
128
        static_assert(sizeof...(T) != 0, "D-Bus doesn't allow empty structs");
129
        argument.beginStructure();
130
        std::apply([&argument](const auto &...elements) { (argument << ... << elements); }, tuple);
131
        argument.endStructure();
132
        return argument;
133
    }
134
135
    template <typename... T>
136
    friend const QDBusArgument &operator>>(const QDBusArgument &argument, std::tuple<T...> &tuple)
137
    {
138
        static_assert(sizeof...(T) != 0, "D-Bus doesn't allow empty structs");
139
        argument.beginStructure();
140
        std::apply([&argument](auto &...elements) { (argument >> ... >> elements); }, tuple);
141
        argument.endStructure();
142
        return argument;
143
    }
144
};
145
0
Q_DECLARE_SHARED(QDBusArgument)
146
0
147
0
QT_END_NAMESPACE
148
0
QT_DECL_METATYPE_EXTERN(QDBusArgument, Q_DBUS_EXPORT)
Unexecuted instantiation: int qRegisterNormalizedMetaType<QDBusArgument>(QByteArray const&)
Unexecuted instantiation: QMetaTypeId<QDBusArgument>::qt_metatype_id()
149
0
QT_BEGIN_NAMESPACE
150
0
151
0
template<typename T> inline T qdbus_cast(const QDBusArgument &arg)
152
0
{
153
0
    T item;
154
0
    arg >> item;
155
0
    return item;
156
0
}
157
158
template<typename T> inline T qdbus_cast(const QVariant &v)
159
0
{
160
0
    if (v.metaType() == QMetaType::fromType<QDBusArgument>())
161
0
        return qdbus_cast<T>(qvariant_cast<QDBusArgument>(v));
162
0
    else
163
0
        return qvariant_cast<T>(v);
164
0
}
165
166
// specialize for QVariant, allowing it to be used in place of QDBusVariant
167
template<> inline QVariant qdbus_cast<QVariant>(const QDBusArgument &arg)
168
0
{
169
0
    QDBusVariant item;
170
0
    arg >> item;
171
0
    return item.variant();
172
0
}
173
template<> inline QVariant qdbus_cast<QVariant>(const QVariant &v)
174
0
{
175
0
    return qdbus_cast<QDBusVariant>(v).variant();
176
0
}
177
178
Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QVariant &v);
179
180
// QVariant types
181
#ifndef QDBUS_NO_SPECIALTYPES
182
183
Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QDate &date);
184
Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QDate &date);
185
186
Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QTime &time);
187
Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QTime &time);
188
189
Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QDateTime &dt);
190
Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QDateTime &dt);
191
192
Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QRect &rect);
193
Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QRect &rect);
194
195
Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QRectF &rect);
196
Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QRectF &rect);
197
198
Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QSize &size);
199
Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QSize &size);
200
201
Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QSizeF &size);
202
Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QSizeF &size);
203
204
Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QPoint &pt);
205
Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QPoint &pt);
206
207
Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QPointF &pt);
208
Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QPointF &pt);
209
210
Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QLine &line);
211
Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QLine &line);
212
213
Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QLineF &line);
214
Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QLineF &line);
215
#endif
216
217
template<template <typename> class Container, typename T,
218
         typename = typename Container<T>::iterator>
219
inline QDBusArgument &operator<<(QDBusArgument &arg, const Container<T> &list)
220
0
{
221
0
    arg.beginArray(QMetaType::fromType<T>());
222
0
    typename Container<T>::const_iterator it = list.begin();
223
0
    typename Container<T>::const_iterator end = list.end();
224
0
    for ( ; it != end; ++it)
225
0
        arg << *it;
226
0
    arg.endArray();
227
0
    return arg;
228
0
}
Unexecuted instantiation: QDBusArgument& operator<< <QList, bool, QList<bool>::iterator>(QDBusArgument&, QList<bool> const&)
Unexecuted instantiation: QDBusArgument& operator<< <QList, short, QList<short>::iterator>(QDBusArgument&, QList<short> const&)
Unexecuted instantiation: QDBusArgument& operator<< <QList, unsigned short, QList<unsigned short>::iterator>(QDBusArgument&, QList<unsigned short> const&)
Unexecuted instantiation: QDBusArgument& operator<< <QList, int, QList<int>::iterator>(QDBusArgument&, QList<int> const&)
Unexecuted instantiation: QDBusArgument& operator<< <QList, unsigned int, QList<unsigned int>::iterator>(QDBusArgument&, QList<unsigned int> const&)
Unexecuted instantiation: QDBusArgument& operator<< <QList, long long, QList<long long>::iterator>(QDBusArgument&, QList<long long> const&)
Unexecuted instantiation: QDBusArgument& operator<< <QList, unsigned long long, QList<unsigned long long>::iterator>(QDBusArgument&, QList<unsigned long long> const&)
Unexecuted instantiation: QDBusArgument& operator<< <QList, double, QList<double>::iterator>(QDBusArgument&, QList<double> const&)
Unexecuted instantiation: QDBusArgument& operator<< <QList, QDBusVariant, QList<QDBusVariant>::iterator>(QDBusArgument&, QList<QDBusVariant> const&)
Unexecuted instantiation: QDBusArgument& operator<< <QList, QDBusObjectPath, QList<QDBusObjectPath>::iterator>(QDBusArgument&, QList<QDBusObjectPath> const&)
Unexecuted instantiation: QDBusArgument& operator<< <QList, QDBusSignature, QList<QDBusSignature>::iterator>(QDBusArgument&, QList<QDBusSignature> const&)
Unexecuted instantiation: QDBusArgument& operator<< <QList, QDBusUnixFileDescriptor, QList<QDBusUnixFileDescriptor>::iterator>(QDBusArgument&, QList<QDBusUnixFileDescriptor> const&)
229
230
template<template <typename> class Container, typename T,
231
         typename = typename Container<T>::iterator>
232
inline const QDBusArgument &operator>>(const QDBusArgument &arg, Container<T> &list)
233
0
{
234
0
    arg.beginArray();
235
0
    list.clear();
236
0
    while (!arg.atEnd()) {
237
0
        T item;
238
0
        arg >> item;
239
0
        list.push_back(item);
240
0
    }
241
242
0
    arg.endArray();
243
0
    return arg;
244
0
}
Unexecuted instantiation: QDBusArgument const& operator>><QList, QVariant, QList<QVariant>::iterator>(QDBusArgument const&, QList<QVariant>&)
Unexecuted instantiation: QDBusArgument const& operator>><QList, bool, QList<bool>::iterator>(QDBusArgument const&, QList<bool>&)
Unexecuted instantiation: QDBusArgument const& operator>><QList, short, QList<short>::iterator>(QDBusArgument const&, QList<short>&)
Unexecuted instantiation: QDBusArgument const& operator>><QList, unsigned short, QList<unsigned short>::iterator>(QDBusArgument const&, QList<unsigned short>&)
Unexecuted instantiation: QDBusArgument const& operator>><QList, int, QList<int>::iterator>(QDBusArgument const&, QList<int>&)
Unexecuted instantiation: QDBusArgument const& operator>><QList, unsigned int, QList<unsigned int>::iterator>(QDBusArgument const&, QList<unsigned int>&)
Unexecuted instantiation: QDBusArgument const& operator>><QList, long long, QList<long long>::iterator>(QDBusArgument const&, QList<long long>&)
Unexecuted instantiation: QDBusArgument const& operator>><QList, unsigned long long, QList<unsigned long long>::iterator>(QDBusArgument const&, QList<unsigned long long>&)
Unexecuted instantiation: QDBusArgument const& operator>><QList, double, QList<double>::iterator>(QDBusArgument const&, QList<double>&)
Unexecuted instantiation: QDBusArgument const& operator>><QList, QDBusVariant, QList<QDBusVariant>::iterator>(QDBusArgument const&, QList<QDBusVariant>&)
Unexecuted instantiation: QDBusArgument const& operator>><QList, QDBusObjectPath, QList<QDBusObjectPath>::iterator>(QDBusArgument const&, QList<QDBusObjectPath>&)
Unexecuted instantiation: QDBusArgument const& operator>><QList, QDBusSignature, QList<QDBusSignature>::iterator>(QDBusArgument const&, QList<QDBusSignature>&)
Unexecuted instantiation: QDBusArgument const& operator>><QList, QDBusUnixFileDescriptor, QList<QDBusUnixFileDescriptor>::iterator>(QDBusArgument const&, QList<QDBusUnixFileDescriptor>&)
245
246
inline QDBusArgument &operator<<(QDBusArgument &arg, const QVariantList &list)
247
0
{
248
0
    arg.beginArray(QMetaType::fromType<QDBusVariant>());
249
0
    for (const QVariant &value : list)
250
0
        arg << QDBusVariant(value);
251
0
    arg.endArray();
252
0
    return arg;
253
0
}
254
255
// Specializations for associative containers
256
template <template <typename, typename> class Container, typename Key, typename T,
257
         QtPrivate::IfAssociativeIteratorHasKeyAndValue<typename Container<Key, T>::iterator> = true>
258
inline QDBusArgument &operator<<(QDBusArgument &arg, const Container<Key, T> &map)
259
0
{
260
0
    arg.beginMap(QMetaType::fromType<Key>(), QMetaType::fromType<T>());
261
0
    auto it = map.begin();
262
0
    auto end = map.end();
263
0
    for ( ; it != end; ++it) {
264
0
        arg.beginMapEntry();
265
0
        arg << it.key() << it.value();
266
0
        arg.endMapEntry();
267
0
    }
268
0
    arg.endMap();
269
0
    return arg;
270
0
}
271
272
template <template <typename, typename> class Container, typename Key, typename T,
273
         QtPrivate::IfAssociativeIteratorHasFirstAndSecond<typename Container<Key, T>::iterator> = true>
274
inline QDBusArgument &operator<<(QDBusArgument &arg, const Container<Key, T> &map)
275
{
276
    arg.beginMap(QMetaType::fromType<Key>(), QMetaType::fromType<T>());
277
    auto it = map.begin();
278
    auto end = map.end();
279
    for ( ; it != end; ++it) {
280
        arg.beginMapEntry();
281
        arg << it->first << it->second;
282
        arg.endMapEntry();
283
    }
284
    arg.endMap();
285
    return arg;
286
}
287
288
template <template <typename, typename> class Container, typename Key, typename T,
289
         QtPrivate::IfAssociativeIteratorHasKeyAndValue<typename Container<Key, T>::iterator> = true>
290
inline const QDBusArgument &operator>>(const QDBusArgument &arg, Container<Key, T> &map)
291
0
{
292
0
    arg.beginMap();
293
0
    map.clear();
294
0
    while (!arg.atEnd()) {
295
0
        Key key;
296
0
        T value;
297
0
        arg.beginMapEntry();
298
0
        arg >> key >> value;
299
0
        map.insert(key, value);
300
0
        arg.endMapEntry();
301
0
    }
302
0
    arg.endMap();
303
0
    return arg;
304
0
}
Unexecuted instantiation: _ZrsI4QMap7QString8QVariantTnNSt3__19enable_ifIXsr3qxpE13is_detected_vIN9QtPrivate15KeyAndValueTestENT_IT0_T1_E8iteratorEEEbE4typeELb1EERK13QDBusArgumentSG_RSA_
Unexecuted instantiation: _ZrsI5QHash7QString8QVariantTnNSt3__19enable_ifIXsr3qxpE13is_detected_vIN9QtPrivate15KeyAndValueTestENT_IT0_T1_E8iteratorEEEbE4typeELb1EERK13QDBusArgumentSG_RSA_
Unexecuted instantiation: _ZrsI4QMap7QStringS0_IS1_8QVariantETnNSt3__19enable_ifIXsr3qxpE13is_detected_vIN9QtPrivate15KeyAndValueTestENT_IT0_T1_E8iteratorEEEbE4typeELb1EERK13QDBusArgumentSH_RSB_
305
306
inline QDBusArgument &operator<<(QDBusArgument &arg, const QVariantMap &map)
307
0
{
308
0
    arg.beginMap(QMetaType::fromType<QString>(), QMetaType::fromType<QDBusVariant>());
309
0
    for (const auto &[key, value] : map.asKeyValueRange()) {
310
0
        arg.beginMapEntry();
311
0
        arg << key << QDBusVariant(value);
312
0
        arg.endMapEntry();
313
0
    }
314
0
    arg.endMap();
315
0
    return arg;
316
0
}
317
318
inline QDBusArgument &operator<<(QDBusArgument &arg, const QVariantHash &map)
319
0
{
320
0
    arg.beginMap(QMetaType::fromType<QString>(), QMetaType::fromType<QDBusVariant>());
321
0
    for (const auto &[key, value] : map.asKeyValueRange()) {
322
0
        arg.beginMapEntry();
323
0
        arg << key << QDBusVariant(value);
324
0
        arg.endMapEntry();
325
0
    }
326
0
    arg.endMap();
327
0
    return arg;
328
0
}
329
330
template <typename T1, typename T2>
331
inline QDBusArgument &operator<<(QDBusArgument &arg, const std::pair<T1, T2> &pair)
332
{
333
    arg.beginStructure();
334
    arg << pair.first << pair.second;
335
    arg.endStructure();
336
    return arg;
337
}
338
339
template <typename T1, typename T2>
340
inline const QDBusArgument &operator>>(const QDBusArgument &arg, std::pair<T1, T2> &pair)
341
{
342
    arg.beginStructure();
343
    arg >> pair.first >> pair.second;
344
    arg.endStructure();
345
    return arg;
346
}
347
348
QT_END_NAMESPACE
349
350
#endif // QT_NO_DBUS
351
#endif