source: trunk/src/dbus/qdbusmessage.cpp@ 603

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

trunk: Merged in qt 4.6.1 sources.

File size: 24.3 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 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 "qdbusmessage.h"
43
44#include <qdebug.h>
45#include <qstringlist.h>
46
47#include "qdbus_symbols_p.h"
48
49#include "qdbusargument_p.h"
50#include "qdbuserror.h"
51#include "qdbusmessage_p.h"
52#include "qdbusmetatype.h"
53#include "qdbusconnection_p.h"
54#include "qdbusutil_p.h"
55
56QT_BEGIN_NAMESPACE
57
58static inline const char *data(const QByteArray &arr)
59{
60 return arr.isEmpty() ? 0 : arr.constData();
61}
62
63QDBusMessagePrivate::QDBusMessagePrivate()
64 : msg(0), reply(0), type(DBUS_MESSAGE_TYPE_INVALID),
65 timeout(-1), localReply(0), ref(1), delayedReply(false), localMessage(false),
66 parametersValidated(false)
67{
68}
69
70QDBusMessagePrivate::~QDBusMessagePrivate()
71{
72 if (msg)
73 q_dbus_message_unref(msg);
74 if (reply)
75 q_dbus_message_unref(reply);
76 delete localReply;
77}
78
79/*!
80 \since 4.3
81 Returns the human-readable message associated with the error that was received.
82*/
83QString QDBusMessage::errorMessage() const
84{
85 if (d_ptr->type == ErrorMessage) {
86 if (!d_ptr->message.isEmpty())
87 return d_ptr->message;
88 if (!d_ptr->arguments.isEmpty())
89 return d_ptr->arguments.at(0).toString();
90 }
91 return QString();
92}
93
94/*!
95 \internal
96 Constructs a DBusMessage object from this object. The returned value must be de-referenced
97 with q_dbus_message_unref.
98
99 The \a error object is set to indicate the error if anything went wrong with the
100 marshalling. Usually, this error message will be placed in the reply, as if the call failed.
101 The \a error pointer must not be null.
102*/
103DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDBusError *error)
104{
105 if (!qdbus_loadLibDBus()) {
106 *error = QDBusError(QDBusError::Failed, QLatin1String("Could not open lidbus-1 library"));
107 return 0;
108 }
109
110 DBusMessage *msg = 0;
111 const QDBusMessagePrivate *d_ptr = message.d_ptr;
112
113 switch (d_ptr->type) {
114 case DBUS_MESSAGE_TYPE_INVALID:
115 //qDebug() << "QDBusMessagePrivate::toDBusMessage" << "message is invalid";
116 break;
117 case DBUS_MESSAGE_TYPE_METHOD_CALL:
118 // only service and interface can be empty -> path and name must not be empty
119 if (!d_ptr->parametersValidated) {
120 if (!QDBusUtil::checkBusName(d_ptr->service, QDBusUtil::EmptyAllowed, error))
121 return 0;
122 if (!QDBusUtil::checkObjectPath(d_ptr->path, QDBusUtil::EmptyNotAllowed, error))
123 return 0;
124 if (!QDBusUtil::checkInterfaceName(d_ptr->interface, QDBusUtil::EmptyAllowed, error))
125 return 0;
126 if (!QDBusUtil::checkMemberName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error, "method"))
127 return 0;
128 }
129
130 msg = q_dbus_message_new_method_call(data(d_ptr->service.toUtf8()), d_ptr->path.toUtf8(),
131 data(d_ptr->interface.toUtf8()), d_ptr->name.toUtf8());
132 break;
133 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
134 msg = q_dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
135 if (!d_ptr->localMessage) {
136 q_dbus_message_set_destination(msg, q_dbus_message_get_sender(d_ptr->reply));
137 q_dbus_message_set_reply_serial(msg, q_dbus_message_get_serial(d_ptr->reply));
138 }
139 break;
140 case DBUS_MESSAGE_TYPE_ERROR:
141 // error name can't be empty
142 if (!d_ptr->parametersValidated
143 && !QDBusUtil::checkErrorName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error))
144 return 0;
145
146 msg = q_dbus_message_new(DBUS_MESSAGE_TYPE_ERROR);
147 q_dbus_message_set_error_name(msg, d_ptr->name.toUtf8());
148 if (!d_ptr->localMessage) {
149 q_dbus_message_set_destination(msg, q_dbus_message_get_sender(d_ptr->reply));
150 q_dbus_message_set_reply_serial(msg, q_dbus_message_get_serial(d_ptr->reply));
151 }
152 break;
153 case DBUS_MESSAGE_TYPE_SIGNAL:
154 // nothing can be empty here
155 if (!d_ptr->parametersValidated) {
156 if (!QDBusUtil::checkObjectPath(d_ptr->path, QDBusUtil::EmptyNotAllowed, error))
157 return 0;
158 if (!QDBusUtil::checkInterfaceName(d_ptr->interface, QDBusUtil::EmptyAllowed, error))
159 return 0;
160 if (!QDBusUtil::checkMemberName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error, "method"))
161 return 0;
162 }
163
164 msg = q_dbus_message_new_signal(d_ptr->path.toUtf8(), d_ptr->interface.toUtf8(),
165 d_ptr->name.toUtf8());
166 break;
167 default:
168 Q_ASSERT(false);
169 break;
170 }
171
172 // if we got here, the parameters validated
173 // and since the message parameters cannot be changed once the message is created
174 // we can record this fact
175 d_ptr->parametersValidated = true;
176
177 QDBusMarshaller marshaller;
178 QVariantList::ConstIterator it = d_ptr->arguments.constBegin();
179 QVariantList::ConstIterator cend = d_ptr->arguments.constEnd();
180 q_dbus_message_iter_init_append(msg, &marshaller.iterator);
181 if (!d_ptr->message.isEmpty())
182 // prepend the error message
183 marshaller.append(d_ptr->message);
184 for ( ; it != cend; ++it)
185 marshaller.appendVariantInternal(*it);
186
187 // check if everything is ok
188 if (marshaller.ok)
189 return msg;
190
191 // not ok;
192 q_dbus_message_unref(msg);
193 *error = QDBusError(QDBusError::Failed, QLatin1String("Marshalling failed: ") + marshaller.errorString);
194 return 0;
195}
196
197/*
198struct DBusMessage
199{
200 DBusAtomic refcount;
201 DBusHeader header;
202 DBusString body;
203 char byte_order;
204 unsigned int locked : 1;
205DBUS_DISABLE_CHECKS
206 unsigned int in_cache : 1;
207#endif
208 DBusList *size_counters;
209 long size_counter_delta;
210 dbus_uint32_t changed_stamp : CHANGED_STAMP_BITS;
211 DBusDataSlotList slot_list;
212#ifndef DBUS_DISABLE_CHECKS
213 int generation;
214#endif
215};
216*/
217
218/*!
219 \internal
220 Constructs a QDBusMessage by parsing the given DBusMessage object.
221*/
222QDBusMessage QDBusMessagePrivate::fromDBusMessage(DBusMessage *dmsg)
223{
224 QDBusMessage message;
225 if (!dmsg)
226 return message;
227
228 message.d_ptr->type = q_dbus_message_get_type(dmsg);
229 message.d_ptr->path = QString::fromUtf8(q_dbus_message_get_path(dmsg));
230 message.d_ptr->interface = QString::fromUtf8(q_dbus_message_get_interface(dmsg));
231 message.d_ptr->name = message.d_ptr->type == DBUS_MESSAGE_TYPE_ERROR ?
232 QString::fromUtf8(q_dbus_message_get_error_name(dmsg)) :
233 QString::fromUtf8(q_dbus_message_get_member(dmsg));
234 message.d_ptr->service = QString::fromUtf8(q_dbus_message_get_sender(dmsg));
235 message.d_ptr->signature = QString::fromUtf8(q_dbus_message_get_signature(dmsg));
236 message.d_ptr->msg = q_dbus_message_ref(dmsg);
237
238 QDBusDemarshaller demarshaller;
239 demarshaller.message = q_dbus_message_ref(dmsg);
240 if (q_dbus_message_iter_init(demarshaller.message, &demarshaller.iterator))
241 while (!demarshaller.atEnd())
242 message << demarshaller.toVariantInternal();
243 return message;
244}
245
246bool QDBusMessagePrivate::isLocal(const QDBusMessage &message)
247{
248 return message.d_ptr->localMessage;
249}
250
251QDBusMessage QDBusMessagePrivate::makeLocal(const QDBusConnectionPrivate &conn,
252 const QDBusMessage &asSent)
253{
254 // simulate the message being sent to the bus and then received back
255 // the only field that the bus sets when delivering the message
256 // (as opposed to the message as we send it), is the sender
257 // so we simply set the sender to our unique name
258
259 // determine if we are carrying any complex types
260 QString computedSignature;
261 QVariantList::ConstIterator it = asSent.d_ptr->arguments.constBegin();
262 QVariantList::ConstIterator end = asSent.d_ptr->arguments.constEnd();
263 for ( ; it != end; ++it) {
264 int id = it->userType();
265 const char *signature = QDBusMetaType::typeToSignature(id);
266 if ((id != QVariant::StringList && id != QVariant::ByteArray &&
267 qstrlen(signature) != 1) || id == qMetaTypeId<QDBusVariant>()) {
268 // yes, we are
269 // we must marshall and demarshall again so as to create QDBusArgument
270 // entries for the complex types
271 QDBusError error;
272 DBusMessage *message = toDBusMessage(asSent, &error);
273 if (!message) {
274 // failed to marshall, so it's a call error
275 return QDBusMessage::createError(error);
276 }
277
278 q_dbus_message_set_sender(message, conn.baseService.toUtf8());
279
280 QDBusMessage retval = fromDBusMessage(message);
281 retval.d_ptr->localMessage = true;
282 q_dbus_message_unref(message);
283 if (retval.d_ptr->service.isEmpty())
284 retval.d_ptr->service = conn.baseService;
285 return retval;
286 } else {
287 computedSignature += QLatin1String(signature);
288 }
289 }
290
291 // no complex types seen
292 // optimise by using the variant list itself
293 QDBusMessage retval;
294 QDBusMessagePrivate *d = retval.d_ptr;
295 d->arguments = asSent.d_ptr->arguments;
296 d->path = asSent.d_ptr->path;
297 d->interface = asSent.d_ptr->interface;
298 d->name = asSent.d_ptr->name;
299 d->message = asSent.d_ptr->message;
300 d->type = asSent.d_ptr->type;
301
302 d->service = conn.baseService;
303 d->signature = computedSignature;
304 d->localMessage = true;
305 return retval;
306}
307
308QDBusMessage QDBusMessagePrivate::makeLocalReply(const QDBusConnectionPrivate &conn,
309 const QDBusMessage &callMsg)
310{
311 // simulate the reply (return or error) message being sent to the bus and
312 // then received back.
313 if (callMsg.d_ptr->localReply)
314 return makeLocal(conn, *callMsg.d_ptr->localReply);
315 return QDBusMessage(); // failed
316}
317
318/*!
319 \class QDBusMessage
320 \inmodule QtDBus
321 \since 4.2
322
323 \brief The QDBusMessage class represents one message sent or
324 received over the D-Bus bus.
325
326 This object can represent any of the four different types of
327 messages (MessageType) that can occur on the bus:
328
329 \list
330 \o Method calls
331 \o Method return values
332 \o Signal emissions
333 \o Error codes
334 \endlist
335
336 Objects of this type are created with the static createError(),
337 createMethodCall() and createSignal() functions. Use the
338 QDBusConnection::send() function to send the messages.
339*/
340
341/*!
342 \enum QDBusMessage::MessageType
343 The possible message types:
344
345 \value MethodCallMessage a message representing an outgoing or incoming method call
346 \value SignalMessage a message representing an outgoing or incoming signal emission
347 \value ReplyMessage a message representing the return values of a method call
348 \value ErrorMessage a message representing an error condition in response to a method call
349 \value InvalidMessage an invalid message: this is never set on messages received from D-Bus
350*/
351
352/*!
353 Constructs a new DBus message with the given \a path, \a interface
354 and \a name, representing a signal emission.
355
356 A DBus signal is emitted from one application and is received by
357 all applications that are listening for that signal from that
358 interface.
359
360 The QDBusMessage object that is returned can be sent using the
361 QDBusConnection::send() function.
362*/
363QDBusMessage QDBusMessage::createSignal(const QString &path, const QString &interface,
364 const QString &name)
365{
366 QDBusMessage message;
367 message.d_ptr->type = DBUS_MESSAGE_TYPE_SIGNAL;
368 message.d_ptr->path = path;
369 message.d_ptr->interface = interface;
370 message.d_ptr->name = name;
371
372 return message;
373}
374
375/*!
376 Constructs a new DBus message representing a method call.
377 A method call always informs its destination address
378 (\a service, \a path, \a interface and \a method).
379
380 The DBus bus allows calling a method on a given remote object without specifying the
381 destination interface, if the method name is unique. However, if two interfaces on the
382 remote object export the same method name, the result is undefined (one of the two may be
383 called or an error may be returned).
384
385 When using DBus in a peer-to-peer context (i.e., not on a bus), the \a service parameter is
386 optional.
387
388 The QDBusObject and QDBusInterface classes provide a simpler abstraction to synchronous
389 method calling.
390
391 This function returns a QDBusMessage object that can be sent with
392 QDBusConnection::call().
393*/
394QDBusMessage QDBusMessage::createMethodCall(const QString &service, const QString &path,
395 const QString &interface, const QString &method)
396{
397 QDBusMessage message;
398 message.d_ptr->type = DBUS_MESSAGE_TYPE_METHOD_CALL;
399 message.d_ptr->service = service;
400 message.d_ptr->path = path;
401 message.d_ptr->interface = interface;
402 message.d_ptr->name = method;
403
404 return message;
405}
406
407/*!
408 Constructs a new DBus message representing an error,
409 with the given \a name and \a msg.
410*/
411QDBusMessage QDBusMessage::createError(const QString &name, const QString &msg)
412{
413 QDBusMessage error;
414 error.d_ptr->type = DBUS_MESSAGE_TYPE_ERROR;
415 error.d_ptr->name = name;
416 error.d_ptr->message = msg;
417
418 return error;
419}
420
421/*!
422 \fn QDBusMessage QDBusMessage::createError(const QDBusError &error)
423
424 Constructs a new DBus message representing the given \a error.
425*/
426
427/*!
428 \fn QDBusMessage QDBusMessage::createError(QDBusError::ErrorType type, const QString &msg)
429
430 Constructs a new DBus message for the error type \a type using
431 the message \a msg. Returns the DBus message.
432*/
433
434/*!
435 \fn QDBusMessage QDBusMessage::createReply(const QList<QVariant> &arguments) const
436
437 Constructs a new DBus message representing a reply, with the given
438 \a arguments.
439*/
440QDBusMessage QDBusMessage::createReply(const QVariantList &arguments) const
441{
442 QDBusMessage reply;
443 reply.setArguments(arguments);
444 reply.d_ptr->type = DBUS_MESSAGE_TYPE_METHOD_RETURN;
445 if (d_ptr->msg)
446 reply.d_ptr->reply = q_dbus_message_ref(d_ptr->msg);
447 if (d_ptr->localMessage) {
448 reply.d_ptr->localMessage = true;
449 d_ptr->localReply = new QDBusMessage(reply); // keep an internal copy
450 }
451
452 // the reply must have a msg or be a local-loop optimisation
453 Q_ASSERT(reply.d_ptr->reply || reply.d_ptr->localMessage);
454 return reply;
455}
456
457/*!
458 Constructs a new DBus message representing an error reply message,
459 with the given \a name and \a msg.
460*/
461QDBusMessage QDBusMessage::createErrorReply(const QString name, const QString &msg) const
462{
463 QDBusMessage reply = QDBusMessage::createError(name, msg);
464 if (d_ptr->msg)
465 reply.d_ptr->reply = q_dbus_message_ref(d_ptr->msg);
466 if (d_ptr->localMessage) {
467 reply.d_ptr->localMessage = true;
468 d_ptr->localReply = new QDBusMessage(reply); // keep an internal copy
469 }
470
471 // the reply must have a msg or be a local-loop optimisation
472 Q_ASSERT(reply.d_ptr->reply || reply.d_ptr->localMessage);
473 return reply;
474}
475
476/*!
477 \fn QDBusMessage QDBusMessage::createReply(const QVariant &argument) const
478
479 Constructs a new DBus message representing a reply, with the
480 given \a argument.
481*/
482
483/*!
484 \fn QDBusMessage QDBusMessage::createErrorReply(const QDBusError &error) const
485
486 Constructs a new DBus message representing an error reply message,
487 from the given \a error object.
488*/
489
490/*!
491 \fn QDBusMessage QDBusMessage::createErrorReply(QDBusError::ErrorType type, const QString &msg) const
492
493 Constructs a new DBus reply message for the error type \a type using
494 the message \a msg. Returns the DBus message.
495*/
496QDBusMessage QDBusMessage::createErrorReply(QDBusError::ErrorType atype, const QString &amsg) const
497{
498 QDBusMessage msg = createErrorReply(QDBusError::errorString(atype), amsg);
499 msg.d_ptr->parametersValidated = true;
500 return msg;
501}
502
503
504/*!
505 Constructs an empty, invalid QDBusMessage object.
506
507 \sa createError(), createMethodCall(), createSignal()
508*/
509QDBusMessage::QDBusMessage()
510{
511 d_ptr = new QDBusMessagePrivate;
512}
513
514/*!
515 Constructs a copy of the object given by \a other.
516
517 Note: QDBusMessage objects are shared. Modifications made to the
518 copy will affect the original one as well. See setDelayedReply()
519 for more information.
520*/
521QDBusMessage::QDBusMessage(const QDBusMessage &other)
522{
523 d_ptr = other.d_ptr;
524 d_ptr->ref.ref();
525}
526
527/*!
528 Disposes of the object and frees any resources that were being held.
529*/
530QDBusMessage::~QDBusMessage()
531{
532 if (!d_ptr->ref.deref())
533 delete d_ptr;
534}
535
536/*!
537 Copies the contents of the object given by \a other.
538
539 Note: QDBusMessage objects are shared. Modifications made to the
540 copy will affect the original one as well. See setDelayedReply()
541 for more information.
542*/
543QDBusMessage &QDBusMessage::operator=(const QDBusMessage &other)
544{
545 qAtomicAssign(d_ptr, other.d_ptr);
546 return *this;
547}
548
549/*!
550 Returns the name of the service or the bus address of the remote method call.
551*/
552QString QDBusMessage::service() const
553{
554 return d_ptr->service;
555}
556
557/*!
558 Returns the path of the object that this message is being sent to (in the case of a
559 method call) or being received from (for a signal).
560*/
561QString QDBusMessage::path() const
562{
563 return d_ptr->path;
564}
565
566/*!
567 Returns the interface of the method being called (in the case of a method call) or of
568 the signal being received from.
569*/
570QString QDBusMessage::interface() const
571{
572 return d_ptr->interface;
573}
574
575/*!
576 Returns the name of the signal that was emitted or the name of the method that was called.
577*/
578QString QDBusMessage::member() const
579{
580 if (d_ptr->type != ErrorMessage)
581 return d_ptr->name;
582 return QString();
583}
584
585/*!
586 Returns the name of the error that was received.
587*/
588QString QDBusMessage::errorName() const
589{
590 if (d_ptr->type == ErrorMessage)
591 return d_ptr->name;
592 return QString();
593}
594
595/*!
596 Returns the signature of the signal that was received or for the output arguments
597 of a method call.
598*/
599QString QDBusMessage::signature() const
600{
601 return d_ptr->signature;
602}
603
604/*!
605 Returns the flag that indicates if this message should see a reply
606 or not. This is only meaningful for \l {MethodCallMessage}{method
607 call messages}: any other kind of message cannot have replies and
608 this function will always return false for them.
609*/
610bool QDBusMessage::isReplyRequired() const
611{
612 if (!d_ptr->msg)
613 return d_ptr->localMessage; // if it's a local message, reply is required
614 return !q_dbus_message_get_no_reply(d_ptr->msg);
615}
616
617/*!
618 Sets whether the message will be replied later (if \a enable is
619 true) or if an automatic reply should be generated by QtDBus
620 (if \a enable is false).
621
622 In D-Bus, all method calls must generate a reply to the caller, unless the
623 caller explicitly indicates otherwise (see isReplyRequired()). QtDBus
624 automatically generates such replies for any slots being called, but it
625 also allows slots to indicate whether they will take responsibility
626 of sending the reply at a later time, after the function has finished
627 processing.
628
629 \sa {Delayed Replies}
630*/
631void QDBusMessage::setDelayedReply(bool enable) const
632{
633 d_ptr->delayedReply = enable;
634}
635
636/*!
637 Returns the delayed reply flag, as set by setDelayedReply(). By default, this
638 flag is false, which means QtDBus will generate automatic replies
639 when necessary.
640*/
641bool QDBusMessage::isDelayedReply() const
642{
643 return d_ptr->delayedReply;
644}
645
646/*!
647 Sets the arguments that are going to be sent over D-Bus to \a arguments. Those
648 will be the arguments to a method call or the parameters in the signal.
649
650 \sa arguments()
651*/
652void QDBusMessage::setArguments(const QList<QVariant> &arguments)
653{
654 // FIXME: should we detach?
655 d_ptr->arguments = arguments;
656}
657
658/*!
659 Returns the list of arguments that are going to be sent or were received from
660 D-Bus.
661*/
662QList<QVariant> QDBusMessage::arguments() const
663{
664 return d_ptr->arguments;
665}
666
667/*!
668 Appends the argument \a arg to the list of arguments to be sent over D-Bus in
669 a method call or signal emission.
670*/
671
672QDBusMessage &QDBusMessage::operator<<(const QVariant &arg)
673{
674 // FIXME: should we detach?
675 d_ptr->arguments.append(arg);
676 return *this;
677}
678
679/*!
680 Returns the message type.
681*/
682QDBusMessage::MessageType QDBusMessage::type() const
683{
684 switch (d_ptr->type) {
685 case DBUS_MESSAGE_TYPE_METHOD_CALL:
686 return MethodCallMessage;
687 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
688 return ReplyMessage;
689 case DBUS_MESSAGE_TYPE_ERROR:
690 return ErrorMessage;
691 case DBUS_MESSAGE_TYPE_SIGNAL:
692 return SignalMessage;
693 default:
694 break;
695 }
696 return InvalidMessage;
697}
698
699/*!
700 Sends the message without waiting for a reply. This is suitable
701 for errors, signals, and return values as well as calls whose
702 return values are not necessary.
703
704 Returns true if the message was queued successfully;
705 otherwise returns false.
706
707 \sa QDBusConnection::send()
708*/
709#ifndef QT_NO_DEBUG_STREAM
710static QDebug operator<<(QDebug dbg, QDBusMessage::MessageType t)
711{
712 switch (t)
713 {
714 case QDBusMessage::MethodCallMessage:
715 return dbg << "MethodCall";
716 case QDBusMessage::ReplyMessage:
717 return dbg << "MethodReturn";
718 case QDBusMessage::SignalMessage:
719 return dbg << "Signal";
720 case QDBusMessage::ErrorMessage:
721 return dbg << "Error";
722 default:
723 return dbg << "Invalid";
724 }
725}
726
727static void debugVariantList(QDebug dbg, const QVariantList &list)
728{
729 bool first = true;
730 QVariantList::ConstIterator it = list.constBegin();
731 QVariantList::ConstIterator end = list.constEnd();
732 for ( ; it != end; ++it) {
733 if (!first)
734 dbg.nospace() << ", ";
735 dbg.nospace() << qPrintable(QDBusUtil::argumentToString(*it));
736 first = false;
737 }
738}
739
740QDebug operator<<(QDebug dbg, const QDBusMessage &msg)
741{
742 dbg.nospace() << "QDBusMessage(type=" << msg.type()
743 << ", service=" << msg.service();
744 if (msg.type() == QDBusMessage::MethodCallMessage ||
745 msg.type() == QDBusMessage::SignalMessage)
746 dbg.nospace() << ", path=" << msg.path()
747 << ", interface=" << msg.interface()
748 << ", member=" << msg.member();
749 if (msg.type() == QDBusMessage::ErrorMessage)
750 dbg.nospace() << ", error name=" << msg.errorName()
751 << ", error message=" << msg.errorMessage();
752 dbg.nospace() << ", signature=" << msg.signature()
753 << ", contents=(";
754 debugVariantList(dbg, msg.arguments());
755 dbg.nospace() << ") )";
756 return dbg.space();
757}
758#endif
759
760QT_END_NAMESPACE
761
Note: See TracBrowser for help on using the repository browser.