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

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

trunk: Merged in qt 4.6.2 sources.

File size: 35.5 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
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 [email protected].
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 Returns the type signature of the D-Bus type this QDBusArgument
539 \since 4.5
540
541 Appends the variant \a v.
542
543 \sa asVariant()
544*/
545void QDBusArgument::appendVariant(const QVariant &v)
546{
547 if (QDBusArgumentPrivate::checkWrite(d))
548 d->marshaller()->appendVariantInternal(v);
549}
550
551/*!
552 \internal
553 Returns the type signature of the D-Bus type this QDBusArgument
554 object is currently pointing to.
555*/
556QString QDBusArgument::currentSignature() const
557{
558 if (!d)
559 return QString();
560 if (d->direction == QDBusArgumentPrivate::Demarshalling)
561 return d->demarshaller()->currentSignature();
562 else
563 return d->marshaller()->currentSignature();
564}
565
566/*!
567 \since 4.5
568 Returns the classification of the current element type. If an
569 error decoding the type occurs or if we're at the end of the
570 argument, this function returns QDBusArgument::UnknownType.
571
572 This function only makes sense when demarshalling arguments. If it
573 is used while marshalling, it will always return UnknownType.
574*/
575QDBusArgument::ElementType QDBusArgument::currentType() const
576{
577 if (!d)
578 return UnknownType;
579 if (d->direction == QDBusArgumentPrivate::Demarshalling)
580 return d->demarshaller()->currentType();
581 return UnknownType;
582}
583
584/*!
585 Extracts one D-BUS primitive argument of type \c{BYTE} from the
586 D-BUS stream and puts it into \a arg.
587*/
588const QDBusArgument &QDBusArgument::operator>>(uchar &arg) const
589{
590 if (QDBusArgumentPrivate::checkReadAndDetach(d))
591 arg = d->demarshaller()->toByte();
592 return *this;
593}
594
595/*!
596 \overload
597 Extracts one D-Bus primitive argument of type \c{BOOLEAN} from the
598 D-Bus stream.
599*/
600const QDBusArgument &QDBusArgument::operator>>(bool &arg) const
601{
602 if (QDBusArgumentPrivate::checkReadAndDetach(d))
603 arg = d->demarshaller()->toBool();
604 return *this;
605}
606
607/*!
608 \overload
609 Extracts one D-Bus primitive argument of type \c{UINT16} from the
610 D-Bus stream.
611*/
612const QDBusArgument &QDBusArgument::operator>>(ushort &arg) const
613{
614 if (QDBusArgumentPrivate::checkReadAndDetach(d))
615 arg = d->demarshaller()->toUShort();
616 return *this;
617}
618
619/*!
620 \overload
621 Extracts one D-Bus primitive argument of type \c{INT16} from the
622 D-Bus stream.
623*/
624const QDBusArgument &QDBusArgument::operator>>(short &arg) const
625{
626 if (QDBusArgumentPrivate::checkReadAndDetach(d))
627 arg = d->demarshaller()->toShort();
628 return *this;
629}
630
631/*!
632 \overload
633 Extracts one D-Bus primitive argument of type \c{INT32} from the
634 D-Bus stream.
635*/
636const QDBusArgument &QDBusArgument::operator>>(int &arg) const
637{
638 if (QDBusArgumentPrivate::checkReadAndDetach(d))
639 arg = d->demarshaller()->toInt();
640 return *this;
641}
642
643/*!
644 \overload
645 Extracts one D-Bus primitive argument of type \c{UINT32} from the
646 D-Bus stream.
647*/
648const QDBusArgument &QDBusArgument::operator>>(uint &arg) const
649{
650 if (QDBusArgumentPrivate::checkReadAndDetach(d))
651 arg = d->demarshaller()->toUInt();
652 return *this;
653}
654
655/*!
656 \overload
657 Extracts one D-Bus primitive argument of type \c{INT64} from the
658 D-Bus stream.
659*/
660const QDBusArgument &QDBusArgument::operator>>(qlonglong &arg) const
661{
662 if (QDBusArgumentPrivate::checkReadAndDetach(d))
663 arg = d->demarshaller()->toLongLong();
664 return *this;
665}
666
667/*!
668 \overload
669 Extracts one D-Bus primitive argument of type \c{UINT64} from the
670 D-Bus stream.
671*/
672const QDBusArgument &QDBusArgument::operator>>(qulonglong &arg) const
673{
674 if (QDBusArgumentPrivate::checkReadAndDetach(d))
675 arg = d->demarshaller()->toULongLong();
676 return *this;
677}
678
679/*!
680 \overload
681 Extracts one D-Bus primitive argument of type \c{DOUBLE}
682 (double-precision floating pount) from the D-Bus stream.
683*/
684const QDBusArgument &QDBusArgument::operator>>(double &arg) const
685{
686 if (QDBusArgumentPrivate::checkReadAndDetach(d))
687 arg = d->demarshaller()->toDouble();
688 return *this;
689}
690
691/*!
692 \overload
693 Extracts one D-Bus primitive argument of type \c{STRING} (Unicode
694 character string) from the D-Bus stream.
695*/
696const QDBusArgument &QDBusArgument::operator>>(QString &arg) const
697{
698 if (QDBusArgumentPrivate::checkReadAndDetach(d))
699 arg = d->demarshaller()->toString();
700 return *this;
701}
702
703/*!
704 \overload
705 \internal
706 Extracts one D-Bus primitive argument of type \c{OBJECT_PATH}
707 (D-Bus path to an object) from the D-Bus stream.
708*/
709const QDBusArgument &QDBusArgument::operator>>(QDBusObjectPath &arg) const
710{
711 if (QDBusArgumentPrivate::checkReadAndDetach(d))
712 arg = d->demarshaller()->toObjectPath();
713 return *this;
714}
715
716/*!
717 \overload
718 \internal
719 Extracts one D-Bus primitive argument of type \c{SIGNATURE} (D-Bus
720 type signature) from the D-Bus stream.
721*/
722const QDBusArgument &QDBusArgument::operator>>(QDBusSignature &arg) const
723{
724 if (QDBusArgumentPrivate::checkReadAndDetach(d))
725 arg = d->demarshaller()->toSignature();
726 return *this;
727}
728
729/*!
730 \overload
731 Extracts one D-Bus primitive argument of type \c{VARIANT} from the
732 D-Bus stream.
733
734 A D-Bus variant type can contain any type, including other
735 variants. It is similar to the Qt QVariant type.
736
737 In case the variant contains a type not directly supported by
738 QDBusArgument, the value of the returned QDBusVariant will contain
739 another QDBusArgument. It is your responsibility to further
740 demarshall it into another type.
741*/
742const QDBusArgument &QDBusArgument::operator>>(QDBusVariant &arg) const
743{
744 if (QDBusArgumentPrivate::checkReadAndDetach(d))
745 arg = d->demarshaller()->toVariant();
746 return *this;
747}
748
749/*!
750 \overload
751 Extracts an array of strings from the D-Bus stream and return it
752 as a QStringList.
753
754 QStringList and QByteArray are the only two non-primitive types
755 that are supported directly by QDBusArgument because of their
756 widespread usage in Qt applications.
757
758 Other arrays are supported through compound types in QtDBus.
759*/
760const QDBusArgument &QDBusArgument::operator>>(QStringList &arg) const
761{
762 if (QDBusArgumentPrivate::checkReadAndDetach(d))
763 arg = d->demarshaller()->toStringList();
764 return *this;
765}
766
767/*!
768 \overload
769 Extracts an array of bytes from the D-Bus stream and return it
770 as a QByteArray.
771
772 QStringList and QByteArray are the only two non-primitive types
773 that are supported directly by QDBusArgument because of their
774 widespread usage in Qt applications.
775
776 Other arrays are supported through compound types in QtDBus.
777*/
778const QDBusArgument &QDBusArgument::operator>>(QByteArray &arg) const
779{
780 if (QDBusArgumentPrivate::checkReadAndDetach(d))
781 arg = d->demarshaller()->toByteArray();
782 return *this;
783}
784
785/*!
786 Opens a new D-Bus structure suitable for appending new arguments.
787
788 This function is used usually in \c{operator<<} streaming
789 operators, as in the following example:
790
791 \snippet doc/src/snippets/code/src_qdbus_qdbusargument.cpp 4
792
793 Structures can contain other structures, so the following code is
794 also valid:
795
796 \snippet doc/src/snippets/code/src_qdbus_qdbusargument.cpp 5
797
798 \sa endStructure(), beginArray(), beginMap()
799*/
800void QDBusArgument::beginStructure()
801{
802 if (QDBusArgumentPrivate::checkWrite(d))
803 d = d->marshaller()->beginStructure();
804}
805
806/*!
807 Closes a D-Bus structure opened with beginStructure(). This function must be called
808 same number of times that beginStructure() is called.
809
810 \sa beginStructure(), endArray(), endMap()
811*/
812void QDBusArgument::endStructure()
813{
814 if (QDBusArgumentPrivate::checkWrite(d))
815 d = d->marshaller()->endStructure();
816}
817
818/*!
819 Opens a new D-Bus array suitable for appending elements of meta-type \a id.
820
821 This function is used usually in \c{operator<<} streaming
822 operators, as in the following example:
823
824 \snippet doc/src/snippets/code/src_qdbus_qdbusargument.cpp 6
825
826 If the type you want to marshall is a QList, QVector or any of the
827 Qt's \l {Generic Containers} that take one template parameter,
828 you need not declare an \c{operator<<} function for it, since
829 QtDBus provides generic templates to do the job of marshalling
830 the data. The same applies for STL's sequence containers, such
831 as \c {std::list}, \c {std::vector}, etc.
832
833 \sa endArray(), beginStructure(), beginMap()
834*/
835void QDBusArgument::beginArray(int id)
836{
837 if (QDBusArgumentPrivate::checkWrite(d))
838 d = d->marshaller()->beginArray(id);
839}
840
841/*!
842 Closes a D-Bus array opened with beginArray(). This function must be called
843 same number of times that beginArray() is called.
844
845 \sa beginArray(), endStructure(), endMap()
846*/
847void QDBusArgument::endArray()
848{
849 if (QDBusArgumentPrivate::checkWrite(d))
850 d = d->marshaller()->endArray();
851}
852
853/*!
854 Opens a new D-Bus map suitable for
855 appending elements. Maps are containers that associate one entry
856 (the key) to another (the value), such as Qt's QMap or QHash. The
857 ids of the map's key and value meta types must be passed in \a kid
858 and \a vid respectively.
859
860 This function is used usually in \c{operator<<} streaming
861 operators, as in the following example:
862
863 \snippet doc/src/snippets/code/src_qdbus_qdbusargument.cpp 7
864
865 If the type you want to marshall is a QMap or QHash, you need not
866 declare an \c{operator<<} function for it, since QtDBus provides
867 generic templates to do the job of marshalling the data.
868
869 \sa endMap(), beginStructure(), beginArray(), beginMapEntry()
870*/
871void QDBusArgument::beginMap(int kid, int vid)
872{
873 if (QDBusArgumentPrivate::checkWrite(d))
874 d = d->marshaller()->beginMap(kid, vid);
875}
876
877/*!
878 Closes a D-Bus map opened with beginMap(). This function must be called
879 same number of times that beginMap() is called.
880
881 \sa beginMap(), endStructure(), endArray()
882*/
883void QDBusArgument::endMap()
884{
885 if (QDBusArgumentPrivate::checkWrite(d))
886 d = d->marshaller()->endMap();
887}
888
889/*!
890 Opens a D-Bus map entry suitable for
891 appending the key and value entries. This function is only valid
892 when a map has been opened with beginMap().
893
894 See beginMap() for an example of usage of this function.
895
896 \sa endMapEntry(), beginMap()
897*/
898void QDBusArgument::beginMapEntry()
899{
900 if (QDBusArgumentPrivate::checkWrite(d))
901 d = d->marshaller()->beginMapEntry();
902}
903
904/*!
905 Closes a D-Bus map entry opened with beginMapEntry(). This function must be called
906 same number of times that beginMapEntry() is called.
907
908 \sa beginMapEntry()
909*/
910void QDBusArgument::endMapEntry()
911{
912 if (QDBusArgumentPrivate::checkWrite(d))
913 d = d->marshaller()->endMapEntry();
914}
915
916/*!
917 Opens a D-Bus structure suitable for extracting elements.
918
919 This function is used usually in \c{operator>>} streaming
920 operators, as in the following example:
921
922 \snippet doc/src/snippets/code/src_qdbus_qdbusargument.cpp 8
923
924 \sa endStructure(), beginArray(), beginMap()
925*/
926void QDBusArgument::beginStructure() const
927{
928 if (QDBusArgumentPrivate::checkReadAndDetach(d))
929 d = d->demarshaller()->beginStructure();
930}
931
932/*!
933 Closes the D-Bus structure and allow extracting of the next element
934 after the structure.
935
936 \sa beginStructure()
937*/
938void QDBusArgument::endStructure() const
939{
940 if (QDBusArgumentPrivate::checkReadAndDetach(d))
941 d = d->demarshaller()->endStructure();
942}
943
944/*!
945 Recurses into the D-Bus array to allow extraction of
946 the array 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 9
952
953 If the type you want to demarshall is a QList, QVector or any of the
954 Qt's \l {Generic Containers} that take one template parameter, you
955 need not declare an \c{operator>>} function for it, since QtDBus
956 provides generic templates to do the job of demarshalling the data.
957 The same applies for STL's sequence containers, such as \c {std::list},
958 \c {std::vector}, etc.
959
960 \sa atEnd(), beginStructure(), beginMap()
961*/
962void QDBusArgument::beginArray() const
963{
964 if (QDBusArgumentPrivate::checkReadAndDetach(d))
965 d = d->demarshaller()->beginArray();
966}
967
968/*!
969 Closes the D-Bus array and allow extracting of the next element
970 after the array.
971
972 \sa beginArray()
973*/
974void QDBusArgument::endArray() const
975{
976 if (QDBusArgumentPrivate::checkReadAndDetach(d))
977 d = d->demarshaller()->endArray();
978}
979
980/*!
981 Recurses into the D-Bus map to allow extraction of
982 the map's elements.
983
984 This function is used usually in \c{operator>>} streaming
985 operators, as in the following example:
986
987 \snippet doc/src/snippets/code/src_qdbus_qdbusargument.cpp 10
988
989 If the type you want to demarshall is a QMap or QHash, you need not
990 declare an \c{operator>>} function for it, since QtDBus provides
991 generic templates to do the job of demarshalling the data.
992
993 \sa endMap(), beginStructure(), beginArray(), beginMapEntry()
994*/
995void QDBusArgument::beginMap() const
996{
997 if (QDBusArgumentPrivate::checkReadAndDetach(d))
998 d = d->demarshaller()->beginMap();
999}
1000
1001/*!
1002 Closes the D-Bus map and allow extracting of the next element
1003 after the map.
1004
1005 \sa beginMap()
1006*/
1007void QDBusArgument::endMap() const
1008{
1009 if (QDBusArgumentPrivate::checkReadAndDetach(d))
1010 d = d->demarshaller()->endMap();
1011}
1012
1013/*!
1014 Recurses into the D-Bus map entry to allow extraction
1015 of the key and value pair.
1016
1017 See beginMap() for an example of how this function is usually used.
1018
1019 \sa endMapEntry(), beginMap()
1020*/
1021void QDBusArgument::beginMapEntry() const
1022{
1023 if (QDBusArgumentPrivate::checkReadAndDetach(d))
1024 d = d->demarshaller()->beginMapEntry();
1025}
1026
1027/*!
1028 Closes the D-Bus map entry and allow extracting of the next element
1029 on the map.
1030
1031 \sa beginMapEntry()
1032*/
1033void QDBusArgument::endMapEntry() const
1034{
1035 if (QDBusArgumentPrivate::checkReadAndDetach(d))
1036 d = d->demarshaller()->endMapEntry();
1037}
1038
1039/*!
1040 Returns true if there are no more elements to be extracted from
1041 this QDBusArgument. This function is usually used in QDBusArgument
1042 objects returned from beginMap() and beginArray().
1043*/
1044bool QDBusArgument::atEnd() const
1045{
1046 if (QDBusArgumentPrivate::checkRead(d))
1047 return d->demarshaller()->atEnd();
1048
1049 return true; // at least, stop reading
1050}
1051
1052/*!
1053 \since 4.5
1054
1055 Returns the current argument in the form of a QVariant. Basic
1056 types will be decoded and returned in the QVariant, but for
1057 complex types, this function will return a QDBusArgument object in
1058 the QVariant. It is the caller's responsibility to decode the
1059 argument (for example, by calling asVariant() in it).
1060
1061 For example, if the current argument is an INT32, this function
1062 will return a QVariant with an argument of type QVariant::Int. For
1063 an array of INT32, it will return a QVariant containing a
1064 QDBusArgument.
1065
1066 If an error occurs or if there are no more arguments to decode
1067 (i.e., we are at the end of the argument list), this function will
1068 return an invalid QVariant.
1069
1070 \sa atEnd()
1071*/
1072QVariant QDBusArgument::asVariant() const
1073{
1074 if (QDBusArgumentPrivate::checkRead(d))
1075 return d->demarshaller()->toVariantInternal();
1076
1077 return QVariant();
1078}
1079
1080QT_END_NAMESPACE
1081
1082// for optimization purposes, we include the marshallers here
1083#include "qdbusmarshaller.cpp"
1084#include "qdbusdemarshaller.cpp"
1085
1086QT_BEGIN_NAMESPACE
1087
1088// QDBusArgument operators
1089
1090const QDBusArgument &operator>>(const QDBusArgument &a, QVariant &v)
1091{
1092 QDBusVariant dbv;
1093 a >> dbv;
1094 v = dbv.variant();
1095 return a;
1096}
1097
1098// QVariant types
1099#ifndef QDBUS_NO_SPECIALTYPES
1100const QDBusArgument &operator>>(const QDBusArgument &a, QDate &date)
1101{
1102 int y, m, d;
1103 a.beginStructure();
1104 a >> y >> m >> d;
1105 a.endStructure();
1106
1107 if (y != 0 && m != 0 && d != 0)
1108 date.setYMD(y, m, d);
1109 else
1110 date = QDate();
1111 return a;
1112}
1113
1114QDBusArgument &operator<<(QDBusArgument &a, const QDate &date)
1115{
1116 a.beginStructure();
1117 if (date.isValid())
1118 a << date.year() << date.month() << date.day();
1119 else
1120 a << 0 << 0 << 0;
1121 a.endStructure();
1122 return a;
1123}
1124
1125const QDBusArgument &operator>>(const QDBusArgument &a, QTime &time)
1126{
1127 int h, m, s, ms;
1128 a.beginStructure();
1129 a >> h >> m >> s >> ms;
1130 a.endStructure();
1131
1132 if (h < 0)
1133 time = QTime();
1134 else
1135 time.setHMS(h, m, s, ms);
1136 return a;
1137}
1138
1139QDBusArgument &operator<<(QDBusArgument &a, const QTime &time)
1140{
1141 a.beginStructure();
1142 if (time.isValid())
1143 a << time.hour() << time.minute() << time.second() << time.msec();
1144 else
1145 a << -1 << -1 << -1 << -1;
1146 a.endStructure();
1147 return a;
1148}
1149
1150const QDBusArgument &operator>>(const QDBusArgument &a, QDateTime &dt)
1151{
1152 QDate date;
1153 QTime time;
1154 int timespec;
1155
1156 a.beginStructure();
1157 a >> date >> time >> timespec;
1158 a.endStructure();
1159
1160 dt = QDateTime(date, time, Qt::TimeSpec(timespec));
1161 return a;
1162}
1163
1164QDBusArgument &operator<<(QDBusArgument &a, const QDateTime &dt)
1165{
1166 a.beginStructure();
1167 a << dt.date() << dt.time() << int(dt.timeSpec());
1168 a.endStructure();
1169 return a;
1170}
1171
1172const QDBusArgument &operator>>(const QDBusArgument &a, QRect &rect)
1173{
1174 int x, y, width, height;
1175 a.beginStructure();
1176 a >> x >> y >> width >> height;
1177 a.endStructure();
1178
1179 rect.setRect(x, y, width, height);
1180 return a;
1181}
1182
1183QDBusArgument &operator<<(QDBusArgument &a, const QRect &rect)
1184{
1185 a.beginStructure();
1186 a << rect.x() << rect.y() << rect.width() << rect.height();
1187 a.endStructure();
1188
1189 return a;
1190}
1191
1192const QDBusArgument &operator>>(const QDBusArgument &a, QRectF &rect)
1193{
1194 double x, y, width, height;
1195 a.beginStructure();
1196 a >> x >> y >> width >> height;
1197 a.endStructure();
1198
1199 rect.setRect(qreal(x), qreal(y), qreal(width), qreal(height));
1200 return a;
1201}
1202
1203QDBusArgument &operator<<(QDBusArgument &a, const QRectF &rect)
1204{
1205 a.beginStructure();
1206 a << double(rect.x()) << double(rect.y()) << double(rect.width()) << double(rect.height());
1207 a.endStructure();
1208
1209 return a;
1210}
1211
1212const QDBusArgument &operator>>(const QDBusArgument &a, QSize &size)
1213{
1214 a.beginStructure();
1215 a >> size.rwidth() >> size.rheight();
1216 a.endStructure();
1217
1218 return a;
1219}
1220
1221QDBusArgument &operator<<(QDBusArgument &a, const QSize &size)
1222{
1223 a.beginStructure();
1224 a << size.width() << size.height();
1225 a.endStructure();
1226
1227 return a;
1228}
1229
1230const QDBusArgument &operator>>(const QDBusArgument &a, QSizeF &size)
1231{
1232 double width, height;
1233 a.beginStructure();
1234 a >> width >> height;
1235 a.endStructure();
1236
1237 size.setWidth(qreal(width));
1238 size.setHeight(qreal(height));
1239 return a;
1240}
1241
1242QDBusArgument &operator<<(QDBusArgument &a, const QSizeF &size)
1243{
1244 a.beginStructure();
1245 a << double(size.width()) << double(size.height());
1246 a.endStructure();
1247
1248 return a;
1249}
1250
1251const QDBusArgument &operator>>(const QDBusArgument &a, QPoint &pt)
1252{
1253 a.beginStructure();
1254 a >> pt.rx() >> pt.ry();
1255 a.endStructure();
1256
1257 return a;
1258}
1259
1260QDBusArgument &operator<<(QDBusArgument &a, const QPoint &pt)
1261{
1262 a.beginStructure();
1263 a << pt.x() << pt.y();
1264 a.endStructure();
1265
1266 return a;
1267}
1268
1269const QDBusArgument &operator>>(const QDBusArgument &a, QPointF &pt)
1270{
1271 double x, y;
1272 a.beginStructure();
1273 a >> x >> y;
1274 a.endStructure();
1275
1276 pt.setX(qreal(x));
1277 pt.setY(qreal(y));
1278 return a;
1279}
1280
1281QDBusArgument &operator<<(QDBusArgument &a, const QPointF &pt)
1282{
1283 a.beginStructure();
1284 a << double(pt.x()) << double(pt.y());
1285 a.endStructure();
1286
1287 return a;
1288}
1289
1290const QDBusArgument &operator>>(const QDBusArgument &a, QLine &line)
1291{
1292 QPoint p1, p2;
1293 a.beginStructure();
1294 a >> p1 >> p2;
1295 a.endStructure();
1296
1297 line = QLine(p1, p2);
1298 return a;
1299}
1300
1301QDBusArgument &operator<<(QDBusArgument &a, const QLine &line)
1302{
1303 a.beginStructure();
1304 a << line.p1() << line.p2();
1305 a.endStructure();
1306
1307 return a;
1308}
1309
1310const QDBusArgument &operator>>(const QDBusArgument &a, QLineF &line)
1311{
1312 QPointF p1, p2;
1313 a.beginStructure();
1314 a >> p1 >> p2;
1315 a.endStructure();
1316
1317 line = QLineF(p1, p2);
1318 return a;
1319}
1320
1321QDBusArgument &operator<<(QDBusArgument &a, const QLineF &line)
1322{
1323 a.beginStructure();
1324 a << line.p1() << line.p2();
1325 a.endStructure();
1326
1327 return a;
1328}
1329#endif
1330
1331QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.