Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qdbusmetatype.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 "qdbusmetatype.h"
5#include "qdbusmetatype_p.h"
6
7#include <string.h>
8#include "qdbus_symbols_p.h"
9
10#include <qbytearray.h>
11#include <qglobal.h>
12#include <qlist.h>
13#include <qreadwritelock.h>
14#include <qdatetime.h>
15#include <qrect.h>
16#include <qsize.h>
17#include <qpoint.h>
18#include <qline.h>
19
20#include "qdbusargument_p.h"
21#include "qdbusutil_p.h"
23#ifndef QT_BOOTSTRAPPED
24#include "qdbusmessage.h"
25#endif
26
27#ifndef QT_NO_DBUS
28
29#ifndef DBUS_TYPE_UNIX_FD
30# define DBUS_TYPE_UNIX_FD int('h')
31# define DBUS_TYPE_UNIX_FD_AS_STRING "h"
32#endif
33
35
37{
38public:
40 { }
41
42 // Suggestion:
43 // change 'signature' to char* and make QDBusCustomTypeInfo a Movable type
47};
48
50{
51 Q_CONSTINIT static QBasicAtomicInt initialized = Q_BASIC_ATOMIC_INITIALIZER(false);
52
53 // reentrancy is not a problem since everything else is locked on their own
54 // set the guard variable at the end
55 if (!initialized.loadRelaxed()) {
56 // register our types with Qt Core (calling qMetaTypeId<T>() does this implicitly)
57 (void)message();
58 (void)argument();
59 (void)variant();
61 (void)signature();
62 (void)error();
63 (void)unixfd();
64
65#ifndef QDBUS_NO_SPECIALTYPES
66 // and register Qt Core's with us
67 qDBusRegisterMetaType<QDate>();
68 qDBusRegisterMetaType<QTime>();
69 qDBusRegisterMetaType<QDateTime>();
70 qDBusRegisterMetaType<QRect>();
71 qDBusRegisterMetaType<QRectF>();
72 qDBusRegisterMetaType<QSize>();
73 qDBusRegisterMetaType<QSizeF>();
74 qDBusRegisterMetaType<QPoint>();
75 qDBusRegisterMetaType<QPointF>();
76 qDBusRegisterMetaType<QLine>();
77 qDBusRegisterMetaType<QLineF>();
78 qDBusRegisterMetaType<QVariantList>();
79 qDBusRegisterMetaType<QVariantMap>();
80 qDBusRegisterMetaType<QVariantHash>();
81 qDBusRegisterMetaType<QDBusObjectPath>();
82
83 qDBusRegisterMetaType<QList<bool> >();
84 qDBusRegisterMetaType<QList<short> >();
85 qDBusRegisterMetaType<QList<ushort> >();
86 qDBusRegisterMetaType<QList<int> >();
87 qDBusRegisterMetaType<QList<uint> >();
88 qDBusRegisterMetaType<QList<qlonglong> >();
89 qDBusRegisterMetaType<QList<qulonglong> >();
90 qDBusRegisterMetaType<QList<double> >();
91 qDBusRegisterMetaType<QList<QDBusObjectPath> >();
92 qDBusRegisterMetaType<QList<QDBusSignature> >();
93 qDBusRegisterMetaType<QList<QDBusUnixFileDescriptor> >();
94#endif
95
96 initialized.storeRelaxed(true);
97 }
98}
99
102Q_GLOBAL_STATIC(QReadWriteLock, customTypesLock)
103
104
179void QDBusMetaType::registerMarshallOperators(QMetaType metaType, MarshallFunction mf,
180 DemarshallFunction df)
181{
182 int id = metaType.id();
183 auto *ct = customTypes();
184 if (id < 0 || !mf || !df || !ct)
185 return; // error!
186
187 QWriteLocker locker(customTypesLock());
188 QDBusCustomTypeInfo &info = (*ct)[id];
189 info.marshall = mf;
190 info.demarshall = df;
191}
192
200{
201 int id = metaType.id();
203
205 {
206 QReadLocker locker(customTypesLock());
207 auto *ct = customTypes();
208 auto it = ct->constFind(id);
209 if (it == ct->cend())
210 return false; // non-existent
211
212 const QDBusCustomTypeInfo &info = *it;
213 if (!info.marshall) {
214 mf = nullptr; // make gcc happy
215 return false;
216 } else
217 mf = info.marshall;
218 }
219
220 mf(arg, data);
221 return true;
222}
223
231{
232 int id = metaType.id();
234
236 {
237 QReadLocker locker(customTypesLock());
238 auto *ct = customTypes();
239 auto it = ct->constFind(id);
240 if (it == ct->cend())
241 return false; // non-existent
242
243 const QDBusCustomTypeInfo &info = *it;
244 if (!info.demarshall) {
245 df = nullptr; // make gcc happy
246 return false;
247 } else
248 df = info.demarshall;
249 }
250#ifndef QT_BOOTSTRAPPED
252 df(copy, data);
253#else
254 Q_UNUSED(arg);
255 Q_UNUSED(data);
256 Q_UNUSED(df);
257#endif
258 return true;
259}
260
274{
275 if (!signature)
277
279 switch (signature[0])
280 {
282 return QMetaType(QMetaType::Bool);
283
284 case DBUS_TYPE_BYTE:
285 return QMetaType(QMetaType::UChar);
286
287 case DBUS_TYPE_INT16:
288 return QMetaType(QMetaType::Short);
289
290 case DBUS_TYPE_UINT16:
291 return QMetaType(QMetaType::UShort);
292
293 case DBUS_TYPE_INT32:
294 return QMetaType(QMetaType::Int);
295
296 case DBUS_TYPE_UINT32:
297 return QMetaType(QMetaType::UInt);
298
299 case DBUS_TYPE_INT64:
300 return QMetaType(QMetaType::LongLong);
301
302 case DBUS_TYPE_UINT64:
303 return QMetaType(QMetaType::ULongLong);
304
305 case DBUS_TYPE_DOUBLE:
306 return QMetaType(QMetaType::Double);
307
308 case DBUS_TYPE_STRING:
309 return QMetaType(QMetaType::QString);
310
313
316
319
322
323 case DBUS_TYPE_ARRAY: // special case
324 switch (signature[1]) {
325 case DBUS_TYPE_BYTE:
326 return QMetaType(QMetaType::QByteArray);
327
328 case DBUS_TYPE_STRING:
329 return QMetaType(QMetaType::QStringList);
330
332 return QMetaType(QMetaType::QVariantList);
333
335 return QMetaType::fromType<QList<QDBusObjectPath> >();
336
338 return QMetaType::fromType<QList<QDBusSignature> >();
339
340 }
342 default:
344 }
345}
346
356{
357 auto *ct = customTypes();
358 QWriteLocker locker(customTypesLock());
359 auto &info = (*ct)[type.id()];
360 info.signature = signature;
361 // note how marshall/demarshall are not set, the type is never used at runtime
362}
363
376{
377 // check if it's a static type
378 switch (type.id())
379 {
380 case QMetaType::UChar:
382
383 case QMetaType::Bool:
385
386 case QMetaType::Short:
388
389 case QMetaType::UShort:
391
392 case QMetaType::Int:
394
395 case QMetaType::UInt:
397
398 case QMetaType::LongLong:
400
401 case QMetaType::ULongLong:
403
404 case QMetaType::Double:
406
407 case QMetaType::QString:
409
410 case QMetaType::QStringList:
413
414 case QMetaType::QByteArray:
417 }
418
422 else if (type == QDBusMetaTypeId::objectpath())
424 else if (type == QDBusMetaTypeId::signature())
426 else if (type == QDBusMetaTypeId::unixfd())
428
429 // try the database
430 auto *ct = customTypes();
431 {
432 QReadLocker locker(customTypesLock());
433 auto it = ct->constFind(type.id());
434 if (it == ct->end())
435 return nullptr;
436
437 const QDBusCustomTypeInfo &info = *it;
438
439 if (!info.signature.isNull())
440 return info.signature;
441
442 if (!info.marshall)
443 return nullptr; // type not registered with us
444 }
445
446 // call to user code to construct the signature type
448 {
449 // createSignature will never return a null QByteArray
450 // if there was an error, it'll return ""
452
453 // re-acquire lock
454 QWriteLocker locker(customTypesLock());
455 info = &(*ct)[type.id()];
456 info->signature = signature;
457 }
458 return info->signature;
459}
460
462
463#endif // QT_NO_DBUS
\inmodule QtCore
Definition qbytearray.h:57
static QByteArray createSignature(int id)
\inmodule QtDBus
QDBusMetaType::DemarshallFunction demarshall
QDBusMetaType::MarshallFunction marshall
\inmodule QtDBus
static bool demarshall(const QDBusArgument &, QMetaType id, void *data)
static bool marshall(QDBusArgument &, QMetaType id, const void *data)
static QMetaType signatureToMetaType(const char *signature)
static const char * typeToSignature(QMetaType type)
void(* DemarshallFunction)(const QDBusArgument &, void *)
void(* MarshallFunction)(QDBusArgument &, const void *)
static void registerCustomType(QMetaType type, const QByteArray &signature)
\inmodule QtCore
Definition qhash.h:818
\inmodule QtCore
Definition qmetatype.h:320
int id(int=0) const
Definition qmetatype.h:454
\inmodule QtCore
\inmodule QtCore
iterator end()
Definition qset.h:140
const_iterator cend() const noexcept
Definition qset.h:142
const_iterator constFind(const T &value) const
Definition qset.h:161
\inmodule QtCore
#define DBUS_TYPE_UINT64_AS_STRING
#define DBUS_TYPE_UNIX_FD_AS_STRING
#define DBUS_TYPE_BOOLEAN_AS_STRING
#define DBUS_TYPE_INT16_AS_STRING
#define DBUS_TYPE_SIGNATURE
#define DBUS_TYPE_BYTE_AS_STRING
#define DBUS_TYPE_OBJECT_PATH
#define DBUS_TYPE_BYTE
#define DBUS_TYPE_INT64_AS_STRING
#define DBUS_TYPE_DOUBLE_AS_STRING
#define DBUS_TYPE_INT16
#define DBUS_TYPE_VARIANT
#define DBUS_TYPE_INT32
#define DBUS_TYPE_UNIX_FD
#define DBUS_TYPE_INT32_AS_STRING
#define DBUS_TYPE_BOOLEAN
#define DBUS_TYPE_SIGNATURE_AS_STRING
#define DBUS_TYPE_STRING
#define DBUS_TYPE_OBJECT_PATH_AS_STRING
#define DBUS_TYPE_ARRAY
#define DBUS_TYPE_ARRAY_AS_STRING
#define DBUS_TYPE_STRING_AS_STRING
#define DBUS_TYPE_INT64
#define DBUS_TYPE_DOUBLE
#define DBUS_TYPE_UINT64
#define DBUS_TYPE_VARIANT_AS_STRING
#define DBUS_TYPE_UINT16
#define DBUS_TYPE_UINT32_AS_STRING
#define DBUS_TYPE_UINT32
#define DBUS_TYPE_UINT16_AS_STRING
QSet< QString >::iterator it
QMetaType unixfd()
QMetaType variant()
QMetaType objectpath()
QMetaType signature()
Combined button and popup list for selecting options.
static jboolean copy(JNIEnv *, jobject)
#define Q_BASIC_ATOMIC_INITIALIZER(a)
#define Q_FALLTHROUGH()
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 const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
DBusConnection const char DBusError * error
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
GLenum GLuint id
[7]
GLenum type
GLuint GLsizei const GLchar * message
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
SSL_CTX int(*) void arg)
#define Q_UNUSED(x)
QFileInfo info(fileName)
[8]
QObject::connect nullptr
QVariant variant
[1]
QDBusArgument argument