Qt 4.8
qdbusinterface.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtDBus module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qdbusinterface.h"
43 
44 #include "qdbus_symbols_p.h"
45 #include <QtCore/qpointer.h>
46 #include <QtCore/qstringlist.h>
47 
48 #include "qdbusmetatype_p.h"
49 #include "qdbusinterface_p.h"
50 #include "qdbusconnection_p.h"
51 
52 #ifndef QT_NO_DBUS
53 
55 
56 static void copyArgument(void *to, int id, const QVariant &arg)
57 {
58  if (id == arg.userType()) {
59  switch (id) {
60  case QVariant::Bool:
61  *reinterpret_cast<bool *>(to) = arg.toBool();
62  return;
63 
64  case QMetaType::UChar:
65  *reinterpret_cast<uchar *>(to) = arg.value<uchar>();
66  return;
67 
68  case QMetaType::Short:
69  *reinterpret_cast<short *>(to) = arg.value<short>();
70  return;
71 
72  case QMetaType::UShort:
73  *reinterpret_cast<ushort *>(to) = arg.value<ushort>();
74  return;
75 
76  case QVariant::Int:
77  *reinterpret_cast<int *>(to) = arg.toInt();
78  return;
79 
80  case QVariant::UInt:
81  *reinterpret_cast<uint *>(to) = arg.toUInt();
82  return;
83 
84  case QVariant::LongLong:
85  *reinterpret_cast<qlonglong *>(to) = arg.toLongLong();
86  return;
87 
89  *reinterpret_cast<qulonglong *>(to) = arg.toULongLong();
90  return;
91 
92  case QVariant::Double:
93  *reinterpret_cast<double *>(to) = arg.toDouble();
94  return;
95 
96  case QVariant::String:
97  *reinterpret_cast<QString *>(to) = arg.toString();
98  return;
99 
100  case QVariant::ByteArray:
101  *reinterpret_cast<QByteArray *>(to) = arg.toByteArray();
102  return;
103 
105  *reinterpret_cast<QStringList *>(to) = arg.toStringList();
106  return;
107  }
108 
109  if (id == QDBusMetaTypeId::variant) {
110  *reinterpret_cast<QDBusVariant *>(to) = arg.value<QDBusVariant>();
111  return;
112  } else if (id == QDBusMetaTypeId::objectpath) {
113  *reinterpret_cast<QDBusObjectPath *>(to) = arg.value<QDBusObjectPath>();
114  return;
115  } else if (id == QDBusMetaTypeId::signature) {
116  *reinterpret_cast<QDBusSignature *>(to) = arg.value<QDBusSignature>();
117  return;
118  }
119 
120  // those above are the only types possible
121  // the demarshaller code doesn't demarshall anything else
122  qFatal("Found a decoded basic type in a D-Bus reply that shouldn't be there");
123  }
124 
125  // if we got here, it's either an un-dermarshalled type or a mismatch
126  if (arg.userType() != QDBusMetaTypeId::argument) {
127  // it's a mismatch
128  //qWarning?
129  return;
130  }
131 
132  // is this type registered?
133  const char *userSignature = QDBusMetaType::typeToSignature(id);
134  if (!userSignature || !*userSignature) {
135  // type not registered
136  //qWarning?
137  return;
138  }
139 
140  // is it the same signature?
141  QDBusArgument dbarg = arg.value<QDBusArgument>();
142  if (dbarg.currentSignature() != QLatin1String(userSignature)) {
143  // not the same signature, another mismatch
144  //qWarning?
145  return;
146  }
147 
148  // we can demarshall
149  QDBusMetaType::demarshall(dbarg, id, to);
150 }
151 
153  const QString &iface, const QDBusConnection &con)
154  : QDBusAbstractInterfacePrivate(serv, p, iface, con, true), metaObject(0)
155 {
156  // QDBusAbstractInterfacePrivate's constructor checked the parameters for us
157  if (connection.isConnected()) {
159 
160  if (!metaObject) {
161  // creation failed, somehow
162  // most common causes are that the service doesn't exist or doesn't support introspection
163  // those are not fatal errors, so we continue working
164 
165  if (!lastError.isValid())
167  }
168  }
169 }
170 
172 {
173  if (metaObject && !metaObject->cached)
174  delete metaObject;
175 }
176 
177 
223  : QDBusAbstractInterface(*new QDBusInterfacePrivate(service, path, interface, connection),
224  parent)
225 {
226 }
227 
232 {
233  // resources are freed in QDBusInterfacePrivate::~QDBusInterfacePrivate()
234 }
235 
244 {
245  return d_func()->metaObject ? d_func()->metaObject : &QDBusAbstractInterface::staticMetaObject;
246 }
247 
255 void *QDBusInterface::qt_metacast(const char *_clname)
256 {
257  if (!_clname) return 0;
258  if (!strcmp(_clname, "QDBusInterface"))
259  return static_cast<void*>(const_cast<QDBusInterface*>(this));
260  if (d_func()->interface.toLatin1() == _clname)
261  return static_cast<void*>(const_cast<QDBusInterface*>(this));
262  return QDBusAbstractInterface::qt_metacast(_clname);
263 }
264 
273 {
274  _id = QDBusAbstractInterface::qt_metacall(_c, _id, _a);
275  if (_id < 0 || !d_func()->isValid || !d_func()->metaObject)
276  return _id;
277  return d_func()->metacall(_c, _id, _a);
278 }
279 
281 {
283 
285  int offset = metaObject->methodOffset();
286  QMetaMethod mm = metaObject->method(id + offset);
287 
288  if (mm.methodType() == QMetaMethod::Signal) {
289  // signal relay from D-Bus world to Qt world
290  QMetaObject::activate(q, metaObject, id, argv);
291 
292  } else if (mm.methodType() == QMetaMethod::Slot || mm.methodType() == QMetaMethod::Method) {
293  // method call relay from Qt world to D-Bus world
294  // get D-Bus equivalent signature
295  QString methodName = QLatin1String(metaObject->dbusNameForMethod(id));
296  const int *inputTypes = metaObject->inputTypesForMethod(id);
297  int inputTypesCount = *inputTypes;
298 
299  // we will assume that the input arguments were passed correctly
300  QVariantList args;
301  int i = 1;
302  for ( ; i <= inputTypesCount; ++i)
303  args << QVariant(inputTypes[i], argv[i]);
304 
305  // make the call
306  QDBusMessage reply = q->callWithArgumentList(QDBus::Block, methodName, args);
307 
308  if (reply.type() == QDBusMessage::ReplyMessage) {
309  // attempt to demarshall the return values
310  args = reply.arguments();
312  const int *outputTypes = metaObject->outputTypesForMethod(id);
313  int outputTypesCount = *outputTypes++;
314 
315  if (*mm.typeName()) {
316  // this method has a return type
317  if (argv[0] && it != args.constEnd())
318  copyArgument(argv[0], *outputTypes++, *it);
319 
320  // skip this argument even if we didn't copy it
321  --outputTypesCount;
322  ++it;
323  }
324 
325  for (int j = 0; j < outputTypesCount && it != args.constEnd(); ++i, ++j, ++it) {
326  copyArgument(argv[i], outputTypes[j], *it);
327  }
328  }
329 
330  // done
331  lastError = reply;
332  return -1;
333  }
334  }
335  return id;
336 }
337 
339 
340 #endif // QT_NO_DBUS
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
The QMetaObject class contains meta-information about Qt objects.
Definition: qobjectdefs.h:304
unsigned char c[8]
Definition: qnumeric_p.h:62
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
bool isValid() const
Returns true if this is a valid error condition (i.e., if there was an error), otherwise false...
Definition: qdbuserror.cpp:356
#define it(className, varName)
The QDBusArgument class is used to marshall and demarshall D-Bus arguments.
Definition: qdbusargument.h:69
bool isValid() const
Returns true if this is a valid reference to a remote object.
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
static void copyArgument(void *to, int id, const QVariant &arg)
virtual const QMetaObject * metaObject() const
Overrides QObject::metaObject to return our own copy.
The QDBusError class represents an error received from the D-Bus bus or from remote applications foun...
Definition: qdbuserror.h:60
QString toString() const
Returns the variant as a QString if the variant has type() String , Bool , ByteArray ...
Definition: qvariant.cpp:2270
const_iterator constBegin() const
Returns a const STL-style iterator pointing to the first item in the list.
Definition: qlist.h:269
QString currentSignature() const
Returns the type signature of the D-Bus type this QDBusArgument object is currently pointing to...
static const QMetaObject staticMetaObject
This variable stores the meta-object for the class.
Definition: qobject.h:128
The QDBusSignature class enables the programmer to identify the SIGNATURE type provided by the D-Bus ...
The QDBusInterface class is a proxy for interfaces on remote objects.
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
bool toBool() const
Returns the variant as a bool if the variant has type() Bool.
Definition: qvariant.cpp:2691
static int variant
static int objectpath
The QString class provides a Unicode character string.
Definition: qstring.h:83
const char * typeName() const
Returns the return type of this method, or an empty string if the return type is void.
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
QByteArray toByteArray() const
Returns the variant as a QByteArray if the variant has type() ByteArray or String (converted using QS...
Definition: qvariant.cpp:2383
~QDBusInterface()
Destroy the object interface and frees up any resource used.
QDBusError lastError() const
Returns the error the last operation produced, or an invalid error if the last operation did not prod...
#define Q_Q(Class)
Definition: qglobal.h:2483
int toInt(bool *ok=0) const
Returns the variant as an int if the variant has type() Int , Bool , ByteArray , Char ...
Definition: qvariant.cpp:2625
static const char * typeToSignature(int type)
Returns the D-Bus signature equivalent to the supplied meta type id type.
unsigned char uchar
Definition: qglobal.h:994
QStringList toStringList() const
Returns the variant as a QStringList if the variant has type() StringList, String ...
Definition: qvariant.cpp:2259
The QDBusAbstractInterface class is the base class for all D-Bus interfaces in the QtDBus binding...
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
qlonglong toLongLong(bool *ok=0) const
Returns the variant as a long long int if the variant has type() LongLong , Bool , ByteArray , Char , Double , Int , String , UInt , or ULongLong ; otherwise returns 0.
Definition: qvariant.cpp:2659
QList< QVariant > arguments() const
Returns the list of arguments that are going to be sent or were received from D-Bus.
static bool demarshall(const QDBusArgument &, int id, void *data)
Executes the demarshalling of type id (whose data will be placed in data) from the D-Bus marshalling ...
QDBusMetaObject * findMetaObject(const QString &service, const QString &path, const QString &interface, QDBusError &error)
int methodOffset() const
Returns the method offset for this class; i.e.
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
qulonglong toULongLong(bool *ok=0) const
Returns the variant as as an unsigned long long int if the variant has type() ULongLong ...
Definition: qvariant.cpp:2675
unsigned int uint
Definition: qglobal.h:996
QDBusMetaObject * metaObject
MethodType methodType() const
Returns the type of this method (signal, slot, or method).
Q_CORE_EXPORT void qFatal(const char *,...)
int userType() const
Returns the storage type of the value stored in the variant.
Definition: qvariant.cpp:1913
unsigned short ushort
Definition: qglobal.h:995
The QDBusConnection class represents a connection to the D-Bus bus daemon.
static void activate(QObject *sender, int signal_index, void **argv)
Definition: qobject.cpp:3690
const_iterator ConstIterator
Qt-style synonym for QList::const_iterator.
Definition: qlist.h:279
uint toUInt(bool *ok=0) const
Returns the variant as an unsigned int if the variant has type() UInt , Bool , ByteArray ...
Definition: qvariant.cpp:2644
The QDBusObjectPath class enables the programmer to identify the OBJECT_PATH type provided by the D-B...
static QByteArray methodName(const char *signature, int nameLength)
Makes a deep copy of the first nameLength characters of the given method signature and returns the co...
QDBusInterfacePrivate(const QString &serv, const QString &p, const QString &iface, const QDBusConnection &con)
double toDouble(bool *ok=0) const
Returns the variant as a double if the variant has type() Double , QMetaType::Float ...
Definition: qvariant.cpp:2710
int metacall(QMetaObject::Call c, int id, void **argv)
QObject * parent
Definition: qobject.h:92
static int signature
The QDBusMessage class represents one message sent or received over the D-Bus bus.
Definition: qdbusmessage.h:59
MessageType type() const
Returns the message type.
QMetaMethod method(int index) const
Returns the meta-data for the method with the given index.
quint64 qulonglong
Definition: qglobal.h:952
virtual void * qt_metacast(const char *)
Override QObject::qt_metacast to catch the interface name too.
bool isConnected() const
Returns true if this QDBusConnection object is connected.
T value() const
Returns the stored value converted to the template type T.
Definition: qvariant.h:332
static int argument
qint64 qlonglong
Definition: qglobal.h:951
virtual int qt_metacall(QMetaObject::Call, int, void **)
Dispatch the call through the private.
QDBusInterface(QDBusInterfacePrivate *p)
The QMetaMethod class provides meta-data about a member function.
Definition: qmetaobject.h:56
The QDBusVariant class enables the programmer to identify the variant type provided by the D-Bus type...
const_iterator constEnd() const
Returns a const STL-style iterator pointing to the imaginary item after the last item in the list...
Definition: qlist.h:272
QDBusConnectionPrivate * connectionPrivate() const