1/****************************************************************************
2**
3** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4** Contact: http://www.qt-project.org/legal
5**
6** This file is part of the QtDBus module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Digia. For licensing terms and
14** conditions see http://qt.digia.com/licensing. For further information
15** use the contact form at http://qt.digia.com/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 2.1 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 2.1 requirements
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24**
25** In addition, as a special exception, Digia gives you certain additional
26** rights. These rights are described in the Digia Qt LGPL Exception
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28**
29** GNU General Public License Usage
30** Alternatively, this file may be used under the terms of the GNU
31** General Public License version 3.0 as published by the Free Software
32** Foundation and appearing in the file LICENSE.GPL included in the
33** packaging of this file. Please review the following information to
34** ensure the GNU General Public License version 3.0 requirements will be
35** met: http://www.gnu.org/copyleft/gpl.html.
36**
37**
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#ifndef QDBUSARGUMENT_H
43#define QDBUSARGUMENT_H
44
45#include <QtCore/qbytearray.h>
46#include <QtCore/qhash.h>
47#include <QtCore/qglobal.h>
48#include <QtCore/qlist.h>
49#include <QtCore/qmap.h>
50#include <QtCore/qstring.h>
51#include <QtCore/qstringlist.h>
52#include <QtCore/qvariant.h>
53#include <QtDBus/qdbusextratypes.h>
54#include <QtDBus/qdbusmacros.h>
55
56#ifndef QT_NO_DBUS
57
58QT_BEGIN_HEADER
59
60QT_BEGIN_NAMESPACE
61
62QT_MODULE(DBus)
63
64class QDBusUnixFileDescriptor;
65
66class QDBusArgumentPrivate;
67class QDBusDemarshaller;
68class QDBusMarshaller;
69class Q_DBUS_EXPORT QDBusArgument
70{
71public:
72 enum ElementType {
73 BasicType,
74 VariantType,
75 ArrayType,
76 StructureType,
77 MapType,
78 MapEntryType,
79 UnknownType = -1
80 };
81
82 QDBusArgument();
83 QDBusArgument(const QDBusArgument &other);
84 QDBusArgument &operator=(const QDBusArgument &other);
85 ~QDBusArgument();
86
87 // used for marshalling (Qt -> D-BUS)
88 QDBusArgument &operator<<(uchar arg);
89 QDBusArgument &operator<<(bool arg);
90 QDBusArgument &operator<<(short arg);
91 QDBusArgument &operator<<(ushort arg);
92 QDBusArgument &operator<<(int arg);
93 QDBusArgument &operator<<(uint arg);
94 QDBusArgument &operator<<(qlonglong arg);
95 QDBusArgument &operator<<(qulonglong arg);
96 QDBusArgument &operator<<(double arg);
97 QDBusArgument &operator<<(const QString &arg);
98 QDBusArgument &operator<<(const QDBusVariant &arg);
99 QDBusArgument &operator<<(const QDBusObjectPath &arg);
100 QDBusArgument &operator<<(const QDBusSignature &arg);
101 QDBusArgument &operator<<(const QDBusUnixFileDescriptor &arg);
102 QDBusArgument &operator<<(const QStringList &arg);
103 QDBusArgument &operator<<(const QByteArray &arg);
104
105 void beginStructure();
106 void endStructure();
107 void beginArray(int elementMetaTypeId);
108 void endArray();
109 void beginMap(int keyMetaTypeId, int valueMetaTypeId);
110 void endMap();
111 void beginMapEntry();
112 void endMapEntry();
113
114 void appendVariant(const QVariant &v);
115
116 // used for de-marshalling (D-BUS -> Qt)
117 QString currentSignature() const;
118 ElementType currentType() const;
119
120 const QDBusArgument &operator>>(uchar &arg) const;
121 const QDBusArgument &operator>>(bool &arg) const;
122 const QDBusArgument &operator>>(short &arg) const;
123 const QDBusArgument &operator>>(ushort &arg) const;
124 const QDBusArgument &operator>>(int &arg) const;
125 const QDBusArgument &operator>>(uint &arg) const;
126 const QDBusArgument &operator>>(qlonglong &arg) const;
127 const QDBusArgument &operator>>(qulonglong &arg) const;
128 const QDBusArgument &operator>>(double &arg) const;
129 const QDBusArgument &operator>>(QString &arg) const;
130 const QDBusArgument &operator>>(QDBusVariant &arg) const;
131 const QDBusArgument &operator>>(QDBusObjectPath &arg) const;
132 const QDBusArgument &operator>>(QDBusSignature &arg) const;
133 const QDBusArgument &operator>>(QDBusUnixFileDescriptor &arg) const;
134 const QDBusArgument &operator>>(QStringList &arg) const;
135 const QDBusArgument &operator>>(QByteArray &arg) const;
136
137 void beginStructure() const;
138 void endStructure() const;
139 void beginArray() const;
140 void endArray() const;
141 void beginMap() const;
142 void endMap() const;
143 void beginMapEntry() const;
144 void endMapEntry() const;
145 bool atEnd() const;
146
147 QVariant asVariant() const;
148
149protected:
150 QDBusArgument(QDBusArgumentPrivate *d);
151 friend class QDBusArgumentPrivate;
152 mutable QDBusArgumentPrivate *d;
153};
154
155template<typename T> inline T qdbus_cast(const QDBusArgument &arg
156#ifndef Q_QDOC
157, T * = 0
158#endif
159 )
160{
161 T item;
162 arg >> item;
163 return item;
164}
165
166template<typename T> inline T qdbus_cast(const QVariant &v
167#ifndef Q_QDOC
168, T * = 0
169#endif
170 )
171{
172 int id = v.userType();
173 if (id == qMetaTypeId<QDBusArgument>())
174 return qdbus_cast<T>(qvariant_cast<QDBusArgument>(v));
175 else
176 return qvariant_cast<T>(v);
177}
178
179// specialize for QVariant, allowing it to be used in place of QDBusVariant
180template<> inline QVariant qdbus_cast<QVariant>(const QDBusArgument &arg, QVariant *)
181{
182 QDBusVariant item;
183 arg >> item;
184 return item.variant();
185}
186template<> inline QVariant qdbus_cast<QVariant>(const QVariant &v, QVariant *)
187{
188 return qdbus_cast<QDBusVariant>(v).variant();
189}
190
191Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QVariant &v);
192
193// QVariant types
194#ifndef QDBUS_NO_SPECIALTYPES
195
196Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QDate &date);
197Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QDate &date);
198
199Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QTime &time);
200Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QTime &time);
201
202Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QDateTime &dt);
203Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QDateTime &dt);
204
205Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QRect &rect);
206Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QRect &rect);
207
208Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QRectF &rect);
209Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QRectF &rect);
210
211Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QSize &size);
212Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QSize &size);
213
214Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QSizeF &size);
215Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QSizeF &size);
216
217Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QPoint &pt);
218Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QPoint &pt);
219
220Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QPointF &pt);
221Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QPointF &pt);
222
223Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QLine &line);
224Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QLine &line);
225
226Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QLineF &line);
227Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QLineF &line);
228#endif
229
230template<template <typename> class Container, typename T>
231inline QDBusArgument &operator<<(QDBusArgument &arg, const Container<T> &list)
232{
233 int id = qMetaTypeId<T>();
234 arg.beginArray(id);
235 typename Container<T>::const_iterator it = list.begin();
236 typename Container<T>::const_iterator end = list.end();
237 for ( ; it != end; ++it)
238 arg << *it;
239 arg.endArray();
240 return arg;
241}
242
243template<template <typename> class Container, typename T>
244inline const QDBusArgument &operator>>(const QDBusArgument &arg, Container<T> &list)
245{
246 arg.beginArray();
247 list.clear();
248 while (!arg.atEnd()) {
249 T item;
250 arg >> item;
251 list.push_back(item);
252 }
253
254 arg.endArray();
255 return arg;
256}
257
258// QList specializations
259template<typename T>
260inline QDBusArgument &operator<<(QDBusArgument &arg, const QList<T> &list)
261{
262 int id = qMetaTypeId<T>();
263 arg.beginArray(id);
264 typename QList<T>::ConstIterator it = list.constBegin();
265 typename QList<T>::ConstIterator end = list.constEnd();
266 for ( ; it != end; ++it)
267 arg << *it;
268 arg.endArray();
269 return arg;
270}
271
272template<typename T>
273inline const QDBusArgument &operator>>(const QDBusArgument &arg, QList<T> &list)
274{
275 arg.beginArray();
276 list.clear();
277 while (!arg.atEnd()) {
278 T item;
279 arg >> item;
280 list.push_back(item);
281 }
282 arg.endArray();
283
284 return arg;
285}
286
287inline QDBusArgument &operator<<(QDBusArgument &arg, const QVariantList &list)
288{
289 int id = qMetaTypeId<QDBusVariant>();
290 arg.beginArray(id);
291 QVariantList::ConstIterator it = list.constBegin();
292 QVariantList::ConstIterator end = list.constEnd();
293 for ( ; it != end; ++it)
294 arg << QDBusVariant(*it);
295 arg.endArray();
296 return arg;
297}
298
299// QMap specializations
300template<typename Key, typename T>
301inline QDBusArgument &operator<<(QDBusArgument &arg, const QMap<Key, T> &map)
302{
303 int kid = qMetaTypeId<Key>();
304 int vid = qMetaTypeId<T>();
305 arg.beginMap(kid, vid);
306 typename QMap<Key, T>::ConstIterator it = map.constBegin();
307 typename QMap<Key, T>::ConstIterator end = map.constEnd();
308 for ( ; it != end; ++it) {
309 arg.beginMapEntry();
310 arg << it.key() << it.value();
311 arg.endMapEntry();
312 }
313 arg.endMap();
314 return arg;
315}
316
317template<typename Key, typename T>
318inline const QDBusArgument &operator>>(const QDBusArgument &arg, QMap<Key, T> &map)
319{
320 arg.beginMap();
321 map.clear();
322 while (!arg.atEnd()) {
323 Key key;
324 T value;
325 arg.beginMapEntry();
326 arg >> key >> value;
327 map.insertMulti(key, value);
328 arg.endMapEntry();
329 }
330 arg.endMap();
331 return arg;
332}
333
334inline QDBusArgument &operator<<(QDBusArgument &arg, const QVariantMap &map)
335{
336 arg.beginMap(QVariant::String, qMetaTypeId<QDBusVariant>());
337 QVariantMap::ConstIterator it = map.constBegin();
338 QVariantMap::ConstIterator end = map.constEnd();
339 for ( ; it != end; ++it) {
340 arg.beginMapEntry();
341 arg << it.key() << QDBusVariant(it.value());
342 arg.endMapEntry();
343 }
344 arg.endMap();
345 return arg;
346}
347
348// QHash specializations
349template<typename Key, typename T>
350inline QDBusArgument &operator<<(QDBusArgument &arg, const QHash<Key, T> &map)
351{
352 int kid = qMetaTypeId<Key>();
353 int vid = qMetaTypeId<T>();
354 arg.beginMap(kid, vid);
355 typename QHash<Key, T>::ConstIterator it = map.constBegin();
356 typename QHash<Key, T>::ConstIterator end = map.constEnd();
357 for ( ; it != end; ++it) {
358 arg.beginMapEntry();
359 arg << it.key() << it.value();
360 arg.endMapEntry();
361 }
362 arg.endMap();
363 return arg;
364}
365
366template<typename Key, typename T>
367inline const QDBusArgument &operator>>(const QDBusArgument &arg, QHash<Key, T> &map)
368{
369 arg.beginMap();
370 map.clear();
371 while (!arg.atEnd()) {
372 Key key;
373 T value;
374 arg.beginMapEntry();
375 arg >> key >> value;
376 map.insertMulti(key, value);
377 arg.endMapEntry();
378 }
379 arg.endMap();
380 return arg;
381}
382
383inline QDBusArgument &operator<<(QDBusArgument &arg, const QVariantHash &map)
384{
385 arg.beginMap(QVariant::String, qMetaTypeId<QDBusVariant>());
386 QVariantHash::ConstIterator it = map.constBegin();
387 QVariantHash::ConstIterator end = map.constEnd();
388 for ( ; it != end; ++it) {
389 arg.beginMapEntry();
390 arg << it.key() << QDBusVariant(it.value());
391 arg.endMapEntry();
392 }
393 arg.endMap();
394 return arg;
395}
396
397
398QT_END_NAMESPACE
399
400Q_DECLARE_METATYPE(QDBusArgument)
401
402QT_END_HEADER
403
404#endif // QT_NO_DBUS
405#endif
406