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#include "qdbusargument.h"
43
44#include <qatomic.h>
45#include <qbytearray.h>
46#include <qlist.h>
47#include <qmap.h>
48#include <qstring.h>
49#include <qstringlist.h>
50#include <qvariant.h>
51#include <qdatetime.h>
52#include <qrect.h>
53#include <qline.h>
54
55#include "qdbusargument_p.h"
56#include "qdbusmetatype_p.h"
57#include "qdbusutil_p.h"
58
59#ifndef QT_NO_DBUS
60
61QT_BEGIN_NAMESPACE
62
63QDBusArgumentPrivate::~QDBusArgumentPrivate()
64{
65 if (message)
66 q_dbus_message_unref(message);
67}
68
69QByteArray QDBusArgumentPrivate::createSignature(int id)
70{
71 if (!qdbus_loadLibDBus())
72 return "";
73
74 QByteArray signature;
75 QDBusMarshaller *marshaller = new QDBusMarshaller(0);
76 marshaller->ba = &signature;
77
78 // run it
79 void *null = 0;
80 QVariant v(id, null);
81 QDBusArgument arg(marshaller);
82 QDBusMetaType::marshall(arg, v.userType(), v.constData());
83 arg.d = 0;
84
85 // delete it
86 bool ok = marshaller->ok;
87 delete marshaller;
88
89 if (signature.isEmpty() || !ok || !QDBusUtil::isValidSingleSignature(QString::fromLatin1(signature))) {
90 qWarning("QDBusMarshaller: type `%s' produces invalid D-BUS signature `%s' "
91 "(Did you forget to call beginStructure() ?)",
92 QVariant::typeToName( QVariant::Type(id) ),
93 signature.isEmpty() ? "<empty>" : signature.constData());
94 return "";
95 } else if ((signature.at(0) != DBUS_TYPE_ARRAY && signature.at(0) != DBUS_STRUCT_BEGIN_CHAR) ||
96 (signature.at(0) == DBUS_TYPE_ARRAY && (signature.at(1) == DBUS_TYPE_BYTE ||
97 signature.at(1) == DBUS_TYPE_STRING))) {
98 qWarning("QDBusMarshaller: type `%s' attempts to redefine basic D-BUS type '%s' (%s) "
99 "(Did you forget to call beginStructure() ?)",
100 QVariant::typeToName( QVariant::Type(id) ),
101 signature.constData(),
102 QVariant::typeToName( QVariant::Type(QDBusMetaType::signatureToType(signature))) );
103 return "";
104 }
105 return signature;
106}
107
108bool QDBusArgumentPrivate::checkWrite(QDBusArgumentPrivate *&d)
109{
110 if (!d)
111 return false;
112 if (d->direction == Marshalling) {
113 if (!d->marshaller()->ok)
114 return false;
115
116 if (d->message && d->ref != 1) {
117 QDBusMarshaller *dd = new QDBusMarshaller(d->capabilities);
118 dd->message = q_dbus_message_copy(d->message);
119 q_dbus_message_iter_init_append(dd->message, &dd->iterator);
120
121 if (!d->ref.deref())
122 delete d;
123 d = dd;
124 }
125 return true;
126 }
127
128#ifdef QT_DEBUG
129 qFatal("QDBusArgument: write from a read-only object");
130#else
131 qWarning("QDBusArgument: write from a read-only object");
132#endif
133 return false;
134}
135
136bool QDBusArgumentPrivate::checkRead(QDBusArgumentPrivate *d)
137{
138 if (!d)
139 return false;
140 if (d->direction == Demarshalling)
141 return true;
142
143#ifdef QT_DEBUG
144 qFatal("QDBusArgument: read from a write-only object");
145#else
146 qWarning("QDBusArgument: read from a write-only object");
147#endif
148
149 return false;
150}
151
152bool QDBusArgumentPrivate::checkReadAndDetach(QDBusArgumentPrivate *&d)
153{
154 if (!checkRead(d))
155 return false; // don't bother
156
157 if (d->ref == 1)
158 return true; // no need to detach
159
160 QDBusDemarshaller *dd = new QDBusDemarshaller(d->capabilities);
161 dd->message = q_dbus_message_ref(d->message);
162 dd->iterator = static_cast<QDBusDemarshaller*>(d)->iterator;
163
164 if (!d->ref.deref())
165 delete d;
166 d = dd;
167 return true;
168}
169
170/*!
171 \class QDBusArgument
172 \inmodule QtDBus
173 \since 4.2
174
175 \brief The QDBusArgument class is used to marshall and demarshall D-Bus arguments.
176
177 The class is used to send arguments over D-Bus to remote
178 applications and to receive them back. D-Bus offers an extensible
179 type system, based on a few primitive types and associations of
180 them. See the \l {qdbustypesystem.html}{QtDBus type system} page
181 for more information on the type system.
182
183 QDBusArgument is the central class in the QtDBus type system,
184 providing functions to marshall and demarshall the primitive
185 types. The compound types are then created by association of one
186 or more of the primitive types in arrays, dictionaries or
187 structures.
188
189 The following example illustrates how a structure containing an
190 integer and a string can be constructed using the \l
191 {qdbustypesystem.html}{QtDBus type system}:
192
193 \snippet doc/src/snippets/code/src_qdbus_qdbusargument.cpp 0
194
195 The type has to be registered with qDBusRegisterMetaType() before
196 it can be used with QDBusArgument. Therefore, somewhere in your
197 program, you should add the following code:
198
199 \snippet doc/src/snippets/code/src_qdbus_qdbusargument.cpp 1
200
201 Once registered, a type can be used in outgoing method calls
202 (placed with QDBusAbstractInterface::call()), signal emissions
203 from registered objects or in incoming calls from remote
204 applications.
205
206 It is important to note that the \c{operator<<} and \c{operator>>}
207 streaming functions must always produce the same number of entries
208 in case of structures, both in reading and in writing (marshalling
209 and demarshalling), otherwise calls and signals may start to
210 silently fail.
211
212 The following example illustrates this wrong usage
213 in context of a class that may contain invalid data:
214
215 \badcode
216 // Wrongly marshall the MyTime data into a D-Bus argument
217 QDBusArgument &operator<<(QDBusArgument &argument, const MyTime &mytime)
218 {
219 argument.beginStructure();
220 if (mytime.isValid)
221 argument << true << mytime.hour
222 << mytime.minute << mytime.second;
223 else
224 argument << false;
225 argument.endStructure();
226 return argument;
227 }
228 \endcode
229
230 In this example, both the \c{operator<<} and the \c{operator>>}
231 functions may produce a different number of reads/writes. This can
232 confuse the QtDBus type system and should be avoided.
233
234 \sa QDBusAbstractInterface, {qdbustypesystem.html}{The QtDBus type
235 system}, {usingadaptors.html}{Using Adaptors}, qdbus_cast()
236*/
237
238/*!
239 \enum QDBusArgument::ElementType
240 \since 4.5
241
242 This enum describes the type of element held by the argument.
243
244 \value BasicType A basic element, which is understood by
245 QVariant. The following types are considered basic: bool,
246 byte, short, ushort, int, uint, qint64, quint64, double,
247 QString, QByteArray, QDBusObjectPath, QDBusSignature
248
249 \value VariantType The variant element (QDBusVariant)
250
251 \value ArrayType An array element, usually represented by QList<T>
252 or QVector<T>. Note: QByteArray and associative maps are not
253 considered arrays, even if the D-Bus protocol transports them as such.
254
255 \value StructureType A custom type represented by a structure,
256 like QDateTime, QPoint, etc.
257
258 \value MapType An associative container, like QMap<Key, Value> or
259 QHash<Key, Value>
260
261 \value MapEntryType One entry in an associative container: both
262 the key and the value form one map-entry type.
263
264 \value UnknownType The type is unknown or we have reached the end
265 of the list.
266
267 \sa currentType()
268*/
269
270/*!
271 \fn qdbus_cast(const QDBusArgument &argument)
272 \relates QDBusArgument
273 \since 4.2
274
275 Attempts to demarshall the contents of \a argument into the type
276 \c{T}. For example:
277
278 \snippet doc/src/snippets/code/src_qdbus_qdbusargument.cpp 2
279
280 Note that it is equivalent to the following:
281
282 \snippet doc/src/snippets/code/src_qdbus_qdbusargument.cpp 3
283*/
284
285/*!
286 Constructs an empty QDBusArgument argument.
287
288 An empty QDBusArgument object does not allow either reading or
289 writing to be performed.
290*/
291QDBusArgument::QDBusArgument()
292{
293 if (!qdbus_loadLibDBus()) {
294 d = 0;
295 return;
296 }
297
298 QDBusMarshaller *dd = new QDBusMarshaller(0);
299 d = dd;
300
301 // create a new message with any type, we won't sent it anyways
302 dd->message = q_dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL);
303 q_dbus_message_iter_init_append(dd->message, &dd->iterator);
304}
305
306/*!
307 Constructs a copy of the \a other QDBusArgument object.
308
309 Both objects will therefore contain the same state from this point
310 forward. QDBusArguments are explicitly shared and, therefore, any
311 modification to either copy will affect the other one too.
312*/
313QDBusArgument::QDBusArgument(const QDBusArgument &other)
314 : d(other.d)
315{
316 if (d)
317 d->ref.ref();
318}
319
320/*!
321 \internal
322*/
323QDBusArgument::QDBusArgument(QDBusArgumentPrivate *dd)
324 : d(dd)
325{
326}
327
328/*!
329 Copies the \a other QDBusArgument object into this one.
330
331 Both objects will therefore contain the same state from this point
332 forward. QDBusArguments are explicitly shared and, therefore, any
333 modification to either copy will affect the other one too.
334*/
335QDBusArgument &QDBusArgument::operator=(const QDBusArgument &other)
336{
337 qAtomicAssign(d, other.d);
338 return *this;
339}
340
341/*!
342 Disposes of the resources associated with this QDBusArgument
343 object.
344*/
345QDBusArgument::~QDBusArgument()
346{
347 if (d && !d->ref.deref())
348 delete d;
349}
350
351/*!
352 Appends the primitive value \a arg of type \c{BYTE} to the D-Bus stream.
353*/
354QDBusArgument &QDBusArgument::operator<<(uchar arg)
355{
356 if (QDBusArgumentPrivate::checkWrite(d))
357 d->marshaller()->append(arg);
358 return *this;
359}
360
361/*!
362 \overload
363 Appends the primitive value \a arg of type \c{BOOLEAN} to the D-Bus stream.
364*/
365QDBusArgument &QDBusArgument::operator<<(bool arg)
366{
367 if (QDBusArgumentPrivate::checkWrite(d))
368 d->marshaller()->append(arg);
369 return *this;
370}
371
372/*!
373 \overload
374 Appends the primitive value \a arg of type \c{INT16} to the D-Bus stream.
375*/
376QDBusArgument &QDBusArgument::operator<<(short arg)
377{
378 if (QDBusArgumentPrivate::checkWrite(d))
379 d->marshaller()->append(arg);
380 return *this;
381}
382
383/*!
384 \overload
385 Appends the primitive value \a arg of type \c{UINT16} to the D-Bus stream.
386*/
387QDBusArgument &QDBusArgument::operator<<(ushort arg)
388{
389 if (QDBusArgumentPrivate::checkWrite(d))
390 d->marshaller()->append(arg);
391 return *this;
392}
393
394/*!
395 \overload
396 Appends the primitive value \a arg of type \c{INT32} to the D-Bus stream.
397*/
398QDBusArgument &QDBusArgument::operator<<(int arg)
399{
400 if (QDBusArgumentPrivate::checkWrite(d))
401 d->marshaller()->append(arg);
402 return *this;
403}
404
405/*!
406 \overload
407 Appends the primitive value \a arg of type \c{UINT32} to the D-Bus stream.
408*/
409QDBusArgument &QDBusArgument::operator<<(uint arg)
410{
411 if (QDBusArgumentPrivate::checkWrite(d))
412 d->marshaller()->append(arg);
413 return *this;
414}
415
416/*!
417 \overload
418 Appends the primitive value \a arg of type \c{INT64} to the D-Bus stream.
419*/
420QDBusArgument &QDBusArgument::operator<<(qlonglong arg)
421{
422 if (QDBusArgumentPrivate::checkWrite(d))
423 d->marshaller()->append(arg);
424 return *this;
425}
426
427/*!
428 \overload
429 Appends the primitive value \a arg of type \c{UINT64} to the D-Bus stream.
430*/
431QDBusArgument &QDBusArgument::operator<<(qulonglong arg)
432{
433 if (QDBusArgumentPrivate::checkWrite(d))
434 d->marshaller()->append(arg);
435 return *this;
436}
437
438/*!
439 \overload
440 Appends the primitive value \a arg of type \c{DOUBLE} (double-precision
441 floating-point) to the D-Bus stream.
442*/
443QDBusArgument &QDBusArgument::operator<<(double arg)
444{
445 if (QDBusArgumentPrivate::checkWrite(d))
446 d->marshaller()->append(arg);
447 return *this;
448}
449
450/*!
451 \overload
452 Appends the primitive value \a arg of type \c{STRING} (Unicode character
453 string) to the D-Bus stream.
454*/
455QDBusArgument &QDBusArgument::operator<<(const QString &arg)
456{
457 if (QDBusArgumentPrivate::checkWrite(d))
458 d->marshaller()->append(arg);
459 return *this;
460}
461
462/*!
463 \overload
464 \internal
465 Appends the primitive value \a arg of type \c{OBJECT_PATH} (path to a D-Bus
466 object) to the D-Bus stream.
467*/
468QDBusArgument &QDBusArgument::operator<<(const QDBusObjectPath &arg)
469{
470 if (QDBusArgumentPrivate::checkWrite(d))
471 d->marshaller()->append(arg);
472 return *this;
473}
474
475/*!
476 \overload
477 \internal
478 Appends the primitive value \a arg of type \c{SIGNATURE} (D-Bus type
479 signature) to the D-Bus stream.
480*/
481QDBusArgument &QDBusArgument::operator<<(const QDBusSignature &arg)
482{
483 if (QDBusArgumentPrivate::checkWrite(d))
484 d->marshaller()->append(arg);
485 return *this;
486}
487
488/*!
489 \overload
490 \since 4.8
491 \internal
492 Appends the primitive value \a arg of type \c{UNIX_FILE_DESCRIPTOR} (Unix
493 File Descriptor) to the D-Bus stream.
494*/
495QDBusArgument &QDBusArgument::operator<<(const QDBusUnixFileDescriptor &arg)
496{
497 if (QDBusArgumentPrivate::checkWrite(d))
498 d->marshaller()->append(arg);
499 return *this;
500}
501
502/*!
503 \overload
504 Appends the primitive value \a arg of type \c{VARIANT} to the D-Bus stream.
505
506 A D-Bus variant type can contain any type, including other
507 variants. It is similar to the Qt QVariant type.
508*/
509QDBusArgument &QDBusArgument::operator<<(const QDBusVariant &arg)
510{
511 if (QDBusArgumentPrivate::checkWrite(d))
512 d->marshaller()->append(arg);
513 return *this;
514}
515
516/*!
517 \overload
518 Appends the QStringList given by \a arg as \c{ARRAY of STRING}
519 to the D-Bus stream.
520
521 QStringList and QByteArray are the only two non-primitive types
522 that are supported directly by QDBusArgument because of their
523 widespread usage in Qt applications.
524
525 Other arrays are supported through compound types in QtDBus.
526*/
527QDBusArgument &QDBusArgument::operator<<(const QStringList &arg)
528{
529 if (QDBusArgumentPrivate::checkWrite(d))
530 d->marshaller()->append(arg);
531 return *this;
532}
533
534/*!
535 \overload
536 Appends the QByteArray given by \a arg as \c{ARRAY of BYTE}
537 to the D-Bus stream.
538
539 QStringList and QByteArray are the only two non-primitive types
540 that are supported directly by QDBusArgument because of their
541 widespread usage in Qt applications.
542
543 Other arrays are supported through compound types in QtDBus.
544*/
545QDBusArgument &QDBusArgument::operator<<(const QByteArray &arg)
546{
547 if (QDBusArgumentPrivate::checkWrite(d))
548 d->marshaller()->append(arg);
549 return *this;
550}
551
552/*!
553 \internal
554 \since 4.5
555
556 Appends the variant \a v.
557
558 \sa asVariant()
559*/
560void QDBusArgument::appendVariant(const QVariant &v)
561{
562 if (QDBusArgumentPrivate::checkWrite(d))
563 d->marshaller()->appendVariantInternal(v);
564}
565
566/*!
567 \internal
568 Returns the type signature of the D-Bus type this QDBusArgument
569 object is currently pointing to.
570*/
571QString QDBusArgument::currentSignature() const
572{
573 if (!d)
574 return QString();
575 if (d->direction == QDBusArgumentPrivate::Demarshalling)
576 return d->demarshaller()->currentSignature();
577 else
578 return d->marshaller()->currentSignature();
579}
580
581/*!
582 \since 4.5
583 Returns the classification of the current element type. If an
584 error decoding the type occurs or if we're at the end of the
585 argument, this function returns QDBusArgument::UnknownType.
586
587 This function only makes sense when demarshalling arguments. If it
588 is used while marshalling, it will always return UnknownType.
589*/
590QDBusArgument::ElementType QDBusArgument::currentType() const
591{
592 if (!d)
593 return UnknownType;
594 if (d->direction == QDBusArgumentPrivate::Demarshalling)
595 return d->demarshaller()->currentType();
596 return UnknownType;
597}
598
599/*!
600 Extracts one D-BUS primitive argument of type \c{BYTE} from the
601 D-BUS stream and puts it into \a arg.
602*/
603const QDBusArgument &QDBusArgument::operator>>(uchar &arg) const
604{
605 if (QDBusArgumentPrivate::checkReadAndDetach(d))
606 arg = d->demarshaller()->toByte();
607 return *this;
608}
609
610/*!
611 \overload
612 Extracts one D-Bus primitive argument of type \c{BOOLEAN} from the
613 D-Bus stream.
614*/
615const QDBusArgument &QDBusArgument::operator>>(bool &arg) const
616{
617 if (QDBusArgumentPrivate::checkReadAndDetach(d))
618 arg = d->demarshaller()->toBool();
619 return *this;
620}
621
622/*!
623 \overload
624 Extracts one D-Bus primitive argument of type \c{UINT16} from the
625 D-Bus stream.
626*/
627const QDBusArgument &QDBusArgument::operator>>(ushort &arg) const
628{
629 if (QDBusArgumentPrivate::checkReadAndDetach(d))
630 arg = d->demarshaller()->toUShort();
631 return *this;
632}
633
634/*!
635 \overload
636 Extracts one D-Bus primitive argument of type \c{INT16} from the
637 D-Bus stream.
638*/
639const QDBusArgument &QDBusArgument::operator>>(short &arg) const
640{
641 if (QDBusArgumentPrivate::checkReadAndDetach(d))
642 arg = d->demarshaller()->toShort();
643 return *this;
644}
645
646/*!
647 \overload
648 Extracts one D-Bus primitive argument of type \c{INT32} from the
649 D-Bus stream.
650*/
651const QDBusArgument &QDBusArgument::operator>>(int &arg) const
652{
653 if (QDBusArgumentPrivate::checkReadAndDetach(d))
654 arg = d->demarshaller()->toInt();
655 return *this;
656}
657
658/*!
659 \overload
660 Extracts one D-Bus primitive argument of type \c{UINT32} from the
661 D-Bus stream.
662*/
663const QDBusArgument &QDBusArgument::operator>>(uint &arg) const
664{
665 if (QDBusArgumentPrivate::checkReadAndDetach(d))
666 arg = d->demarshaller()->toUInt();
667 return *this;
668}
669
670/*!
671 \overload
672 Extracts one D-Bus primitive argument of type \c{INT64} from the
673 D-Bus stream.
674*/
675const QDBusArgument &QDBusArgument::operator>>(qlonglong &arg) const
676{
677 if (QDBusArgumentPrivate::checkReadAndDetach(d))
678 arg = d->demarshaller()->toLongLong();
679 return *this;
680}
681
682/*!
683 \overload
684 Extracts one D-Bus primitive argument of type \c{UINT64} from the
685 D-Bus stream.
686*/
687const QDBusArgument &QDBusArgument::operator>>(qulonglong &arg) const
688{
689 if (QDBusArgumentPrivate::checkReadAndDetach(d))
690 arg = d->demarshaller()->toULongLong();
691 return *this;
692}
693
694/*!
695 \overload
696 Extracts one D-Bus primitive argument of type \c{DOUBLE}
697 (double-precision floating pount) from the D-Bus stream.
698*/
699const QDBusArgument &QDBusArgument::operator>>(double &arg) const
700{
701 if (QDBusArgumentPrivate::checkReadAndDetach(d))
702 arg = d->demarshaller()->toDouble();
703 return *this;
704}
705
706/*!
707 \overload
708 Extracts one D-Bus primitive argument of type \c{STRING} (Unicode
709 character string) from the D-Bus stream.
710*/
711const QDBusArgument &QDBusArgument::operator>>(QString &arg) const
712{
713 if (QDBusArgumentPrivate::checkReadAndDetach(d))
714 arg = d->demarshaller()->toString();
715 return *this;
716}
717
718/*!
719 \overload
720 \internal
721 Extracts one D-Bus primitive argument of type \c{OBJECT_PATH}
722 (D-Bus path to an object) from the D-Bus stream.
723*/
724const QDBusArgument &QDBusArgument::operator>>(QDBusObjectPath &arg) const
725{
726 if (QDBusArgumentPrivate::checkReadAndDetach(d))
727 arg = d->demarshaller()->toObjectPath();
728 return *this;
729}
730
731/*!
732 \overload
733 \internal
734 Extracts one D-Bus primitive argument of type \c{SIGNATURE} (D-Bus
735 type signature) from the D-Bus stream.
736*/
737const QDBusArgument &QDBusArgument::operator>>(QDBusSignature &arg) const
738{
739 if (QDBusArgumentPrivate::checkReadAndDetach(d))
740 arg = d->demarshaller()->toSignature();
741 return *this;
742}
743
744/*!
745 \overload
746 \since 4.8
747 \internal
748 Extracts one D-Bus primitive argument of type \c{UNIX_FILE_DESCRIPTOR}
749 (Unix file descriptor) from the D-Bus stream.
750*/
751const QDBusArgument &QDBusArgument::operator>>(QDBusUnixFileDescriptor &arg) const
752{
753 if (QDBusArgumentPrivate::checkReadAndDetach(d))
754 arg = d->demarshaller()->toUnixFileDescriptor();
755 return *this;
756}
757
758/*!
759 \overload
760 Extracts one D-Bus primitive argument of type \c{VARIANT} from the
761 D-Bus stream.
762
763 A D-Bus variant type can contain any type, including other
764 variants. It is similar to the Qt QVariant type.
765
766 In case the variant contains a type not directly supported by
767 QDBusArgument, the value of the returned QDBusVariant will contain
768 another QDBusArgument. It is your responsibility to further
769 demarshall it into another type.
770*/
771const QDBusArgument &QDBusArgument::operator>>(QDBusVariant &arg) const
772{
773 if (QDBusArgumentPrivate::checkReadAndDetach(d))
774 arg = d->demarshaller()->toVariant();
775 return *this;
776}
777
778/*!
779 \overload
780 Extracts an array of strings from the D-Bus stream and return it
781 as a QStringList.
782
783 QStringList and QByteArray are the only two non-primitive types
784 that are supported directly by QDBusArgument because of their
785 widespread usage in Qt applications.
786
787 Other arrays are supported through compound types in QtDBus.
788*/
789const QDBusArgument &QDBusArgument::operator>>(QStringList &arg) const
790{
791 if (QDBusArgumentPrivate::checkReadAndDetach(d))
792 arg = d->demarshaller()->toStringList();
793 return *this;
794}
795
796/*!
797 \overload
798 Extracts an array of bytes from the D-Bus stream and return it
799 as a QByteArray.
800
801 QStringList and QByteArray are the only two non-primitive types
802 that are supported directly by QDBusArgument because of their
803 widespread usage in Qt applications.
804
805 Other arrays are supported through compound types in QtDBus.
806*/
807const QDBusArgument &QDBusArgument::operator>>(QByteArray &arg) const
808{
809 if (QDBusArgumentPrivate::checkReadAndDetach(d))
810 arg = d->demarshaller()->toByteArray();
811 return *this;
812}
813
814/*!
815 Opens a new D-Bus structure suitable for appending new arguments.
816
817 This function is used usually in \c{operator<<} streaming
818 operators, as in the following example:
819
820 \snippet doc/src/snippets/code/src_qdbus_qdbusargument.cpp 4
821
822 Structures can contain other structures, so the following code is
823 also valid:
824
825 \snippet doc/src/snippets/code/src_qdbus_qdbusargument.cpp 5
826
827 \sa endStructure(), beginArray(), beginMap()
828*/
829void QDBusArgument::beginStructure()
830{
831 if (QDBusArgumentPrivate::checkWrite(d))
832 d = d->marshaller()->beginStructure();
833}
834
835/*!
836 Closes a D-Bus structure opened with beginStructure(). This function must be called
837 same number of times that beginStructure() is called.
838
839 \sa beginStructure(), endArray(), endMap()
840*/
841void QDBusArgument::endStructure()
842{
843 if (QDBusArgumentPrivate::checkWrite(d))
844 d = d->marshaller()->endStructure();
845}
846
847/*!
848 Opens a new D-Bus array suitable for appending elements of meta-type \a id.
849
850 This function is used usually in \c{operator<<} streaming
851 operators, as in the following example:
852
853 \snippet doc/src/snippets/code/src_qdbus_qdbusargument.cpp 6
854
855 If the type you want to marshall is a QList, QVector or any of the
856 Qt's \l {Container Classes} that take one template parameter,
857 you need not declare an \c{operator<<} function for it, since
858 QtDBus provides generic templates to do the job of marshalling
859 the data. The same applies for STL's sequence containers, such
860 as \c {std::list}, \c {std::vector}, etc.
861
862 \sa endArray(), beginStructure(), beginMap()
863*/
864void QDBusArgument::beginArray(int id)
865{
866 if (QDBusArgumentPrivate::checkWrite(d))
867 d = d->marshaller()->beginArray(id);
868}
869
870/*!
871 Closes a D-Bus array opened with beginArray(). This function must be called
872 same number of times that beginArray() is called.
873
874 \sa beginArray(), endStructure(), endMap()
875*/
876void QDBusArgument::endArray()
877{
878 if (QDBusArgumentPrivate::checkWrite(d))
879 d = d->marshaller()->endArray();
880}
881
882/*!
883 Opens a new D-Bus map suitable for
884 appending elements. Maps are containers that associate one entry
885 (the key) to another (the value), such as Qt's QMap or QHash. The
886 ids of the map's key and value meta types must be passed in \a kid
887 and \a vid respectively.
888
889 This function is used usually in \c{operator<<} streaming
890 operators, as in the following example:
891
892 \snippet doc/src/snippets/code/src_qdbus_qdbusargument.cpp 7
893
894 If the type you want to marshall is a QMap or QHash, you need not
895 declare an \c{operator<<} function for it, since QtDBus provides
896 generic templates to do the job of marshalling the data.
897
898 \sa endMap(), beginStructure(), beginArray(), beginMapEntry()
899*/
900void QDBusArgument::beginMap(int kid, int vid)
901{
902 if (QDBusArgumentPrivate::checkWrite(d))
903 d = d->marshaller()->beginMap(kid, vid);
904}
905
906/*!
907 Closes a D-Bus map opened with beginMap(). This function must be called
908 same number of times that beginMap() is called.
909
910 \sa beginMap(), endStructure(), endArray()
911*/
912void QDBusArgument::endMap()
913{
914 if (QDBusArgumentPrivate::checkWrite(d))
915 d = d->marshaller()->endMap();
916}
917
918/*!
919 Opens a D-Bus map entry suitable for
920 appending the key and value entries. This function is only valid
921 when a map has been opened with beginMap().
922
923 See beginMap() for an example of usage of this function.
924
925 \sa endMapEntry(), beginMap()
926*/
927void QDBusArgument::beginMapEntry()
928{
929 if (QDBusArgumentPrivate::checkWrite(d))
930 d = d->marshaller()->beginMapEntry();
931}
932
933/*!
934 Closes a D-Bus map entry opened with beginMapEntry(). This function must be called
935 same number of times that beginMapEntry() is called.
936
937 \sa beginMapEntry()
938*/
939void QDBusArgument::endMapEntry()
940{
941 if (QDBusArgumentPrivate::checkWrite(d))
942 d = d->marshaller()->endMapEntry();
943}
944
945/*!
946 Opens a D-Bus structure suitable for extracting elements.
947
948 This function is used usually in \c{operator>>} streaming
949 operators, as in the following example:
950
951 \snippet doc/src/snippets/code/src_qdbus_qdbusargument.cpp 8
952
953 \sa endStructure(), beginArray(), beginMap()
954*/
955void QDBusArgument::beginStructure() const
956{
957 if (QDBusArgumentPrivate::checkReadAndDetach(d))
958 d = d->demarshaller()->beginStructure();
959}
960
961/*!
962 Closes the D-Bus structure and allow extracting of the next element
963 after the structure.
964
965 \sa beginStructure()
966*/
967void QDBusArgument::endStructure() const
968{
969 if (QDBusArgumentPrivate::checkReadAndDetach(d))
970 d = d->demarshaller()->endStructure();
971}
972
973/*!
974 Recurses into the D-Bus array to allow extraction of
975 the array elements.
976
977 This function is used usually in \c{operator>>} streaming
978 operators, as in the following example:
979
980 \snippet doc/src/snippets/code/src_qdbus_qdbusargument.cpp 9
981
982 If the type you want to demarshall is a QList, QVector or any of the
983 Qt's \l {Container Classes} that take one template parameter, you
984 need not declare an \c{operator>>} function for it, since QtDBus
985 provides generic templates to do the job of demarshalling the data.
986 The same applies for STL's sequence containers, such as \c {std::list},
987 \c {std::vector}, etc.
988
989 \sa atEnd(), beginStructure(), beginMap()
990*/
991void QDBusArgument::beginArray() const
992{
993 if (QDBusArgumentPrivate::checkReadAndDetach(d))
994 d = d->demarshaller()->beginArray();
995}
996
997/*!
998 Closes the D-Bus array and allow extracting of the next element
999 after the array.
1000
1001 \sa beginArray()
1002*/
1003void QDBusArgument::endArray() const
1004{
1005 if (QDBusArgumentPrivate::checkReadAndDetach(d))
1006 d = d->demarshaller()->endArray();
1007}
1008
1009/*!
1010 Recurses into the D-Bus map to allow extraction of
1011 the map's elements.
1012
1013 This function is used usually in \c{operator>>} streaming
1014 operators, as in the following example:
1015
1016 \snippet doc/src/snippets/code/src_qdbus_qdbusargument.cpp 10
1017
1018 If the type you want to demarshall is a QMap or QHash, you need not
1019 declare an \c{operator>>} function for it, since QtDBus provides
1020 generic templates to do the job of demarshalling the data.
1021
1022 \sa endMap(), beginStructure(), beginArray(), beginMapEntry()
1023*/
1024void QDBusArgument::beginMap() const
1025{
1026 if (QDBusArgumentPrivate::checkReadAndDetach(d))
1027 d = d->demarshaller()->beginMap();
1028}
1029
1030/*!
1031 Closes the D-Bus map and allow extracting of the next element
1032 after the map.
1033
1034 \sa beginMap()
1035*/
1036void QDBusArgument::endMap() const
1037{
1038 if (QDBusArgumentPrivate::checkReadAndDetach(d))
1039 d = d->demarshaller()->endMap();
1040}
1041
1042/*!
1043 Recurses into the D-Bus map entry to allow extraction
1044 of the key and value pair.
1045
1046 See beginMap() for an example of how this function is usually used.
1047
1048 \sa endMapEntry(), beginMap()
1049*/
1050void QDBusArgument::beginMapEntry() const
1051{
1052 if (QDBusArgumentPrivate::checkReadAndDetach(d))
1053 d = d->demarshaller()->beginMapEntry();
1054}
1055
1056/*!
1057 Closes the D-Bus map entry and allow extracting of the next element
1058 on the map.
1059
1060 \sa beginMapEntry()
1061*/
1062void QDBusArgument::endMapEntry() const
1063{
1064 if (QDBusArgumentPrivate::checkReadAndDetach(d))
1065 d = d->demarshaller()->endMapEntry();
1066}
1067
1068/*!
1069 Returns true if there are no more elements to be extracted from
1070 this QDBusArgument. This function is usually used in QDBusArgument
1071 objects returned from beginMap() and beginArray().
1072*/
1073bool QDBusArgument::atEnd() const
1074{
1075 if (QDBusArgumentPrivate::checkRead(d))
1076 return d->demarshaller()->atEnd();
1077
1078 return true; // at least, stop reading
1079}
1080
1081/*!
1082 \since 4.5
1083
1084 Returns the current argument in the form of a QVariant. Basic
1085 types will be decoded and returned in the QVariant, but for
1086 complex types, this function will return a QDBusArgument object in
1087 the QVariant. It is the caller's responsibility to decode the
1088 argument (for example, by calling asVariant() in it).
1089
1090 For example, if the current argument is an INT32, this function
1091 will return a QVariant with an argument of type QVariant::Int. For
1092 an array of INT32, it will return a QVariant containing a
1093 QDBusArgument.
1094
1095 If an error occurs or if there are no more arguments to decode
1096 (i.e., we are at the end of the argument list), this function will
1097 return an invalid QVariant.
1098
1099 \sa atEnd()
1100*/
1101QVariant QDBusArgument::asVariant() const
1102{
1103 if (QDBusArgumentPrivate::checkRead(d))
1104 return d->demarshaller()->toVariantInternal();
1105
1106 return QVariant();
1107}
1108
1109QT_END_NAMESPACE
1110
1111// for optimization purposes, we include the marshallers here
1112#include "qdbusmarshaller.cpp"
1113#include "qdbusdemarshaller.cpp"
1114
1115QT_BEGIN_NAMESPACE
1116
1117// QDBusArgument operators
1118
1119const QDBusArgument &operator>>(const QDBusArgument &a, QVariant &v)
1120{
1121 QDBusVariant dbv;
1122 a >> dbv;
1123 v = dbv.variant();
1124 return a;
1125}
1126
1127// QVariant types
1128#ifndef QDBUS_NO_SPECIALTYPES
1129const QDBusArgument &operator>>(const QDBusArgument &a, QDate &date)
1130{
1131 int y, m, d;
1132 a.beginStructure();
1133 a >> y >> m >> d;
1134 a.endStructure();
1135
1136 if (y != 0 && m != 0 && d != 0)
1137 date.setYMD(y, m, d);
1138 else
1139 date = QDate();
1140 return a;
1141}
1142
1143QDBusArgument &operator<<(QDBusArgument &a, const QDate &date)
1144{
1145 a.beginStructure();
1146 if (date.isValid())
1147 a << date.year() << date.month() << date.day();
1148 else
1149 a << 0 << 0 << 0;
1150 a.endStructure();
1151 return a;
1152}
1153
1154const QDBusArgument &operator>>(const QDBusArgument &a, QTime &time)
1155{
1156 int h, m, s, ms;
1157 a.beginStructure();
1158 a >> h >> m >> s >> ms;
1159 a.endStructure();
1160
1161 if (h < 0)
1162 time = QTime();
1163 else
1164 time.setHMS(h, m, s, ms);
1165 return a;
1166}
1167
1168QDBusArgument &operator<<(QDBusArgument &a, const QTime &time)
1169{
1170 a.beginStructure();
1171 if (time.isValid())
1172 a << time.hour() << time.minute() << time.second() << time.msec();
1173 else
1174 a << -1 << -1 << -1 << -1;
1175 a.endStructure();
1176 return a;
1177}
1178
1179const QDBusArgument &operator>>(const QDBusArgument &a, QDateTime &dt)
1180{
1181 QDate date;
1182 QTime time;
1183 int timespec;
1184
1185 a.beginStructure();
1186 a >> date >> time >> timespec;
1187 a.endStructure();
1188
1189 dt = QDateTime(date, time, Qt::TimeSpec(timespec));
1190 return a;
1191}
1192
1193QDBusArgument &operator<<(QDBusArgument &a, const QDateTime &dt)
1194{
1195 a.beginStructure();
1196 a << dt.date() << dt.time() << int(dt.timeSpec());
1197 a.endStructure();
1198 return a;
1199}
1200
1201const QDBusArgument &operator>>(const QDBusArgument &a, QRect &rect)
1202{
1203 int x, y, width, height;
1204 a.beginStructure();
1205 a >> x >> y >> width >> height;
1206 a.endStructure();
1207
1208 rect.setRect(x, y, width, height);
1209 return a;
1210}
1211
1212QDBusArgument &operator<<(QDBusArgument &a, const QRect &rect)
1213{
1214 a.beginStructure();
1215 a << rect.x() << rect.y() << rect.width() << rect.height();
1216 a.endStructure();
1217
1218 return a;
1219}
1220
1221const QDBusArgument &operator>>(const QDBusArgument &a, QRectF &rect)
1222{
1223 double x, y, width, height;
1224 a.beginStructure();
1225 a >> x >> y >> width >> height;
1226 a.endStructure();
1227
1228 rect.setRect(qreal(x), qreal(y), qreal(width), qreal(height));
1229 return a;
1230}
1231
1232QDBusArgument &operator<<(QDBusArgument &a, const QRectF &rect)
1233{
1234 a.beginStructure();
1235 a << double(rect.x()) << double(rect.y()) << double(rect.width()) << double(rect.height());
1236 a.endStructure();
1237
1238 return a;
1239}
1240
1241const QDBusArgument &operator>>(const QDBusArgument &a, QSize &size)
1242{
1243 a.beginStructure();
1244 a >> size.rwidth() >> size.rheight();
1245 a.endStructure();
1246
1247 return a;
1248}
1249
1250QDBusArgument &operator<<(QDBusArgument &a, const QSize &size)
1251{
1252 a.beginStructure();
1253 a << size.width() << size.height();
1254 a.endStructure();
1255
1256 return a;
1257}
1258
1259const QDBusArgument &operator>>(const QDBusArgument &a, QSizeF &size)
1260{
1261 double width, height;
1262 a.beginStructure();
1263 a >> width >> height;
1264 a.endStructure();
1265
1266 size.setWidth(qreal(width));
1267 size.setHeight(qreal(height));
1268 return a;
1269}
1270
1271QDBusArgument &operator<<(QDBusArgument &a, const QSizeF &size)
1272{
1273 a.beginStructure();
1274 a << double(size.width()) << double(size.height());
1275 a.endStructure();
1276
1277 return a;
1278}
1279
1280const QDBusArgument &operator>>(const QDBusArgument &a, QPoint &pt)
1281{
1282 a.beginStructure();
1283 a >> pt.rx() >> pt.ry();
1284 a.endStructure();
1285
1286 return a;
1287}
1288
1289QDBusArgument &operator<<(QDBusArgument &a, const QPoint &pt)
1290{
1291 a.beginStructure();
1292 a << pt.x() << pt.y();
1293 a.endStructure();
1294
1295 return a;
1296}
1297
1298const QDBusArgument &operator>>(const QDBusArgument &a, QPointF &pt)
1299{
1300 double x, y;
1301 a.beginStructure();
1302 a >> x >> y;
1303 a.endStructure();
1304
1305 pt.setX(qreal(x));
1306 pt.setY(qreal(y));
1307 return a;
1308}
1309
1310QDBusArgument &operator<<(QDBusArgument &a, const QPointF &pt)
1311{
1312 a.beginStructure();
1313 a << double(pt.x()) << double(pt.y());
1314 a.endStructure();
1315
1316 return a;
1317}
1318
1319const QDBusArgument &operator>>(const QDBusArgument &a, QLine &line)
1320{
1321 QPoint p1, p2;
1322 a.beginStructure();
1323 a >> p1 >> p2;
1324 a.endStructure();
1325
1326 line = QLine(p1, p2);
1327 return a;
1328}
1329
1330QDBusArgument &operator<<(QDBusArgument &a, const QLine &line)
1331{
1332 a.beginStructure();
1333 a << line.p1() << line.p2();
1334 a.endStructure();
1335
1336 return a;
1337}
1338
1339const QDBusArgument &operator>>(const QDBusArgument &a, QLineF &line)
1340{
1341 QPointF p1, p2;
1342 a.beginStructure();
1343 a >> p1 >> p2;
1344 a.endStructure();
1345
1346 line = QLineF(p1, p2);
1347 return a;
1348}
1349
1350QDBusArgument &operator<<(QDBusArgument &a, const QLineF &line)
1351{
1352 a.beginStructure();
1353 a << line.p1() << line.p2();
1354 a.endStructure();
1355
1356 return a;
1357}
1358#endif
1359
1360QT_END_NAMESPACE
1361
1362#endif // QT_NO_DBUS
1363