source: trunk/src/dbus/qdbusargument.cpp@ 769

Last change on this file since 769 was 769, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.3 sources from branches/vendor/nokia/qt.

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