Cleanup usage of QVariant::Type.
[profile/ivi/qtbase.git] / src / dbus / qdbusargument.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtDBus module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
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
61 QT_BEGIN_NAMESPACE
62
63 QDBusArgumentPrivate::~QDBusArgumentPrivate()
64 {
65     if (message)
66         q_dbus_message_unref(message);
67 }
68
69 QByteArray 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                  QMetaType::typeName(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                  QMetaType::typeName(id),
101                  signature.constData(),
102                  QMetaType::typeName(QDBusMetaType::signatureToType(signature)));
103         return "";
104     }
105     return signature;
106 }
107
108 bool 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.load() != 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
136 bool 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
152 bool QDBusArgumentPrivate::checkReadAndDetach(QDBusArgumentPrivate *&d)
153 {
154     if (!checkRead(d))
155         return false;           //  don't bother
156
157     if (d->ref.load() == 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 */
291 QDBusArgument::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 */
313 QDBusArgument::QDBusArgument(const QDBusArgument &other)
314     : d(other.d)
315 {
316     if (d)
317         d->ref.ref();
318 }
319
320 /*!
321     \internal
322 */
323 QDBusArgument::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 */
335 QDBusArgument &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 */
345 QDBusArgument::~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 */
354 QDBusArgument &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 */
365 QDBusArgument &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 */
376 QDBusArgument &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 */
387 QDBusArgument &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 */
398 QDBusArgument &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 */
409 QDBusArgument &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 */
420 QDBusArgument &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 */
431 QDBusArgument &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 */
443 QDBusArgument &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 */
455 QDBusArgument &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 */
468 QDBusArgument &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 */
481 QDBusArgument &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 */
495 QDBusArgument &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 */
509 QDBusArgument &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 */
527 QDBusArgument &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 */
545 QDBusArgument &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 */
560 void 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 */
571 QString 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 */
590 QDBusArgument::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 */
603 const 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 */
615 const 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 */
627 const 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 */
639 const 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 */
651 const 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 */
663 const 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 */
675 const 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 */
687 const 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 */
699 const 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 */
711 const 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 */
724 const 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 */
737 const 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 */
751 const 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 */
771 const 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 */
789 const 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 */
807 const 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 */
829 void 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 */
841 void 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 */
864 void 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 */
876 void 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 */
900 void 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 */
912 void 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 */
927 void 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 */
939 void 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 */
955 void 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 */
967 void 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 */
991 void 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 */
1003 void 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 */
1024 void 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 */
1036 void 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 */
1050 void 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 */
1062 void 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 */
1073 bool 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 */
1101 QVariant QDBusArgument::asVariant() const
1102 {
1103     if (QDBusArgumentPrivate::checkRead(d))
1104         return d->demarshaller()->toVariantInternal();
1105
1106     return QVariant();
1107 }
1108
1109 QT_END_NAMESPACE
1110
1111 // for optimization purposes, we include the marshallers here
1112 #include "qdbusmarshaller.cpp"
1113 #include "qdbusdemarshaller.cpp"
1114
1115 QT_BEGIN_NAMESPACE
1116
1117 // QDBusArgument operators
1118
1119 const 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
1129 const 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.setDate(y, m, d);
1138     else
1139         date = QDate();
1140     return a;
1141 }
1142
1143 QDBusArgument &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
1154 const 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
1168 QDBusArgument &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
1179 const 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
1193 QDBusArgument &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
1201 const 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
1212 QDBusArgument &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
1221 const 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
1232 QDBusArgument &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
1241 const 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
1250 QDBusArgument &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
1259 const 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
1271 QDBusArgument &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
1280 const 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
1289 QDBusArgument &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
1298 const 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
1310 QDBusArgument &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
1319 const 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
1330 QDBusArgument &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
1339 const 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
1350 QDBusArgument &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
1360 QT_END_NAMESPACE
1361
1362 #endif // QT_NO_DBUS