1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the QtDBus module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 3 requirements |
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
24 | ** |
25 | ** GNU General Public License Usage |
26 | ** Alternatively, this file may be used under the terms of the GNU |
27 | ** General Public License version 2.0 or (at your option) the GNU General |
28 | ** Public license version 3 or any later version approved by the KDE Free |
29 | ** Qt Foundation. The licenses are as published by the Free Software |
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
31 | ** included in the packaging of this file. Please review the following |
32 | ** information to ensure the GNU General Public License requirements will |
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. |
35 | ** |
36 | ** $QT_END_LICENSE$ |
37 | ** |
38 | ****************************************************************************/ |
39 | |
40 | #include "qdbusargument.h" |
41 | #include "qdbusargument_p.h" |
42 | |
43 | #include <qatomic.h> |
44 | #include <qbytearray.h> |
45 | #include <qlist.h> |
46 | #include <qmap.h> |
47 | #include <qstring.h> |
48 | #include <qstringlist.h> |
49 | #include <qvariant.h> |
50 | #include <qdatetime.h> |
51 | #include <qrect.h> |
52 | #include <qline.h> |
53 | |
54 | #include "qdbusmetatype_p.h" |
55 | #include "qdbusutil_p.h" |
56 | |
57 | #ifndef QT_NO_DBUS |
58 | |
59 | QT_BEGIN_NAMESPACE |
60 | |
61 | QDBusArgumentPrivate::~QDBusArgumentPrivate() |
62 | { |
63 | if (message) |
64 | q_dbus_message_unref(message); |
65 | } |
66 | |
67 | QByteArray QDBusArgumentPrivate::createSignature(int id) |
68 | { |
69 | if (!qdbus_loadLibDBus()) |
70 | return "" ; |
71 | |
72 | QByteArray signature; |
73 | QDBusMarshaller *marshaller = new QDBusMarshaller(0); |
74 | marshaller->ba = &signature; |
75 | |
76 | // run it |
77 | QVariant v{QMetaType(id)}; |
78 | QDBusArgument arg(marshaller); |
79 | QDBusMetaType::marshall(arg, v.metaType(), v.constData()); |
80 | arg.d = nullptr; |
81 | |
82 | // delete it |
83 | bool ok = marshaller->ok; |
84 | delete marshaller; |
85 | |
86 | if (signature.isEmpty() || !ok || !QDBusUtil::isValidSingleSignature(QString::fromLatin1(signature))) { |
87 | qWarning("QDBusMarshaller: type `%s' produces invalid D-BUS signature `%s' " |
88 | "(Did you forget to call beginStructure() ?)" , |
89 | QMetaType(id).name(), |
90 | signature.isEmpty() ? "<empty>" : signature.constData()); |
91 | return "" ; |
92 | } else if ((signature.at(0) != DBUS_TYPE_ARRAY && signature.at(0) != DBUS_STRUCT_BEGIN_CHAR) || |
93 | (signature.at(0) == DBUS_TYPE_ARRAY && (signature.at(1) == DBUS_TYPE_BYTE || |
94 | signature.at(1) == DBUS_TYPE_STRING))) { |
95 | qWarning("QDBusMarshaller: type `%s' attempts to redefine basic D-BUS type '%s' (%s) " |
96 | "(Did you forget to call beginStructure() ?)" , |
97 | QMetaType(id).name(), |
98 | signature.constData(), |
99 | QDBusMetaType::signatureToMetaType(signature).name()); |
100 | return "" ; |
101 | } |
102 | return signature; |
103 | } |
104 | |
105 | bool QDBusArgumentPrivate::checkWrite(QDBusArgumentPrivate *&d) |
106 | { |
107 | if (!d) |
108 | return false; |
109 | if (d->direction == Marshalling) { |
110 | if (!d->marshaller()->ok) |
111 | return false; |
112 | |
113 | if (d->message && d->ref.loadRelaxed() != 1) { |
114 | QDBusMarshaller *dd = new QDBusMarshaller(d->capabilities); |
115 | dd->message = q_dbus_message_copy(d->message); |
116 | q_dbus_message_iter_init_append(dd->message, &dd->iterator); |
117 | |
118 | if (!d->ref.deref()) |
119 | delete d; |
120 | d = dd; |
121 | } |
122 | return true; |
123 | } |
124 | |
125 | #ifdef QT_DEBUG |
126 | qFatal("QDBusArgument: write from a read-only object" ); |
127 | #else |
128 | qWarning("QDBusArgument: write from a read-only object" ); |
129 | #endif |
130 | return false; |
131 | } |
132 | |
133 | bool QDBusArgumentPrivate::checkRead(QDBusArgumentPrivate *d) |
134 | { |
135 | if (!d) |
136 | return false; |
137 | if (d->direction == Demarshalling) |
138 | return true; |
139 | |
140 | #ifdef QT_DEBUG |
141 | qFatal("QDBusArgument: read from a write-only object" ); |
142 | #else |
143 | qWarning("QDBusArgument: read from a write-only object" ); |
144 | #endif |
145 | |
146 | return false; |
147 | } |
148 | |
149 | bool QDBusArgumentPrivate::checkReadAndDetach(QDBusArgumentPrivate *&d) |
150 | { |
151 | if (!checkRead(d)) |
152 | return false; // don't bother |
153 | |
154 | if (d->ref.loadRelaxed() == 1) |
155 | return true; // no need to detach |
156 | |
157 | QDBusDemarshaller *dd = new QDBusDemarshaller(d->capabilities); |
158 | dd->message = q_dbus_message_ref(d->message); |
159 | dd->iterator = static_cast<QDBusDemarshaller*>(d)->iterator; |
160 | |
161 | if (!d->ref.deref()) |
162 | delete d; |
163 | d = dd; |
164 | return true; |
165 | } |
166 | |
167 | /*! |
168 | \class QDBusArgument |
169 | \inmodule QtDBus |
170 | \since 4.2 |
171 | |
172 | \brief The QDBusArgument class is used to marshall and demarshall D-Bus arguments. |
173 | |
174 | The class is used to send arguments over D-Bus to remote |
175 | applications and to receive them back. D-Bus offers an extensible |
176 | type system, based on a few primitive types and associations of |
177 | them. See the \l {qdbustypesystem.html}{Qt D-Bus Type System} page |
178 | for more information on the type system. |
179 | |
180 | QDBusArgument is the central class in the Qt D-Bus type system, |
181 | providing functions to marshall and demarshall the primitive |
182 | types. The compound types are then created by association of one |
183 | or more of the primitive types in arrays, dictionaries or |
184 | structures. |
185 | |
186 | The following example illustrates how a structure containing an |
187 | integer and a string can be constructed using the \l |
188 | {qdbustypesystem.html}{Qt D-Bus type system}: |
189 | |
190 | \snippet code/src_qdbus_qdbusargument.cpp 0-0 |
191 | \codeline |
192 | \snippet code/src_qdbus_qdbusargument.cpp 0-1 |
193 | |
194 | The type has to be registered with qDBusRegisterMetaType() before |
195 | it can be used with QDBusArgument. Therefore, somewhere in your |
196 | program, you should add the following code: |
197 | |
198 | \snippet code/src_qdbus_qdbusargument.cpp 1 |
199 | |
200 | Once registered, a type can be used in outgoing method calls |
201 | (placed with QDBusAbstractInterface::call()), signal emissions |
202 | from registered objects or in incoming calls from remote |
203 | applications. |
204 | |
205 | It is important to note that the \c{operator<<} and \c{operator>>} |
206 | streaming functions must always produce the same number of entries |
207 | in case of structures, both in reading and in writing (marshalling |
208 | and demarshalling), otherwise calls and signals may start to |
209 | silently fail. |
210 | |
211 | The following example illustrates this wrong usage |
212 | in context of a class that may contain invalid data: |
213 | |
214 | \code |
215 | //bad code |
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 Qt D-Bus type system and should be avoided. |
233 | |
234 | \sa QDBusAbstractInterface, {qdbustypesystem.html}{The Qt D-Bus 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 | 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 template<typename T> T qdbus_cast(const QDBusArgument &arg) |
272 | \relates QDBusArgument |
273 | \since 4.2 |
274 | |
275 | Attempts to demarshall the contents of \a arg into the type |
276 | \c{T}. For example: |
277 | |
278 | \snippet code/src_qdbus_qdbusargument.cpp 2 |
279 | |
280 | Note that it is equivalent to the following: |
281 | |
282 | \snippet 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 = nullptr; |
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 Qt D-Bus. |
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 Qt D-Bus. |
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 | else |
608 | arg = 0; |
609 | return *this; |
610 | } |
611 | |
612 | /*! |
613 | \overload |
614 | Extracts one D-Bus primitive argument of type \c{BOOLEAN} from the |
615 | D-Bus stream. |
616 | */ |
617 | const QDBusArgument &QDBusArgument::operator>>(bool &arg) const |
618 | { |
619 | if (QDBusArgumentPrivate::checkReadAndDetach(d)) |
620 | arg = d->demarshaller()->toBool(); |
621 | else |
622 | arg = false; |
623 | return *this; |
624 | } |
625 | |
626 | /*! |
627 | \overload |
628 | Extracts one D-Bus primitive argument of type \c{UINT16} from the |
629 | D-Bus stream. |
630 | */ |
631 | const QDBusArgument &QDBusArgument::operator>>(ushort &arg) const |
632 | { |
633 | if (QDBusArgumentPrivate::checkReadAndDetach(d)) |
634 | arg = d->demarshaller()->toUShort(); |
635 | else |
636 | arg = 0; |
637 | return *this; |
638 | } |
639 | |
640 | /*! |
641 | \overload |
642 | Extracts one D-Bus primitive argument of type \c{INT16} from the |
643 | D-Bus stream. |
644 | */ |
645 | const QDBusArgument &QDBusArgument::operator>>(short &arg) const |
646 | { |
647 | if (QDBusArgumentPrivate::checkReadAndDetach(d)) |
648 | arg = d->demarshaller()->toShort(); |
649 | else |
650 | arg = 0; |
651 | return *this; |
652 | } |
653 | |
654 | /*! |
655 | \overload |
656 | Extracts one D-Bus primitive argument of type \c{INT32} from the |
657 | D-Bus stream. |
658 | */ |
659 | const QDBusArgument &QDBusArgument::operator>>(int &arg) const |
660 | { |
661 | if (QDBusArgumentPrivate::checkReadAndDetach(d)) |
662 | arg = d->demarshaller()->toInt(); |
663 | else |
664 | arg = 0; |
665 | return *this; |
666 | } |
667 | |
668 | /*! |
669 | \overload |
670 | Extracts one D-Bus primitive argument of type \c{UINT32} from the |
671 | D-Bus stream. |
672 | */ |
673 | const QDBusArgument &QDBusArgument::operator>>(uint &arg) const |
674 | { |
675 | if (QDBusArgumentPrivate::checkReadAndDetach(d)) |
676 | arg = d->demarshaller()->toUInt(); |
677 | else |
678 | arg = 0; |
679 | return *this; |
680 | } |
681 | |
682 | /*! |
683 | \overload |
684 | Extracts one D-Bus primitive argument of type \c{INT64} from the |
685 | D-Bus stream. |
686 | */ |
687 | const QDBusArgument &QDBusArgument::operator>>(qlonglong &arg) const |
688 | { |
689 | if (QDBusArgumentPrivate::checkReadAndDetach(d)) |
690 | arg = d->demarshaller()->toLongLong(); |
691 | else |
692 | arg = 0; |
693 | return *this; |
694 | } |
695 | |
696 | /*! |
697 | \overload |
698 | Extracts one D-Bus primitive argument of type \c{UINT64} from the |
699 | D-Bus stream. |
700 | */ |
701 | const QDBusArgument &QDBusArgument::operator>>(qulonglong &arg) const |
702 | { |
703 | if (QDBusArgumentPrivate::checkReadAndDetach(d)) |
704 | arg = d->demarshaller()->toULongLong(); |
705 | else |
706 | arg = 0; |
707 | return *this; |
708 | } |
709 | |
710 | /*! |
711 | \overload |
712 | Extracts one D-Bus primitive argument of type \c{DOUBLE} |
713 | (double-precision floating pount) from the D-Bus stream. |
714 | */ |
715 | const QDBusArgument &QDBusArgument::operator>>(double &arg) const |
716 | { |
717 | if (QDBusArgumentPrivate::checkReadAndDetach(d)) |
718 | arg = d->demarshaller()->toDouble(); |
719 | else |
720 | arg = 0; |
721 | return *this; |
722 | } |
723 | |
724 | /*! |
725 | \overload |
726 | Extracts one D-Bus primitive argument of type \c{STRING} (Unicode |
727 | character string) from the D-Bus stream. |
728 | */ |
729 | const QDBusArgument &QDBusArgument::operator>>(QString &arg) const |
730 | { |
731 | if (QDBusArgumentPrivate::checkReadAndDetach(d)) |
732 | arg = d->demarshaller()->toString(); |
733 | return *this; |
734 | } |
735 | |
736 | /*! |
737 | \overload |
738 | \internal |
739 | Extracts one D-Bus primitive argument of type \c{OBJECT_PATH} |
740 | (D-Bus path to an object) from the D-Bus stream. |
741 | */ |
742 | const QDBusArgument &QDBusArgument::operator>>(QDBusObjectPath &arg) const |
743 | { |
744 | if (QDBusArgumentPrivate::checkReadAndDetach(d)) |
745 | arg = d->demarshaller()->toObjectPath(); |
746 | return *this; |
747 | } |
748 | |
749 | /*! |
750 | \overload |
751 | \internal |
752 | Extracts one D-Bus primitive argument of type \c{SIGNATURE} (D-Bus |
753 | type signature) from the D-Bus stream. |
754 | */ |
755 | const QDBusArgument &QDBusArgument::operator>>(QDBusSignature &arg) const |
756 | { |
757 | if (QDBusArgumentPrivate::checkReadAndDetach(d)) |
758 | arg = d->demarshaller()->toSignature(); |
759 | return *this; |
760 | } |
761 | |
762 | /*! |
763 | \overload |
764 | \since 4.8 |
765 | \internal |
766 | Extracts one D-Bus primitive argument of type \c{UNIX_FILE_DESCRIPTOR} |
767 | (Unix file descriptor) from the D-Bus stream. |
768 | */ |
769 | const QDBusArgument &QDBusArgument::operator>>(QDBusUnixFileDescriptor &arg) const |
770 | { |
771 | if (QDBusArgumentPrivate::checkReadAndDetach(d)) |
772 | arg = d->demarshaller()->toUnixFileDescriptor(); |
773 | return *this; |
774 | } |
775 | |
776 | /*! |
777 | \overload |
778 | Extracts one D-Bus primitive argument of type \c{VARIANT} from the |
779 | D-Bus stream. |
780 | |
781 | A D-Bus variant type can contain any type, including other |
782 | variants. It is similar to the Qt QVariant type. |
783 | |
784 | In case the variant contains a type not directly supported by |
785 | QDBusArgument, the value of the returned QDBusVariant will contain |
786 | another QDBusArgument. It is your responsibility to further |
787 | demarshall it into another type. |
788 | */ |
789 | const QDBusArgument &QDBusArgument::operator>>(QDBusVariant &arg) const |
790 | { |
791 | if (QDBusArgumentPrivate::checkReadAndDetach(d)) |
792 | arg = d->demarshaller()->toVariant(); |
793 | return *this; |
794 | } |
795 | |
796 | /*! |
797 | \overload |
798 | Extracts an array of strings from the D-Bus stream and return it |
799 | as a QStringList. |
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 Qt D-Bus. |
806 | */ |
807 | const QDBusArgument &QDBusArgument::operator>>(QStringList &arg) const |
808 | { |
809 | if (QDBusArgumentPrivate::checkReadAndDetach(d)) |
810 | arg = d->demarshaller()->toStringList(); |
811 | return *this; |
812 | } |
813 | |
814 | /*! |
815 | \overload |
816 | Extracts an array of bytes from the D-Bus stream and return it |
817 | as a QByteArray. |
818 | |
819 | QStringList and QByteArray are the only two non-primitive types |
820 | that are supported directly by QDBusArgument because of their |
821 | widespread usage in Qt applications. |
822 | |
823 | Other arrays are supported through compound types in Qt D-Bus. |
824 | */ |
825 | const QDBusArgument &QDBusArgument::operator>>(QByteArray &arg) const |
826 | { |
827 | if (QDBusArgumentPrivate::checkReadAndDetach(d)) |
828 | arg = d->demarshaller()->toByteArray(); |
829 | return *this; |
830 | } |
831 | |
832 | /*! |
833 | Opens a new D-Bus structure suitable for appending new arguments. |
834 | |
835 | This function is used usually in \c{operator<<} streaming |
836 | operators, as in the following example: |
837 | |
838 | \snippet code/src_qdbus_qdbusargument.cpp 4 |
839 | |
840 | Structures can contain other structures, so the following code is |
841 | also valid: |
842 | |
843 | \snippet code/src_qdbus_qdbusargument.cpp 5 |
844 | |
845 | \sa endStructure(), beginArray(), beginMap() |
846 | */ |
847 | void QDBusArgument::beginStructure() |
848 | { |
849 | if (QDBusArgumentPrivate::checkWrite(d)) |
850 | d = d->marshaller()->beginStructure(); |
851 | } |
852 | |
853 | /*! |
854 | Closes a D-Bus structure opened with beginStructure(). This function must be called |
855 | same number of times that beginStructure() is called. |
856 | |
857 | \sa beginStructure(), endArray(), endMap() |
858 | */ |
859 | void QDBusArgument::endStructure() |
860 | { |
861 | if (QDBusArgumentPrivate::checkWrite(d)) |
862 | d = d->marshaller()->endStructure(); |
863 | } |
864 | |
865 | /*! |
866 | Opens a new D-Bus array suitable for appending elements of meta-type \a id. |
867 | |
868 | This function is used usually in \c{operator<<} streaming |
869 | operators, as in the following example: |
870 | |
871 | \snippet code/src_qdbus_qdbusargument.cpp 6 |
872 | |
873 | If the type you want to marshall is a QList or any of the |
874 | Qt's \l {Container Classes} that take one template parameter, |
875 | you need not declare an \c{operator<<} function for it, since |
876 | Qt D-Bus provides generic templates to do the job of marshalling |
877 | the data. The same applies for STL's sequence containers, such |
878 | as \c {std::list}, \c {std::vector}, etc. |
879 | |
880 | \sa endArray(), beginStructure(), beginMap() |
881 | */ |
882 | void QDBusArgument::beginArray(QMetaType id) |
883 | { |
884 | if (QDBusArgumentPrivate::checkWrite(d)) |
885 | d = d->marshaller()->beginArray(id); |
886 | } |
887 | |
888 | /*! |
889 | Closes a D-Bus array opened with beginArray(). This function must be called |
890 | same number of times that beginArray() is called. |
891 | |
892 | \sa beginArray(), endStructure(), endMap() |
893 | */ |
894 | void QDBusArgument::endArray() |
895 | { |
896 | if (QDBusArgumentPrivate::checkWrite(d)) |
897 | d = d->marshaller()->endArray(); |
898 | } |
899 | |
900 | /*! |
901 | Opens a new D-Bus map suitable for |
902 | appending elements. Maps are containers that associate one entry |
903 | (the key) to another (the value), such as Qt's QMap or QHash. The |
904 | ids of the map's key and value meta types must be passed in \a keyMetaType |
905 | and \a valueMetaType respectively. |
906 | |
907 | This function is used usually in \c{operator<<} streaming |
908 | operators, as in the following example: |
909 | |
910 | \snippet code/src_qdbus_qdbusargument.cpp 7 |
911 | |
912 | You usually don't need to provide an \c{operator<<} or \c{operator>>} |
913 | function for associative containers such as QHash or std::map, |
914 | since Qt D-Bus provides generic templates to do the job of marshalling |
915 | the data. |
916 | |
917 | \sa endMap(), beginStructure(), beginArray(), beginMapEntry() |
918 | */ |
919 | void QDBusArgument::beginMap(QMetaType keyMetaType, QMetaType valueMetaType) |
920 | { |
921 | if (QDBusArgumentPrivate::checkWrite(d)) |
922 | d = d->marshaller()->beginMap(keyMetaType, valueMetaType); |
923 | } |
924 | |
925 | /*! |
926 | Closes a D-Bus map opened with beginMap(). This function must be called |
927 | same number of times that beginMap() is called. |
928 | |
929 | \sa beginMap(), endStructure(), endArray() |
930 | */ |
931 | void QDBusArgument::endMap() |
932 | { |
933 | if (QDBusArgumentPrivate::checkWrite(d)) |
934 | d = d->marshaller()->endMap(); |
935 | } |
936 | |
937 | /*! |
938 | Opens a D-Bus map entry suitable for |
939 | appending the key and value entries. This function is only valid |
940 | when a map has been opened with beginMap(). |
941 | |
942 | See beginMap() for an example of usage of this function. |
943 | |
944 | \sa endMapEntry(), beginMap() |
945 | */ |
946 | void QDBusArgument::beginMapEntry() |
947 | { |
948 | if (QDBusArgumentPrivate::checkWrite(d)) |
949 | d = d->marshaller()->beginMapEntry(); |
950 | } |
951 | |
952 | /*! |
953 | Closes a D-Bus map entry opened with beginMapEntry(). This function must be called |
954 | same number of times that beginMapEntry() is called. |
955 | |
956 | \sa beginMapEntry() |
957 | */ |
958 | void QDBusArgument::endMapEntry() |
959 | { |
960 | if (QDBusArgumentPrivate::checkWrite(d)) |
961 | d = d->marshaller()->endMapEntry(); |
962 | } |
963 | |
964 | /*! |
965 | Opens a D-Bus structure suitable for extracting elements. |
966 | |
967 | This function is used usually in \c{operator>>} streaming |
968 | operators, as in the following example: |
969 | |
970 | \snippet code/src_qdbus_qdbusargument.cpp 8 |
971 | |
972 | \sa endStructure(), beginArray(), beginMap() |
973 | */ |
974 | void QDBusArgument::beginStructure() const |
975 | { |
976 | if (QDBusArgumentPrivate::checkReadAndDetach(d)) |
977 | d = d->demarshaller()->beginStructure(); |
978 | } |
979 | |
980 | /*! |
981 | Closes the D-Bus structure and allow extracting of the next element |
982 | after the structure. |
983 | |
984 | \sa beginStructure() |
985 | */ |
986 | void QDBusArgument::endStructure() const |
987 | { |
988 | if (QDBusArgumentPrivate::checkReadAndDetach(d)) |
989 | d = d->demarshaller()->endStructure(); |
990 | } |
991 | |
992 | /*! |
993 | Recurses into the D-Bus array to allow extraction of |
994 | the array elements. |
995 | |
996 | This function is used usually in \c{operator>>} streaming |
997 | operators, as in the following example: |
998 | |
999 | \snippet code/src_qdbus_qdbusargument.cpp 9 |
1000 | |
1001 | If the type you want to demarshall is a QList or any of the |
1002 | Qt's \l {Container Classes} that take one template parameter, you |
1003 | need not declare an \c{operator>>} function for it, since Qt D-Bus |
1004 | provides generic templates to do the job of demarshalling the data. |
1005 | The same applies for STL's sequence containers, such as \c {std::list}, |
1006 | \c {std::vector}, etc. |
1007 | |
1008 | \sa atEnd(), beginStructure(), beginMap() |
1009 | */ |
1010 | void QDBusArgument::beginArray() const |
1011 | { |
1012 | if (QDBusArgumentPrivate::checkReadAndDetach(d)) |
1013 | d = d->demarshaller()->beginArray(); |
1014 | } |
1015 | |
1016 | /*! |
1017 | Closes the D-Bus array and allow extracting of the next element |
1018 | after the array. |
1019 | |
1020 | \sa beginArray() |
1021 | */ |
1022 | void QDBusArgument::endArray() const |
1023 | { |
1024 | if (QDBusArgumentPrivate::checkReadAndDetach(d)) |
1025 | d = d->demarshaller()->endArray(); |
1026 | } |
1027 | |
1028 | /*! |
1029 | Recurses into the D-Bus map to allow extraction of |
1030 | the map's elements. |
1031 | |
1032 | This function is used usually in \c{operator>>} streaming |
1033 | operators, as in the following example: |
1034 | |
1035 | \snippet code/src_qdbus_qdbusargument.cpp 10 |
1036 | |
1037 | If the type you want to demarshall is a QMap or QHash, you need not |
1038 | declare an \c{operator>>} function for it, since Qt D-Bus provides |
1039 | generic templates to do the job of demarshalling the data. |
1040 | |
1041 | \sa endMap(), beginStructure(), beginArray(), beginMapEntry() |
1042 | */ |
1043 | void QDBusArgument::beginMap() const |
1044 | { |
1045 | if (QDBusArgumentPrivate::checkReadAndDetach(d)) |
1046 | d = d->demarshaller()->beginMap(); |
1047 | } |
1048 | |
1049 | /*! |
1050 | Closes the D-Bus map and allow extracting of the next element |
1051 | after the map. |
1052 | |
1053 | \sa beginMap() |
1054 | */ |
1055 | void QDBusArgument::endMap() const |
1056 | { |
1057 | if (QDBusArgumentPrivate::checkReadAndDetach(d)) |
1058 | d = d->demarshaller()->endMap(); |
1059 | } |
1060 | |
1061 | /*! |
1062 | Recurses into the D-Bus map entry to allow extraction |
1063 | of the key and value pair. |
1064 | |
1065 | See beginMap() for an example of how this function is usually used. |
1066 | |
1067 | \sa endMapEntry(), beginMap() |
1068 | */ |
1069 | void QDBusArgument::beginMapEntry() const |
1070 | { |
1071 | if (QDBusArgumentPrivate::checkReadAndDetach(d)) |
1072 | d = d->demarshaller()->beginMapEntry(); |
1073 | } |
1074 | |
1075 | /*! |
1076 | Closes the D-Bus map entry and allow extracting of the next element |
1077 | on the map. |
1078 | |
1079 | \sa beginMapEntry() |
1080 | */ |
1081 | void QDBusArgument::endMapEntry() const |
1082 | { |
1083 | if (QDBusArgumentPrivate::checkReadAndDetach(d)) |
1084 | d = d->demarshaller()->endMapEntry(); |
1085 | } |
1086 | |
1087 | /*! |
1088 | Returns \c true if there are no more elements to be extracted from |
1089 | this QDBusArgument. This function is usually used in QDBusArgument |
1090 | objects returned from beginMap() and beginArray(). |
1091 | */ |
1092 | bool QDBusArgument::atEnd() const |
1093 | { |
1094 | if (QDBusArgumentPrivate::checkRead(d)) |
1095 | return d->demarshaller()->atEnd(); |
1096 | |
1097 | return true; // at least, stop reading |
1098 | } |
1099 | |
1100 | /*! |
1101 | \since 4.5 |
1102 | |
1103 | Returns the current argument in the form of a QVariant. Basic |
1104 | types will be decoded and returned in the QVariant, but for |
1105 | complex types, this function will return a QDBusArgument object in |
1106 | the QVariant. It is the caller's responsibility to decode the |
1107 | argument (for example, by calling asVariant() in it). |
1108 | |
1109 | For example, if the current argument is an INT32, this function |
1110 | will return a QVariant with an argument of type QMetaType::Int. For |
1111 | an array of INT32, it will return a QVariant containing a |
1112 | QDBusArgument. |
1113 | |
1114 | If an error occurs or if there are no more arguments to decode |
1115 | (i.e., we are at the end of the argument list), this function will |
1116 | return an invalid QVariant. |
1117 | |
1118 | \sa atEnd() |
1119 | */ |
1120 | QVariant QDBusArgument::asVariant() const |
1121 | { |
1122 | if (QDBusArgumentPrivate::checkRead(d)) |
1123 | return d->demarshaller()->toVariantInternal(); |
1124 | |
1125 | return QVariant(); |
1126 | } |
1127 | |
1128 | QT_END_NAMESPACE |
1129 | |
1130 | // for optimization purposes, we include the marshallers here |
1131 | #include "qdbusmarshaller.cpp" |
1132 | #include "qdbusdemarshaller.cpp" |
1133 | |
1134 | QT_BEGIN_NAMESPACE |
1135 | |
1136 | // QDBusArgument operators |
1137 | |
1138 | const QDBusArgument &operator>>(const QDBusArgument &a, QVariant &v) |
1139 | { |
1140 | QDBusVariant dbv; |
1141 | a >> dbv; |
1142 | v = dbv.variant(); |
1143 | return a; |
1144 | } |
1145 | |
1146 | // QVariant types |
1147 | #ifndef QDBUS_NO_SPECIALTYPES |
1148 | const QDBusArgument &operator>>(const QDBusArgument &a, QDate &date) |
1149 | { |
1150 | int y, m, d; |
1151 | a.beginStructure(); |
1152 | a >> y >> m >> d; |
1153 | a.endStructure(); |
1154 | |
1155 | if (y != 0 && m != 0 && d != 0) |
1156 | date.setDate(y, m, d); |
1157 | else |
1158 | date = QDate(); |
1159 | return a; |
1160 | } |
1161 | |
1162 | QDBusArgument &operator<<(QDBusArgument &a, const QDate &date) |
1163 | { |
1164 | a.beginStructure(); |
1165 | if (date.isValid()) |
1166 | a << date.year() << date.month() << date.day(); |
1167 | else |
1168 | a << 0 << 0 << 0; |
1169 | a.endStructure(); |
1170 | return a; |
1171 | } |
1172 | |
1173 | const QDBusArgument &operator>>(const QDBusArgument &a, QTime &time) |
1174 | { |
1175 | int h, m, s, ms; |
1176 | a.beginStructure(); |
1177 | a >> h >> m >> s >> ms; |
1178 | a.endStructure(); |
1179 | |
1180 | if (h < 0) |
1181 | time = QTime(); |
1182 | else |
1183 | time.setHMS(h, m, s, ms); |
1184 | return a; |
1185 | } |
1186 | |
1187 | QDBusArgument &operator<<(QDBusArgument &a, const QTime &time) |
1188 | { |
1189 | a.beginStructure(); |
1190 | if (time.isValid()) |
1191 | a << time.hour() << time.minute() << time.second() << time.msec(); |
1192 | else |
1193 | a << -1 << -1 << -1 << -1; |
1194 | a.endStructure(); |
1195 | return a; |
1196 | } |
1197 | |
1198 | const QDBusArgument &operator>>(const QDBusArgument &a, QDateTime &dt) |
1199 | { |
1200 | QDate date; |
1201 | QTime time; |
1202 | int timespec; |
1203 | |
1204 | a.beginStructure(); |
1205 | a >> date >> time >> timespec; |
1206 | a.endStructure(); |
1207 | |
1208 | dt = QDateTime(date, time, Qt::TimeSpec(timespec)); |
1209 | return a; |
1210 | } |
1211 | |
1212 | QDBusArgument &operator<<(QDBusArgument &a, const QDateTime &dt) |
1213 | { |
1214 | a.beginStructure(); |
1215 | a << dt.date() << dt.time() << int(dt.timeSpec()); |
1216 | a.endStructure(); |
1217 | return a; |
1218 | } |
1219 | |
1220 | const QDBusArgument &operator>>(const QDBusArgument &a, QRect &rect) |
1221 | { |
1222 | int x, y, width, height; |
1223 | a.beginStructure(); |
1224 | a >> x >> y >> width >> height; |
1225 | a.endStructure(); |
1226 | |
1227 | rect.setRect(x, y, width, height); |
1228 | return a; |
1229 | } |
1230 | |
1231 | QDBusArgument &operator<<(QDBusArgument &a, const QRect &rect) |
1232 | { |
1233 | a.beginStructure(); |
1234 | a << rect.x() << rect.y() << rect.width() << rect.height(); |
1235 | a.endStructure(); |
1236 | |
1237 | return a; |
1238 | } |
1239 | |
1240 | const QDBusArgument &operator>>(const QDBusArgument &a, QRectF &rect) |
1241 | { |
1242 | double x, y, width, height; |
1243 | a.beginStructure(); |
1244 | a >> x >> y >> width >> height; |
1245 | a.endStructure(); |
1246 | |
1247 | rect.setRect(qreal(x), qreal(y), qreal(width), qreal(height)); |
1248 | return a; |
1249 | } |
1250 | |
1251 | QDBusArgument &operator<<(QDBusArgument &a, const QRectF &rect) |
1252 | { |
1253 | a.beginStructure(); |
1254 | a << double(rect.x()) << double(rect.y()) << double(rect.width()) << double(rect.height()); |
1255 | a.endStructure(); |
1256 | |
1257 | return a; |
1258 | } |
1259 | |
1260 | const QDBusArgument &operator>>(const QDBusArgument &a, QSize &size) |
1261 | { |
1262 | a.beginStructure(); |
1263 | a >> size.rwidth() >> size.rheight(); |
1264 | a.endStructure(); |
1265 | |
1266 | return a; |
1267 | } |
1268 | |
1269 | QDBusArgument &operator<<(QDBusArgument &a, const QSize &size) |
1270 | { |
1271 | a.beginStructure(); |
1272 | a << size.width() << size.height(); |
1273 | a.endStructure(); |
1274 | |
1275 | return a; |
1276 | } |
1277 | |
1278 | const QDBusArgument &operator>>(const QDBusArgument &a, QSizeF &size) |
1279 | { |
1280 | double width, height; |
1281 | a.beginStructure(); |
1282 | a >> width >> height; |
1283 | a.endStructure(); |
1284 | |
1285 | size.setWidth(qreal(width)); |
1286 | size.setHeight(qreal(height)); |
1287 | return a; |
1288 | } |
1289 | |
1290 | QDBusArgument &operator<<(QDBusArgument &a, const QSizeF &size) |
1291 | { |
1292 | a.beginStructure(); |
1293 | a << double(size.width()) << double(size.height()); |
1294 | a.endStructure(); |
1295 | |
1296 | return a; |
1297 | } |
1298 | |
1299 | const QDBusArgument &operator>>(const QDBusArgument &a, QPoint &pt) |
1300 | { |
1301 | a.beginStructure(); |
1302 | a >> pt.rx() >> pt.ry(); |
1303 | a.endStructure(); |
1304 | |
1305 | return a; |
1306 | } |
1307 | |
1308 | QDBusArgument &operator<<(QDBusArgument &a, const QPoint &pt) |
1309 | { |
1310 | a.beginStructure(); |
1311 | a << pt.x() << pt.y(); |
1312 | a.endStructure(); |
1313 | |
1314 | return a; |
1315 | } |
1316 | |
1317 | const QDBusArgument &operator>>(const QDBusArgument &a, QPointF &pt) |
1318 | { |
1319 | double x, y; |
1320 | a.beginStructure(); |
1321 | a >> x >> y; |
1322 | a.endStructure(); |
1323 | |
1324 | pt.setX(qreal(x)); |
1325 | pt.setY(qreal(y)); |
1326 | return a; |
1327 | } |
1328 | |
1329 | QDBusArgument &operator<<(QDBusArgument &a, const QPointF &pt) |
1330 | { |
1331 | a.beginStructure(); |
1332 | a << double(pt.x()) << double(pt.y()); |
1333 | a.endStructure(); |
1334 | |
1335 | return a; |
1336 | } |
1337 | |
1338 | const QDBusArgument &operator>>(const QDBusArgument &a, QLine &line) |
1339 | { |
1340 | QPoint p1, p2; |
1341 | a.beginStructure(); |
1342 | a >> p1 >> p2; |
1343 | a.endStructure(); |
1344 | |
1345 | line = QLine(p1, p2); |
1346 | return a; |
1347 | } |
1348 | |
1349 | QDBusArgument &operator<<(QDBusArgument &a, const QLine &line) |
1350 | { |
1351 | a.beginStructure(); |
1352 | a << line.p1() << line.p2(); |
1353 | a.endStructure(); |
1354 | |
1355 | return a; |
1356 | } |
1357 | |
1358 | const QDBusArgument &operator>>(const QDBusArgument &a, QLineF &line) |
1359 | { |
1360 | QPointF p1, p2; |
1361 | a.beginStructure(); |
1362 | a >> p1 >> p2; |
1363 | a.endStructure(); |
1364 | |
1365 | line = QLineF(p1, p2); |
1366 | return a; |
1367 | } |
1368 | |
1369 | QDBusArgument &operator<<(QDBusArgument &a, const QLineF &line) |
1370 | { |
1371 | a.beginStructure(); |
1372 | a << line.p1() << line.p2(); |
1373 | a.endStructure(); |
1374 | |
1375 | return a; |
1376 | } |
1377 | #endif |
1378 | |
1379 | /*! |
1380 | \fn void QDBusArgument::swap(QDBusArgument &other) |
1381 | |
1382 | Swaps this QDBusArgument instance with \a other. |
1383 | */ |
1384 | |
1385 | QT_END_NAMESPACE |
1386 | |
1387 | #endif // QT_NO_DBUS |
1388 | |