Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qdbusinterface.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qdbusinterface.h"
5#include "qdbusinterface_p.h"
6
7#include "qdbus_symbols_p.h"
8#include <QtCore/qpointer.h>
9#include <QtCore/qstringlist.h>
10
11#include "qdbusmetatype_p.h"
12#include "qdbusconnection_p.h"
13
14#ifndef QT_NO_DBUS
15
17
18using namespace Qt::StringLiterals;
19
20static void copyArgument(void *to, int id, const QVariant &arg)
21{
22 if (id == arg.metaType().id()) {
23 switch (id) {
24 case QMetaType::Bool:
25 *reinterpret_cast<bool *>(to) = arg.toBool();
26 return;
27
28 case QMetaType::UChar:
29 *reinterpret_cast<uchar *>(to) = qvariant_cast<uchar>(arg);
30 return;
31
32 case QMetaType::Short:
33 *reinterpret_cast<short *>(to) = qvariant_cast<short>(arg);
34 return;
35
36 case QMetaType::UShort:
37 *reinterpret_cast<ushort *>(to) = qvariant_cast<ushort>(arg);
38 return;
39
40 case QMetaType::Int:
41 *reinterpret_cast<int *>(to) = arg.toInt();
42 return;
43
44 case QMetaType::UInt:
45 *reinterpret_cast<uint *>(to) = arg.toUInt();
46 return;
47
48 case QMetaType::LongLong:
49 *reinterpret_cast<qlonglong *>(to) = arg.toLongLong();
50 return;
51
52 case QMetaType::ULongLong:
53 *reinterpret_cast<qulonglong *>(to) = arg.toULongLong();
54 return;
55
56 case QMetaType::Double:
57 *reinterpret_cast<double *>(to) = arg.toDouble();
58 return;
59
60 case QMetaType::QString:
61 *reinterpret_cast<QString *>(to) = arg.toString();
62 return;
63
64 case QMetaType::QByteArray:
65 *reinterpret_cast<QByteArray *>(to) = arg.toByteArray();
66 return;
67
68 case QMetaType::QStringList:
69 *reinterpret_cast<QStringList *>(to) = arg.toStringList();
70 return;
71 }
72
73 if (id == QDBusMetaTypeId::variant().id()) {
74 *reinterpret_cast<QDBusVariant *>(to) = qvariant_cast<QDBusVariant>(arg);
75 return;
76 } else if (id == QDBusMetaTypeId::objectpath().id()) {
77 *reinterpret_cast<QDBusObjectPath *>(to) = qvariant_cast<QDBusObjectPath>(arg);
78 return;
79 } else if (id == QDBusMetaTypeId::signature().id()) {
80 *reinterpret_cast<QDBusSignature *>(to) = qvariant_cast<QDBusSignature>(arg);
81 return;
82 }
83
84 // those above are the only types possible
85 // the demarshaller code doesn't demarshall anything else
86 qFatal("Found a decoded basic type in a D-Bus reply that shouldn't be there");
87 }
88
89 // if we got here, it's either an un-dermarshalled type or a mismatch
90 if (arg.metaType() != QDBusMetaTypeId::argument()) {
91 // it's a mismatch
92 //qWarning?
93 return;
94 }
95
96 // is this type registered?
97 const char *userSignature = QDBusMetaType::typeToSignature(QMetaType(id));
98 if (!userSignature || !*userSignature) {
99 // type not registered
100 //qWarning?
101 return;
102 }
103
104 // is it the same signature?
105 QDBusArgument dbarg = qvariant_cast<QDBusArgument>(arg);
106 if (dbarg.currentSignature() != QLatin1StringView(userSignature)) {
107 // not the same signature, another mismatch
108 //qWarning?
109 return;
110 }
111
112 // we can demarshall
113 QDBusMetaType::demarshall(dbarg, QMetaType(id), to);
114}
115
117 const QString &iface, const QDBusConnection &con)
118 : QDBusAbstractInterfacePrivate(serv, p, iface, con, true), metaObject(nullptr)
119{
120 // QDBusAbstractInterfacePrivate's constructor checked the parameters for us
121 if (connection.isConnected()) {
123
124 if (!metaObject) {
125 // creation failed, somehow
126 // most common causes are that the service doesn't exist or doesn't support introspection
127 // those are not fatal errors, so we continue working
128
129 if (!lastError.isValid())
130 lastError = QDBusError(QDBusError::InternalError, "Unknown error"_L1);
131 }
132 }
133}
134
136{
138 delete metaObject;
139}
140
141
184QDBusInterface::QDBusInterface(const QString &service, const QString &path, const QString &interface,
187 parent)
188{
189}
190
195{
196 // resources are freed in QDBusInterfacePrivate::~QDBusInterfacePrivate()
197}
198
204{
205 return d_func()->metaObject ? d_func()->metaObject : &QDBusAbstractInterface::staticMetaObject;
206}
207
212void *QDBusInterface::qt_metacast(const char *_clname)
213{
214 if (!_clname) return nullptr;
215 if (!strcmp(_clname, "QDBusInterface"))
216 return static_cast<void*>(const_cast<QDBusInterface*>(this));
217 if (d_func()->interface.toLatin1() == _clname)
218 return static_cast<void*>(const_cast<QDBusInterface*>(this));
219 return QDBusAbstractInterface::qt_metacast(_clname);
220}
221
227{
228 _id = QDBusAbstractInterface::qt_metacall(_c, _id, _a);
229 if (_id < 0 || !d_func()->isValid || !d_func()->metaObject)
230 return _id;
231 return d_func()->metacall(_c, _id, _a);
232}
233
235{
236 Q_Q(QDBusInterface);
237
241
242 if (mm.methodType() == QMetaMethod::Signal) {
243 // signal relay from D-Bus world to Qt world
245
246 } else if (mm.methodType() == QMetaMethod::Slot || mm.methodType() == QMetaMethod::Method) {
247 // method call relay from Qt world to D-Bus world
248 // get D-Bus equivalent signature
250 const int *inputTypes = metaObject->inputTypesForMethod(id);
251 int inputTypesCount = *inputTypes;
252
253 // we will assume that the input arguments were passed correctly
255 args.reserve(inputTypesCount);
256 int i = 1;
257 for ( ; i <= inputTypesCount; ++i)
258 args << QVariant(QMetaType(inputTypes[i]), argv[i]);
259
260 // make the call
261 QDBusMessage reply = q->callWithArgumentList(QDBus::Block, methodName, args);
262
263 if (reply.type() == QDBusMessage::ReplyMessage) {
264 // attempt to demarshall the return values
265 args = reply.arguments();
267 const int *outputTypes = metaObject->outputTypesForMethod(id);
268 int outputTypesCount = *outputTypes++;
269
270 if (mm.returnType() != QMetaType::UnknownType && mm.returnType() != QMetaType::Void) {
271 // this method has a return type
272 if (argv[0] && it != args.constEnd())
273 copyArgument(argv[0], *outputTypes++, *it);
274
275 // skip this argument even if we didn't copy it
276 --outputTypesCount;
277 ++it;
278 }
279
280 for (int j = 0; j < outputTypesCount && it != args.constEnd(); ++i, ++j, ++it) {
281 copyArgument(argv[i], outputTypes[j], *it);
282 }
283 }
284
285 // done
287 return -1;
288 }
289 }
290 return id;
291}
292
294
295#endif // QT_NO_DBUS
\inmodule QtCore
Definition qbytearray.h:57
int qt_metacall(QMetaObject::Call, int, void **) override
QDBusConnectionPrivate * connectionPrivate() const
bool isValid() const
Returns true if this is a valid reference to a remote object.
\inmodule QtDBus
QString currentSignature() const
QDBusMetaObject * findMetaObject(const QString &service, const QString &path, const QString &interface, QDBusError &error)
\inmodule QtDBus
bool isConnected() const
Returns true if this QDBusConnection object is connected.
\inmodule QtDBus
Definition qdbuserror.h:21
bool isValid() const
Returns true if this is a valid error condition (i.e., if there was an error), otherwise false.
int metacall(QMetaObject::Call c, int id, void **argv)
QDBusMetaObject * metaObject
QDBusInterfacePrivate(const QString &serv, const QString &p, const QString &iface, const QDBusConnection &con)
\inmodule QtDBus
virtual int qt_metacall(QMetaObject::Call, int, void **) override
virtual const QMetaObject * metaObject() const override
~QDBusInterface()
Destroy the object interface and frees up any resource used.
virtual void * qt_metacast(const char *) override
\inmodule QtDBus
static bool demarshall(const QDBusArgument &, QMetaType id, void *data)
static const char * typeToSignature(QMetaType type)
\inmodule QtDBus
\inmodule QtDBus
\inmodule QtDBus
const_iterator constBegin() const noexcept
Definition qlist.h:615
void reserve(qsizetype size)
Definition qlist.h:746
const_iterator constEnd() const noexcept
Definition qlist.h:616
const_iterator ConstIterator
Definition qlist.h:251
\inmodule QtCore
Definition qmetaobject.h:18
int returnType() const
MethodType methodType() const
Returns the type of this method (signal, slot, or method).
QByteArray name() const
\inmodule QtCore
Definition qmetatype.h:320
int id(int=0) const
Definition qmetatype.h:454
\inmodule QtCore
Definition qobject.h:90
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5710
\inmodule QtCore
Definition qvariant.h:64
QSet< QString >::iterator it
QMetaType variant()
QMetaType argument()
QMetaType objectpath()
QMetaType signature()
Combined button and popup list for selecting options.
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char * interface
DBusConnection * connection
static void copyArgument(void *to, int id, const QVariant &arg)
static QString methodName(const QDBusIntrospection::Method &method)
#define qFatal
Definition qlogging.h:164
GLenum GLuint id
[7]
GLenum GLuint GLintptr offset
const GLubyte * c
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLsizei const GLchar *const * path
GLfloat GLfloat p
[1]
SSL_CTX int(*) void arg)
unsigned char uchar
Definition qtypes.h:27
quint64 qulonglong
Definition qtypes.h:59
unsigned int uint
Definition qtypes.h:29
unsigned short ushort
Definition qtypes.h:28
qint64 qlonglong
Definition qtypes.h:58
obj metaObject() -> className()
QObject::connect nullptr
QNetworkReply * reply
QJSValueList args
const int * outputTypesForMethod(int id) const
const int * inputTypesForMethod(int id) const
\inmodule QtCore
int methodOffset() const
Returns the method offset for this class; i.e.
QMetaMethod method(int index) const
Returns the meta-data for the method with the given index.
static void activate(QObject *sender, int signal_index, void **argv)
Definition qobject.cpp:4057
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent