source: trunk/src/dbus/qdbusmessage.cpp

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

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

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