Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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:
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
57 message().registerType();
58 argument().registerType();
59 variant().registerType();
62 error().registerType();
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
82 qDBusRegisterMetaType<QList<bool> >();
83 qDBusRegisterMetaType<QList<short> >();
84 qDBusRegisterMetaType<QList<ushort> >();
85 qDBusRegisterMetaType<QList<int> >();
86 qDBusRegisterMetaType<QList<uint> >();
87 qDBusRegisterMetaType<QList<qlonglong> >();
88 qDBusRegisterMetaType<QList<qulonglong> >();
89 qDBusRegisterMetaType<QList<double> >();
90
91 // plus lists of our own types
92 qDBusRegisterMetaType<QList<QDBusVariant> >();
93 qDBusRegisterMetaType<QList<QDBusObjectPath> >();
94 qDBusRegisterMetaType<QList<QDBusSignature> >();
95 qDBusRegisterMetaType<QList<QDBusUnixFileDescriptor> >();
96#endif
97
98 initialized.storeRelaxed(true);
99 }
100}
101
103{
105 QHash<int, QDBusCustomTypeInfo> hash;
106};
107
109
110
185void QDBusMetaType::registerMarshallOperators(QMetaType metaType, MarshallFunction mf,
186 DemarshallFunction df)
187{
188 int id = metaType.id();
189 if (id < 0 || !mf || !df)
190 return; // error!
191
192 auto *ct = customTypes();
193 if (!ct)
194 return;
195
196 QWriteLocker locker(&ct->lock);
197 QDBusCustomTypeInfo &info = ct->hash[id];
198 info.marshall = mf;
199 info.demarshall = df;
200}
201
209{
210 auto *ct = customTypes();
211 if (!ct)
212 return false;
213
214 int id = metaType.id();
216
218 {
219 QReadLocker locker(&ct->lock);
220
221 auto it = ct->hash.constFind(id);
222 if (it == ct->hash.cend())
223 return false; // non-existent
224
225 const QDBusCustomTypeInfo &info = *it;
226 if (!info.marshall) {
227 mf = nullptr; // make gcc happy
228 return false;
229 } else
230 mf = info.marshall;
231 }
232
233 mf(arg, data);
234 return true;
235}
236
244{
245 auto *ct = customTypes();
246 if (!ct)
247 return false;
248
249 int id = metaType.id();
251
253 {
254 QReadLocker locker(&ct->lock);
255
256 auto it = ct->hash.constFind(id);
257 if (it == ct->hash.cend())
258 return false; // non-existent
259
260 const QDBusCustomTypeInfo &info = *it;
261 if (!info.demarshall) {
262 df = nullptr; // make gcc happy
263 return false;
264 } else
265 df = info.demarshall;
266 }
267#ifndef QT_BOOTSTRAPPED
269 df(copy, data);
270#else
271 Q_UNUSED(arg);
272 Q_UNUSED(data);
273 Q_UNUSED(df);
274#endif
275 return true;
276}
277
291{
292 if (!signature)
294
296 switch (signature[0])
297 {
299 return QMetaType(QMetaType::Bool);
300
301 case DBUS_TYPE_BYTE:
302 return QMetaType(QMetaType::UChar);
303
304 case DBUS_TYPE_INT16:
305 return QMetaType(QMetaType::Short);
306
307 case DBUS_TYPE_UINT16:
308 return QMetaType(QMetaType::UShort);
309
310 case DBUS_TYPE_INT32:
311 return QMetaType(QMetaType::Int);
312
313 case DBUS_TYPE_UINT32:
314 return QMetaType(QMetaType::UInt);
315
316 case DBUS_TYPE_INT64:
317 return QMetaType(QMetaType::LongLong);
318
319 case DBUS_TYPE_UINT64:
320 return QMetaType(QMetaType::ULongLong);
321
322 case DBUS_TYPE_DOUBLE:
323 return QMetaType(QMetaType::Double);
324
325 case DBUS_TYPE_STRING:
326 return QMetaType(QMetaType::QString);
327
330
333
336
339
340 case DBUS_TYPE_ARRAY: // special case
341 switch (signature[1]) {
342 case DBUS_TYPE_BYTE:
343 return QMetaType(QMetaType::QByteArray);
344
345 case DBUS_TYPE_STRING:
346 return QMetaType(QMetaType::QStringList);
347
349 return QMetaType(QMetaType::QVariantList);
350
352 return QMetaType::fromType<QList<QDBusObjectPath> >();
353
355 return QMetaType::fromType<QList<QDBusSignature> >();
356
357 }
359 default:
361 }
362}
363
373{
374 auto *ct = customTypes();
375 if (!ct)
376 return;
377
378 QWriteLocker locker(&ct->lock);
379 auto &info = ct->hash[type.id()];
380 info.signature = signature;
381 // note how marshall/demarshall are not set, the type is never used at runtime
382}
383
396{
397 // check if it's a static type
398 switch (type.id())
399 {
400 case QMetaType::UChar:
402
403 case QMetaType::Bool:
405
406 case QMetaType::Short:
408
409 case QMetaType::UShort:
411
412 case QMetaType::Int:
414
415 case QMetaType::UInt:
417
418 case QMetaType::LongLong:
420
421 case QMetaType::ULongLong:
423
424 case QMetaType::Double:
426
427 case QMetaType::QString:
429
430 case QMetaType::QStringList:
433
434 case QMetaType::QByteArray:
437 }
438
442 else if (type == QDBusMetaTypeId::objectpath())
444 else if (type == QDBusMetaTypeId::signature())
446 else if (type == QDBusMetaTypeId::unixfd())
448
449 // try the database
450 auto *ct = customTypes();
451 if (!ct)
452 return nullptr;
453
454 {
455 QReadLocker locker(&ct->lock);
456 auto it = ct->hash.constFind(type.id());
457 if (it == ct->hash.end())
458 return nullptr;
459
460 const QDBusCustomTypeInfo &info = *it;
461
462 if (!info.signature.isNull())
463 return info.signature;
464
465 if (!info.marshall)
466 return nullptr; // type not registered with us
467 }
468
469 // call to user code to construct the signature type
471 {
472 // createSignature will never return a null QByteArray
473 // if there was an error, it'll return ""
475
476 // re-acquire lock
477 QWriteLocker locker(&ct->lock);
478 info = &ct->hash[type.id()];
479 info->signature = signature;
480 }
481 return info->signature;
482}
483
485
486#endif // QT_NO_DBUS
\inmodule QtCore
Definition qbytearray.h:57
static QByteArray createSignature(QMetaType type)
\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 qmetatype.h:341
int id(int=0) const
Definition qmetatype.h:475
void registerType() const
Definition qmetatype.h:465
\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
Q_DBUS_EXPORT void init()
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]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum type
GLuint GLsizei const GLchar * message
SSL_CTX int void * arg
#define Q_UNUSED(x)
QObject::connect nullptr
QVariant variant
[1]
QHostInfo info
[0]
QDBusArgument argument
QReadWriteLock lock
QHash< int, QDBusCustomTypeInfo > hash