src/dbus/qdbusmessage.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtDBus module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    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 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    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 QT_BEGIN_NAMESPACE
       
    57 
       
    58 static inline const char *data(const QByteArray &arr)
       
    59 {
       
    60     return arr.isEmpty() ? 0 : arr.constData();
       
    61 }
       
    62 
       
    63 QDBusMessagePrivate::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 
       
    70 QDBusMessagePrivate::~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 */
       
    83 QString 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 */
       
   103 DBusMessage *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 /*
       
   198 struct DBusMessage
       
   199 {
       
   200     DBusAtomic refcount;
       
   201     DBusHeader header;
       
   202     DBusString body;
       
   203     char byte_order;
       
   204     unsigned int locked : 1;
       
   205 DBUS_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 */
       
   222 QDBusMessage 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 
       
   246 bool QDBusMessagePrivate::isLocal(const QDBusMessage &message)
       
   247 {
       
   248     return message.d_ptr->localMessage;
       
   249 }
       
   250 
       
   251 QDBusMessage 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 
       
   308 QDBusMessage 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 */
       
   363 QDBusMessage 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 */
       
   394 QDBusMessage 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 */
       
   411 QDBusMessage 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 */
       
   440 QDBusMessage 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 */
       
   461 QDBusMessage 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 */
       
   496 QDBusMessage 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 */
       
   509 QDBusMessage::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 */
       
   521 QDBusMessage::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 */
       
   530 QDBusMessage::~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 */
       
   543 QDBusMessage &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 */
       
   552 QString 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 */
       
   561 QString 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 */
       
   570 QString 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 */
       
   578 QString 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 */
       
   588 QString 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 */
       
   599 QString 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 */
       
   610 bool 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 */
       
   631 void 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 */
       
   641 bool 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 */
       
   652 void 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 */
       
   662 QList<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 
       
   672 QDBusMessage &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 */
       
   682 QDBusMessage::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
       
   710 static 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 
       
   727 static 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 
       
   740 QDebug 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 
       
   760 QT_END_NAMESPACE
       
   761