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 | |
58 | QT_BEGIN_HEADER |
59 | |
60 | QT_BEGIN_NAMESPACE |
61 | |
62 | QT_MODULE(DBus) |
63 | |
64 | class QDBusUnixFileDescriptor; |
65 | |
66 | class QDBusArgumentPrivate; |
67 | class QDBusDemarshaller; |
68 | class QDBusMarshaller; |
69 | class Q_DBUS_EXPORT QDBusArgument |
70 | { |
71 | public: |
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 | |
149 | protected: |
150 | QDBusArgument(QDBusArgumentPrivate *d); |
151 | friend class QDBusArgumentPrivate; |
152 | mutable QDBusArgumentPrivate *d; |
153 | }; |
154 | |
155 | template<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 | |
166 | template<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 |
180 | template<> inline QVariant qdbus_cast<QVariant>(const QDBusArgument &arg, QVariant *) |
181 | { |
182 | QDBusVariant item; |
183 | arg >> item; |
184 | return item.variant(); |
185 | } |
186 | template<> inline QVariant qdbus_cast<QVariant>(const QVariant &v, QVariant *) |
187 | { |
188 | return qdbus_cast<QDBusVariant>(v).variant(); |
189 | } |
190 | |
191 | Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QVariant &v); |
192 | |
193 | // QVariant types |
194 | #ifndef QDBUS_NO_SPECIALTYPES |
195 | |
196 | Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QDate &date); |
197 | Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QDate &date); |
198 | |
199 | Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QTime &time); |
200 | Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QTime &time); |
201 | |
202 | Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QDateTime &dt); |
203 | Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QDateTime &dt); |
204 | |
205 | Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QRect &rect); |
206 | Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QRect &rect); |
207 | |
208 | Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QRectF &rect); |
209 | Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QRectF &rect); |
210 | |
211 | Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QSize &size); |
212 | Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QSize &size); |
213 | |
214 | Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QSizeF &size); |
215 | Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QSizeF &size); |
216 | |
217 | Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QPoint &pt); |
218 | Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QPoint &pt); |
219 | |
220 | Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QPointF &pt); |
221 | Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QPointF &pt); |
222 | |
223 | Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QLine &line); |
224 | Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QLine &line); |
225 | |
226 | Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QLineF &line); |
227 | Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QLineF &line); |
228 | #endif |
229 | |
230 | template<template <typename> class Container, typename T> |
231 | inline 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 | |
243 | template<template <typename> class Container, typename T> |
244 | inline 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 |
259 | template<typename T> |
260 | inline 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 | |
272 | template<typename T> |
273 | inline 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 | |
287 | inline 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 |
300 | template<typename Key, typename T> |
301 | inline 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 | |
317 | template<typename Key, typename T> |
318 | inline 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 | |
334 | inline 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 |
349 | template<typename Key, typename T> |
350 | inline 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 | |
366 | template<typename Key, typename T> |
367 | inline 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 | |
383 | inline 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 | |
398 | QT_END_NAMESPACE |
399 | |
400 | Q_DECLARE_METATYPE(QDBusArgument) |
401 | |
402 | QT_END_HEADER |
403 | |
404 | #endif // QT_NO_DBUS |
405 | #endif |
406 | |