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