--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbus/qdbusabstractinterface.cpp Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,751 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDBus module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdbusabstractinterface.h"
+#include "qdbusabstractinterface_p.h"
+
+#include "qdbusargument.h"
+#include "qdbuspendingcall.h"
+#include "qdbusmessage_p.h"
+#include "qdbusmetaobject_p.h"
+#include "qdbusmetatype_p.h"
+#include "qdbusutil_p.h"
+
+#include <qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+static QDBusError checkIfValid(const QString &service, const QString &path,
+ const QString &interface, bool isDynamic)
+{
+ // We should be throwing exceptions here... oh well
+ QDBusError error;
+
+ // dynamic interfaces (QDBusInterface) can have empty interfaces, but not service and object paths
+ // non-dynamic is the opposite: service and object paths can be empty, but not the interface
+ if (!isDynamic) {
+ // use assertion here because this should never happen, at all
+ Q_ASSERT_X(!interface.isEmpty(), "QDBusAbstractInterface", "Interface name cannot be empty");
+ }
+ if (!QDBusUtil::checkBusName(service, isDynamic ? QDBusUtil::EmptyNotAllowed : QDBusUtil::EmptyAllowed, &error))
+ return error;
+ if (!QDBusUtil::checkObjectPath(path, isDynamic ? QDBusUtil::EmptyNotAllowed : QDBusUtil::EmptyAllowed, &error))
+ return error;
+ if (!QDBusUtil::checkInterfaceName(interface, QDBusUtil::EmptyAllowed, &error))
+ return error;
+
+ // no error
+ return QDBusError();
+}
+
+QDBusAbstractInterfacePrivate::QDBusAbstractInterfacePrivate(const QString &serv,
+ const QString &p,
+ const QString &iface,
+ const QDBusConnection& con,
+ bool isDynamic)
+ : connection(con), service(serv), path(p), interface(iface),
+ lastError(checkIfValid(serv, p, iface, isDynamic)),
+ isValid(!lastError.isValid())
+{
+ if (!isValid)
+ return;
+
+ if (!connection.isConnected()) {
+ lastError = QDBusError(QDBusError::Disconnected,
+ QLatin1String("Not connected to D-Bus server"));
+ } else if (!service.isEmpty()) {
+ currentOwner = connectionPrivate()->getNameOwner(service); // verify the name owner
+ if (currentOwner.isEmpty()) {
+ lastError = connectionPrivate()->lastError;
+ }
+ }
+}
+
+bool QDBusAbstractInterfacePrivate::canMakeCalls() const
+{
+ // recheck only if we have a wildcard (i.e. empty) service or path
+ // if any are empty, set the error message according to QDBusUtil
+ if (service.isEmpty())
+ return QDBusUtil::checkBusName(service, QDBusUtil::EmptyNotAllowed, &lastError);
+ if (path.isEmpty())
+ return QDBusUtil::checkObjectPath(path, QDBusUtil::EmptyNotAllowed, &lastError);
+ return true;
+}
+
+void QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp, QVariant &where) const
+{
+ if (!isValid || !canMakeCalls()) { // can't make calls
+ where.clear();
+ return;
+ }
+
+ // is this metatype registered?
+ const char *expectedSignature = "";
+ if (mp.type() != 0xff) {
+ expectedSignature = QDBusMetaType::typeToSignature(where.userType());
+ if (expectedSignature == 0) {
+ qWarning("QDBusAbstractInterface: type %s must be registered with QtDBus before it can be "
+ "used to read property %s.%s",
+ mp.typeName(), qPrintable(interface), mp.name());
+ lastError = QDBusError(QDBusError::Failed,
+ QString::fromLatin1("Unregistered type %1 cannot be handled")
+ .arg(QLatin1String(mp.typeName())));
+ where.clear();
+ return;
+ }
+ }
+
+ // try to read this property
+ QDBusMessage msg = QDBusMessage::createMethodCall(service, path,
+ QLatin1String(DBUS_INTERFACE_PROPERTIES),
+ QLatin1String("Get"));
+ QDBusMessagePrivate::setParametersValidated(msg, true);
+ msg << interface << QString::fromUtf8(mp.name());
+ QDBusMessage reply = connection.call(msg, QDBus::Block);
+
+ if (reply.type() != QDBusMessage::ReplyMessage) {
+ lastError = reply;
+ where.clear();
+ return;
+ }
+ if (reply.signature() != QLatin1String("v")) {
+ QString errmsg = QLatin1String("Invalid signature `%1' in return from call to "
+ DBUS_INTERFACE_PROPERTIES);
+ lastError = QDBusError(QDBusError::InvalidSignature, errmsg.arg(reply.signature()));
+ where.clear();
+ return;
+ }
+
+ QByteArray foundSignature;
+ const char *foundType = 0;
+ QVariant value = qvariant_cast<QDBusVariant>(reply.arguments().at(0)).variant();
+
+ if (value.userType() == where.userType() || mp.type() == 0xff
+ || (expectedSignature[0] == 'v' && expectedSignature[1] == '\0')) {
+ // simple match
+ where = value;
+ return;
+ }
+
+ if (value.userType() == qMetaTypeId<QDBusArgument>()) {
+ QDBusArgument arg = qvariant_cast<QDBusArgument>(value);
+
+ foundType = "user type";
+ foundSignature = arg.currentSignature().toLatin1();
+ if (foundSignature == expectedSignature) {
+ // signatures match, we can demarshall
+ QDBusMetaType::demarshall(arg, where.userType(), where.data());
+ return;
+ }
+ } else {
+ foundType = value.typeName();
+ foundSignature = QDBusMetaType::typeToSignature(value.userType());
+ }
+
+ // there was an error...
+ QString errmsg = QLatin1String("Unexpected `%1' (%2) when retrieving property `%3.%4' "
+ "(expected type `%5' (%6))");
+ lastError = QDBusError(QDBusError::InvalidSignature,
+ errmsg.arg(QString::fromLatin1(foundType),
+ QString::fromLatin1(foundSignature),
+ interface,
+ QString::fromUtf8(mp.name()),
+ QString::fromLatin1(mp.typeName()),
+ QString::fromLatin1(expectedSignature)));
+ where.clear();
+ return;
+}
+
+bool QDBusAbstractInterfacePrivate::setProperty(const QMetaProperty &mp, const QVariant &value)
+{
+ if (!isValid || !canMakeCalls()) // can't make calls
+ return false;
+
+ // send the value
+ QDBusMessage msg = QDBusMessage::createMethodCall(service, path,
+ QLatin1String(DBUS_INTERFACE_PROPERTIES),
+ QLatin1String("Set"));
+ QDBusMessagePrivate::setParametersValidated(msg, true);
+ msg << interface << QString::fromUtf8(mp.name()) << qVariantFromValue(QDBusVariant(value));
+ QDBusMessage reply = connection.call(msg, QDBus::Block);
+
+ if (reply.type() != QDBusMessage::ReplyMessage) {
+ lastError = reply;
+ return false;
+ }
+ return true;
+}
+
+void QDBusAbstractInterfacePrivate::_q_serviceOwnerChanged(const QString &name,
+ const QString &oldOwner,
+ const QString &newOwner)
+{
+ Q_UNUSED(oldOwner);
+ //qDebug() << "QDBusAbstractInterfacePrivate serviceOwnerChanged" << name << oldOwner << newOwner;
+ if (name == service) {
+ currentOwner = newOwner;
+ }
+}
+
+QDBusAbstractInterfaceBase::QDBusAbstractInterfaceBase(QDBusAbstractInterfacePrivate &d, QObject *parent)
+ : QObject(d, parent)
+{
+}
+
+int QDBusAbstractInterfaceBase::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+ int saved_id = _id;
+ _id = QObject::qt_metacall(_c, _id, _a);
+ if (_id < 0)
+ return _id;
+
+ if (_c == QMetaObject::ReadProperty || _c == QMetaObject::WriteProperty) {
+ QMetaProperty mp = metaObject()->property(saved_id);
+ int &status = *reinterpret_cast<int *>(_a[2]);
+ QVariant &variant = *reinterpret_cast<QVariant *>(_a[1]);
+
+ if (_c == QMetaObject::WriteProperty) {
+ status = d_func()->setProperty(mp, variant) ? 1 : 0;
+ } else {
+ d_func()->property(mp, variant);
+ status = variant.isValid() ? 1 : 0;
+ }
+ _id = -1;
+ }
+ return _id;
+}
+
+/*!
+ \class QDBusAbstractInterface
+ \inmodule QtDBus
+ \since 4.2
+
+ \brief The QDBusAbstractInterface class is the base class for all D-Bus interfaces in the QtDBus binding, allowing access to remote interfaces
+
+ Generated-code classes also derive from QDBusAbstractInterface,
+ all methods described here are also valid for generated-code
+ classes. In addition to those described here, generated-code
+ classes provide member functions for the remote methods, which
+ allow for compile-time checking of the correct parameters and
+ return values, as well as property type-matching and signal
+ parameter-matching.
+
+ \sa {qdbusxml2cpp.html}{The QDBus compiler}, QDBusInterface
+*/
+
+/*!
+ \internal
+ This is the constructor called from QDBusInterface::QDBusInterface.
+*/
+QDBusAbstractInterface::QDBusAbstractInterface(QDBusAbstractInterfacePrivate &d, QObject *parent)
+ : QDBusAbstractInterfaceBase(d, parent)
+{
+ // keep track of the service owner
+ if (!d_func()->currentOwner.isEmpty())
+ QObject::connect(d_func()->connectionPrivate(), SIGNAL(serviceOwnerChanged(QString,QString,QString)),
+ this, SLOT(_q_serviceOwnerChanged(QString,QString,QString)));
+}
+
+/*!
+ \internal
+ This is the constructor called from static classes derived from
+ QDBusAbstractInterface (i.e., those generated by dbusxml2cpp).
+*/
+QDBusAbstractInterface::QDBusAbstractInterface(const QString &service, const QString &path,
+ const char *interface, const QDBusConnection &con,
+ QObject *parent)
+ : QDBusAbstractInterfaceBase(*new QDBusAbstractInterfacePrivate(service, path, QString::fromLatin1(interface),
+ con, false), parent)
+{
+ // keep track of the service owner
+ if (d_func()->connection.isConnected())
+ QObject::connect(d_func()->connectionPrivate(), SIGNAL(serviceOwnerChanged(QString,QString,QString)),
+ this, SLOT(_q_serviceOwnerChanged(QString,QString,QString)));
+}
+
+/*!
+ Releases this object's resources.
+*/
+QDBusAbstractInterface::~QDBusAbstractInterface()
+{
+}
+
+/*!
+ Returns true if this is a valid reference to a remote object. It returns false if
+ there was an error during the creation of this interface (for instance, if the remote
+ application does not exist).
+
+ Note: when dealing with remote objects, it is not always possible to determine if it
+ exists when creating a QDBusInterface.
+*/
+bool QDBusAbstractInterface::isValid() const
+{
+ return !d_func()->currentOwner.isEmpty();
+}
+
+/*!
+ Returns the connection this interface is assocated with.
+*/
+QDBusConnection QDBusAbstractInterface::connection() const
+{
+ return d_func()->connection;
+}
+
+/*!
+ Returns the name of the service this interface is associated with.
+*/
+QString QDBusAbstractInterface::service() const
+{
+ return d_func()->service;
+}
+
+/*!
+ Returns the object path that this interface is associated with.
+*/
+QString QDBusAbstractInterface::path() const
+{
+ return d_func()->path;
+}
+
+/*!
+ Returns the name of this interface.
+*/
+QString QDBusAbstractInterface::interface() const
+{
+ return d_func()->interface;
+}
+
+/*!
+ Returns the error the last operation produced, or an invalid error if the last operation did not
+ produce an error.
+*/
+QDBusError QDBusAbstractInterface::lastError() const
+{
+ return d_func()->lastError;
+}
+
+/*!
+ Places a call to the remote method specified by \a method on this interface, using \a args as
+ arguments. This function returns the message that was received as a reply, which can be a normal
+ QDBusMessage::ReplyMessage (indicating success) or QDBusMessage::ErrorMessage (if the call
+ failed). The \a mode parameter specifies how this call should be placed.
+
+ If the call succeeds, lastError() will be cleared; otherwise, it will contain the error this
+ call produced.
+
+ Normally, you should place calls using call().
+
+ \warning If you use \c UseEventLoop, your code must be prepared to deal with any reentrancy:
+ other method calls and signals may be delivered before this function returns, as well
+ as other Qt queued signals and events.
+
+ \threadsafe
+*/
+QDBusMessage QDBusAbstractInterface::callWithArgumentList(QDBus::CallMode mode,
+ const QString& method,
+ const QList<QVariant>& args)
+{
+ Q_D(QDBusAbstractInterface);
+
+ if (!d->isValid || !d->canMakeCalls())
+ return QDBusMessage::createError(d->lastError);
+
+ QString m = method;
+ // split out the signature from the method
+ int pos = method.indexOf(QLatin1Char('.'));
+ if (pos != -1)
+ m.truncate(pos);
+
+ if (mode == QDBus::AutoDetect) {
+ // determine if this a sync or async call
+ mode = QDBus::Block;
+ const QMetaObject *mo = metaObject();
+ QByteArray match = m.toLatin1() + '(';
+
+ for (int i = staticMetaObject.methodCount(); i < mo->methodCount(); ++i) {
+ QMetaMethod mm = mo->method(i);
+ if (QByteArray(mm.signature()).startsWith(match)) {
+ // found a method with the same name as what we're looking for
+ // hopefully, nobody is overloading asynchronous and synchronous methods with
+ // the same name
+
+ QList<QByteArray> tags = QByteArray(mm.tag()).split(' ');
+ if (tags.contains("Q_NOREPLY"))
+ mode = QDBus::NoBlock;
+
+ break;
+ }
+ }
+ }
+
+// qDebug() << "QDBusAbstractInterface" << "Service" << service() << "Path:" << path();
+ QDBusMessage msg = QDBusMessage::createMethodCall(service(), path(), interface(), m);
+ QDBusMessagePrivate::setParametersValidated(msg, true);
+ msg.setArguments(args);
+
+ QDBusMessage reply = d->connection.call(msg, mode);
+ d->lastError = reply; // will clear if reply isn't an error
+
+ // ensure that there is at least one element
+ if (reply.arguments().isEmpty())
+ reply << QVariant();
+
+ return reply;
+}
+
+/*!
+ \since 4.5
+ Places a call to the remote method specified by \a method on this
+ interface, using \a args as arguments. This function returns a
+ QDBusPendingCall object that can be used to track the status of the
+ reply and access its contents once it has arrived.
+
+ Normally, you should place calls using asyncCall().
+
+ \threadsafe
+*/
+QDBusPendingCall QDBusAbstractInterface::asyncCallWithArgumentList(const QString& method,
+ const QList<QVariant>& args)
+{
+ Q_D(QDBusAbstractInterface);
+
+ if (!d->isValid || !d->canMakeCalls())
+ return QDBusPendingCall::fromError(d->lastError);
+
+ QDBusMessage msg = QDBusMessage::createMethodCall(service(), path(), interface(), method);
+ QDBusMessagePrivate::setParametersValidated(msg, true);
+ msg.setArguments(args);
+ return d->connection.asyncCall(msg);
+}
+
+/*!
+ Places a call to the remote method specified by \a method
+ on this interface, using \a args as arguments. This function
+ returns immediately after queueing the call. The reply from
+ the remote function is delivered to the \a returnMethod on
+ object \a receiver. If an error occurs, the \a errorMethod
+ on object \a receiver is called instead.
+
+ This function returns true if the queueing succeeds. It does
+ not indicate that the executed call succeeded. If it fails,
+ the \a errorMethod is called. If the queueing failed, this
+ function returns false and no slot will be called.
+
+ The \a returnMethod must have as its parameters the types returned
+ by the function call. Optionally, it may have a QDBusMessage
+ parameter as its last or only parameter. The \a errorMethod must
+ have a QDBusError as its only parameter.
+
+ \since 4.3
+ \sa QDBusError, QDBusMessage
+ */
+bool QDBusAbstractInterface::callWithCallback(const QString &method,
+ const QList<QVariant> &args,
+ QObject *receiver,
+ const char *returnMethod,
+ const char *errorMethod)
+{
+ Q_D(QDBusAbstractInterface);
+
+ if (!d->isValid || !d->canMakeCalls())
+ return false;
+
+ QDBusMessage msg = QDBusMessage::createMethodCall(service(),
+ path(),
+ interface(),
+ method);
+ QDBusMessagePrivate::setParametersValidated(msg, true);
+ msg.setArguments(args);
+
+ d->lastError = 0;
+ return d->connection.callWithCallback(msg,
+ receiver,
+ returnMethod,
+ errorMethod);
+}
+
+/*!
+ \overload
+
+ This function is deprecated. Please use the overloaded version.
+
+ Places a call to the remote method specified by \a method
+ on this interface, using \a args as arguments. This function
+ returns immediately after queueing the call. The reply from
+ the remote function or any errors emitted by it are delivered
+ to the \a slot slot on object \a receiver.
+
+ This function returns true if the queueing succeeded: it does
+ not indicate that the call succeeded. If it failed, the slot
+ will be called with an error message. lastError() will not be
+ set under those circumstances.
+
+ \sa QDBusError, QDBusMessage
+*/
+bool QDBusAbstractInterface::callWithCallback(const QString &method,
+ const QList<QVariant> &args,
+ QObject *receiver,
+ const char *slot)
+{
+ return callWithCallback(method, args, receiver, slot, 0);
+}
+
+/*!
+ \internal
+ Catch signal connections.
+*/
+void QDBusAbstractInterface::connectNotify(const char *signal)
+{
+ // someone connecting to one of our signals
+ Q_D(QDBusAbstractInterface);
+ if (!d->isValid)
+ return;
+
+ // we end up recursing here, so optimise away
+ if (qstrcmp(signal + 1, "destroyed(QObject*)") == 0)
+ return;
+
+ QDBusConnectionPrivate *conn = d->connectionPrivate();
+ if (conn)
+ conn->connectRelay(d->service, d->currentOwner, d->path, d->interface,
+ this, signal);
+}
+
+/*!
+ \internal
+ Catch signal disconnections.
+*/
+void QDBusAbstractInterface::disconnectNotify(const char *signal)
+{
+ // someone disconnecting from one of our signals
+ Q_D(QDBusAbstractInterface);
+ if (!d->isValid)
+ return;
+
+ QDBusConnectionPrivate *conn = d->connectionPrivate();
+ if (conn)
+ conn->disconnectRelay(d->service, d->currentOwner, d->path, d->interface,
+ this, signal);
+}
+
+/*!
+ \internal
+ Get the value of the property \a propname.
+*/
+QVariant QDBusAbstractInterface::internalPropGet(const char *propname) const
+{
+ // assume this property exists and is readable
+ // we're only called from generated code anyways
+
+ return property(propname);
+}
+
+/*!
+ \internal
+ Set the value of the property \a propname to \a value.
+*/
+void QDBusAbstractInterface::internalPropSet(const char *propname, const QVariant &value)
+{
+ setProperty(propname, value);
+}
+
+/*!
+ Calls the method \a method on this interface and passes the parameters to this function to the
+ method.
+
+ The parameters to \c call are passed on to the remote function via D-Bus as input
+ arguments. Output arguments are returned in the QDBusMessage reply. If the reply is an error
+ reply, lastError() will also be set to the contents of the error message.
+
+ This function can be used with up to 8 parameters, passed in arguments \a arg1, \a arg2,
+ \a arg3, \a arg4, \a arg5, \a arg6, \a arg7 and \a arg8. If you need more than 8
+ parameters or if you have a variable number of parameters to be passed, use
+ callWithArgumentList().
+
+ It can be used the following way:
+
+ \snippet doc/src/snippets/code/src_qdbus_qdbusabstractinterface.cpp 0
+
+ This example illustrates function calling with 0, 1 and 2 parameters and illustrates different
+ parameter types passed in each (the first call to \c "ProcessWorkUnicode" will contain one
+ Unicode string, the second call to \c "ProcessWork" will contain one string and one byte array).
+*/
+QDBusMessage QDBusAbstractInterface::call(const QString &method, const QVariant &arg1,
+ const QVariant &arg2,
+ const QVariant &arg3,
+ const QVariant &arg4,
+ const QVariant &arg5,
+ const QVariant &arg6,
+ const QVariant &arg7,
+ const QVariant &arg8)
+{
+ return call(QDBus::AutoDetect, method, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
+}
+
+/*!
+ \overload
+
+ Calls the method \a method on this interface and passes the
+ parameters to this function to the method. If \a mode is \c
+ NoWaitForReply, then this function will return immediately after
+ placing the call, without waiting for a reply from the remote
+ method. Otherwise, \a mode indicates whether this function should
+ activate the Qt Event Loop while waiting for the reply to arrive.
+
+ This function can be used with up to 8 parameters, passed in arguments \a arg1, \a arg2,
+ \a arg3, \a arg4, \a arg5, \a arg6, \a arg7 and \a arg8. If you need more than 8
+ parameters or if you have a variable number of parameters to be passed, use
+ callWithArgumentList().
+
+ If this function reenters the Qt event loop in order to wait for the
+ reply, it will exclude user input. During the wait, it may deliver
+ signals and other method calls to your application. Therefore, it
+ must be prepared to handle a reentrancy whenever a call is placed
+ with call().
+*/
+QDBusMessage QDBusAbstractInterface::call(QDBus::CallMode mode, const QString &method,
+ const QVariant &arg1,
+ const QVariant &arg2,
+ const QVariant &arg3,
+ const QVariant &arg4,
+ const QVariant &arg5,
+ const QVariant &arg6,
+ const QVariant &arg7,
+ const QVariant &arg8)
+{
+ QList<QVariant> argList;
+ int count = 0 + arg1.isValid() + arg2.isValid() + arg3.isValid() + arg4.isValid() +
+ arg5.isValid() + arg6.isValid() + arg7.isValid() + arg8.isValid();
+
+ switch (count) {
+ case 8:
+ argList.prepend(arg8);
+ case 7:
+ argList.prepend(arg7);
+ case 6:
+ argList.prepend(arg6);
+ case 5:
+ argList.prepend(arg5);
+ case 4:
+ argList.prepend(arg4);
+ case 3:
+ argList.prepend(arg3);
+ case 2:
+ argList.prepend(arg2);
+ case 1:
+ argList.prepend(arg1);
+ }
+
+ return callWithArgumentList(mode, method, argList);
+}
+
+
+/*!
+ \since 4.5
+ Calls the method \a method on this interface and passes the parameters to this function to the
+ method.
+
+ The parameters to \c call are passed on to the remote function via D-Bus as input
+ arguments. The returned QDBusPendingCall object can be used to find out information about
+ the reply.
+
+ This function can be used with up to 8 parameters, passed in arguments \a arg1, \a arg2,
+ \a arg3, \a arg4, \a arg5, \a arg6, \a arg7 and \a arg8. If you need more than 8
+ parameters or if you have a variable number of parameters to be passed, use
+ asyncCallWithArgumentList().
+
+ It can be used the following way:
+
+ \snippet doc/src/snippets/code/src_qdbus_qdbusabstractinterface.cpp 1
+
+ This example illustrates function calling with 0, 1 and 2 parameters and illustrates different
+ parameter types passed in each (the first call to \c "ProcessWorkUnicode" will contain one
+ Unicode string, the second call to \c "ProcessWork" will contain one string and one byte array).
+*/
+QDBusPendingCall QDBusAbstractInterface::asyncCall(const QString &method, const QVariant &arg1,
+ const QVariant &arg2,
+ const QVariant &arg3,
+ const QVariant &arg4,
+ const QVariant &arg5,
+ const QVariant &arg6,
+ const QVariant &arg7,
+ const QVariant &arg8)
+{
+ QList<QVariant> argList;
+ int count = 0 + arg1.isValid() + arg2.isValid() + arg3.isValid() + arg4.isValid() +
+ arg5.isValid() + arg6.isValid() + arg7.isValid() + arg8.isValid();
+
+ switch (count) {
+ case 8:
+ argList.prepend(arg8);
+ case 7:
+ argList.prepend(arg7);
+ case 6:
+ argList.prepend(arg6);
+ case 5:
+ argList.prepend(arg5);
+ case 4:
+ argList.prepend(arg4);
+ case 3:
+ argList.prepend(arg3);
+ case 2:
+ argList.prepend(arg2);
+ case 1:
+ argList.prepend(arg1);
+ }
+
+ return asyncCallWithArgumentList(method, argList);
+}
+
+/*!
+ \internal
+*/
+QDBusMessage QDBusAbstractInterface::internalConstCall(QDBus::CallMode mode,
+ const QString &method,
+ const QList<QVariant> &args) const
+{
+ // ### move the code here, and make the other functions call this
+ return const_cast<QDBusAbstractInterface*>(this)->callWithArgumentList(mode, method, args);
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qdbusabstractinterface.cpp"