14using namespace Qt::StringLiterals;
16static void qIterAppend(DBusMessageIter *it, QByteArray *ba,
int type,
const void *arg)
21 q_dbus_message_iter_append_basic(it, type, arg);
29void QDBusMarshaller::unregisteredTypeError(QMetaType id)
31 const char *name = id.name();
32 qWarning(
"QDBusMarshaller: type '%s' (%d) is not registered with D-Bus. "
33 "Use qDBusRegisterMetaType to register it",
34 name ? name :
"", id.id());
35 error(
"Unregistered type %1 passed in arguments"_L1
36 .arg(QLatin1StringView(id.name())));
42 return QString::fromUtf8(q_dbus_message_get_signature(message));
46inline void QDBusMarshaller::
append(uchar arg)
52inline void QDBusMarshaller::
append(
bool arg)
54 dbus_bool_t cast = arg;
59inline void QDBusMarshaller::
append(
short arg)
65inline void QDBusMarshaller::
append(ushort arg)
71inline void QDBusMarshaller::
append(
int arg)
77inline void QDBusMarshaller::
append(uint arg)
83inline void QDBusMarshaller::
append(qlonglong arg)
89inline void QDBusMarshaller::
append(qulonglong arg)
95inline void QDBusMarshaller::
append(
double arg)
101void QDBusMarshaller::
append(
const QString &arg)
103 QByteArray data = arg.toUtf8();
104 const char *cdata = data.constData();
109inline void QDBusMarshaller::
append(
const QDBusObjectPath &arg)
111 QByteArray data = arg.path().toUtf8();
112 if (!ba && data.isEmpty()) {
113 error(
"Invalid object path passed in arguments"_L1);
115 const char *cdata = data.constData();
121inline void QDBusMarshaller::
append(
const QDBusSignature &arg)
123 QByteArray data = arg.signature().toUtf8();
124 if (!ba && data.isNull()) {
125 error(
"Invalid signature passed in arguments"_L1);
127 const char *cdata = data.constData();
133inline void QDBusMarshaller::
append(
const QDBusUnixFileDescriptor &arg)
135 int fd = arg.fileDescriptor();
136 if (!ba && fd == -1) {
137 error(
"Invalid file descriptor passed in arguments"_L1);
144inline void QDBusMarshaller::
append(
const QByteArray &arg)
152 const char* cdata = arg.constData();
153 DBusMessageIter subiterator;
156 q_dbus_message_iter_append_fixed_array(&subiterator,
DBUS_TYPE_BYTE, &cdata, arg.size());
157 q_dbus_message_iter_close_container(&iterator, &subiterator);
168 const QVariant &value = arg.variant();
169 QMetaType id = value.metaType();
171 qWarning(
"QDBusMarshaller: cannot add a null QDBusVariant");
172 error(
"Invalid QVariant passed in arguments"_L1);
176 QByteArray tmpSignature;
177 const char *signature =
nullptr;
178 if (id == QDBusMetaTypeId::argument()) {
181 qvariant_cast<
QDBusArgument>(value).currentSignature().toLatin1();
182 signature = tmpSignature.constData();
185 signature = QDBusMetaType::typeToSignature(id);
188 unregisteredTypeError(id);
192 QDBusMarshaller sub(capabilities);
194 bool isOk = sub.appendVariantInternal(value);
200inline void QDBusMarshaller::
append(
const QStringList &arg)
208 QDBusMarshaller sub(capabilities);
210 for (
const QString &s : arg)
220inline QDBusMarshaller *QDBusMarshaller::
beginArray(QMetaType id)
222 const char *signature = QDBusMetaType::typeToSignature(id);
224 unregisteredTypeError(id);
231inline QDBusMarshaller *QDBusMarshaller::
beginMap(QMetaType kid, QMetaType vid)
233 const char *ksignature = QDBusMetaType::typeToSignature(kid);
235 unregisteredTypeError(kid);
240QT_WARNING_DISABLE_GCC(
"-Wformat-overflow")
241 qWarning(
"QDBusMarshaller: type '%s' (%d) cannot be used as the key type in a D-Bus map.",
242 kid.name(), kid.id());
244 error(
"Type %1 passed in arguments cannot be used as a key in a map"_L1
245 .arg(QLatin1StringView(kid.name())));
249 const char *vsignature = QDBusMetaType::typeToSignature(vid);
251 unregisteredTypeError(vid);
255 QByteArray signature;
257 signature += ksignature;
258 signature += vsignature;
268void QDBusMarshaller::
open(QDBusMarshaller &sub,
int code,
const char *signature)
273 sub.capabilities = capabilities;
296 q_dbus_message_iter_open_container(&iterator, code, signature, &sub.iterator);
300QDBusMarshaller *QDBusMarshaller::
beginCommon(
int code,
const char *signature)
302 QDBusMarshaller *d =
new QDBusMarshaller(capabilities);
313inline QDBusMarshaller *QDBusMarshaller::
endMap()
321 QDBusMarshaller *retval =
parent;
329 if (!skipSignature && closeCode)
332 q_dbus_message_iter_close_container(&parent->iterator, &iterator);
336void QDBusMarshaller::
error(
const QString &msg)
347 QMetaType id = arg.metaType();
349 qWarning(
"QDBusMarshaller: cannot add an invalid QVariant");
350 error(
"Invalid QVariant passed in arguments"_L1);
355 if (id == QDBusMetaTypeId::argument()) {
356 QDBusArgument dbusargument = qvariant_cast<QDBusArgument>(arg);
362 demarshaller.message = q_dbus_message_ref(d->message);
364 if (d->direction == Direction::Demarshalling) {
369 if (!q_dbus_message_iter_init(demarshaller.message, &demarshaller.iterator))
376 const char *signature = QDBusMetaType::typeToSignature(id);
378 unregisteredTypeError(id);
382 switch (*signature) {
385 case DBUS_TYPE_INT16:
386 case DBUS_TYPE_UINT16:
387 case DBUS_TYPE_INT32:
388 case DBUS_TYPE_UINT32:
389 case DBUS_TYPE_INT64:
390 case DBUS_TYPE_UINT64:
391 case DBUS_TYPE_DOUBLE:
392 qIterAppend(&iterator, ba, *signature, arg.constData());
394 case DBUS_TYPE_BOOLEAN:
395 append( arg.toBool() );
399 append( qvariant_cast<uchar>(arg) );
402 append( arg.toBool() );
405 append( qvariant_cast<
short>(arg) );
408 append( qvariant_cast<ushort>(arg) );
411 append(
static_cast<dbus_int32_t>(arg.toInt()) );
414 append(
static_cast<dbus_uint32_t>(arg.toUInt()) );
417 append( arg.toLongLong() );
420 append( arg.toULongLong() );
423 append( arg.toDouble() );
428 append( arg.toString() );
440 return append( qvariant_cast<QDBusVariant>(arg) );
445 switch (arg.metaType().id()) {
446 case QMetaType::QStringList:
447 append( arg.toStringList() );
450 case QMetaType::QByteArray:
451 append( arg.toByteArray() );
461 return appendRegisteredType( arg );
465 qFatal(
"QDBusMarshaller::appendVariantInternal got a DICT_ENTRY!");
469 if (capabilities & QDBusConnection::UnixFileDescriptorPassing || ba) {
470 append(qvariant_cast<QDBusUnixFileDescriptor>(arg));
476 qWarning(
"QDBusMarshaller::appendVariantInternal: Found unknown D-Bus type '%s'",
488 return QDBusMetaType::marshall(self, arg.metaType(), arg.constData());
493 int code = q_dbus_message_iter_get_arg_type(&demarshaller->iterator);
500 q_dbus_message_iter_get_basic(&demarshaller->iterator, &value);
501 q_dbus_message_iter_next(&demarshaller->iterator);
502 q_dbus_message_iter_append_basic(&iterator, code, &value);
507 int element = q_dbus_message_iter_get_element_type(&demarshaller->iterator);
512 q_dbus_message_iter_recurse(&demarshaller->iterator, &sub);
513 q_dbus_message_iter_next(&demarshaller->iterator);
516 q_dbus_message_iter_get_fixed_array(&sub,&data,&len);
518 char signature[2] = {
char(element), 0 };
519 q_dbus_message_iter_open_container(&iterator,
DBUS_TYPE_ARRAY, signature, &sub);
520 q_dbus_message_iter_append_fixed_array(&sub, element, &data, len);
521 q_dbus_message_iter_close_container(&iterator, &sub);
530 QDBusMarshaller mrecursed(capabilities);
531 QByteArray subSignature;
532 const char *sig =
nullptr;
534 subSignature = drecursed->currentSignature().toLatin1();
535 if (!subSignature.isEmpty())
536 sig = subSignature.constData();
541 if (!mrecursed.appendCrossMarshalling(drecursed)) {
QDBusDemarshaller * beginCommon()
QDBusArgument::ElementType currentType()
void append(const QString &arg)
QDBusMarshaller * endMapEntry()
QDBusMarshaller * endCommon()
QDBusMarshaller * endStructure()
void open(QDBusMarshaller &sub, int code, const char *signature)
QString currentSignature()
bool appendVariantInternal(const QVariant &arg)
QDBusMarshaller * beginMap(QMetaType kid, QMetaType vid)
QDBusMarshaller * endMap()
QDBusMarshaller * beginCommon(int code, const char *signature)
void append(const QDBusUnixFileDescriptor &arg)
QDBusMarshaller * beginMapEntry()
bool appendRegisteredType(const QVariant &arg)
void error(const QString &message)
QDBusMarshaller * beginStructure()
QDBusMarshaller * beginArray(QMetaType id)
bool appendCrossMarshalling(QDBusDemarshaller *arg)
QDBusMarshaller * endArray()
#define DBUS_TYPE_SIGNATURE
#define DBUS_TYPE_BYTE_AS_STRING
#define DBUS_TYPE_OBJECT_PATH
#define DBUS_TYPE_VARIANT
#define DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
#define DBUS_TYPE_UNIX_FD
#define DBUS_TYPE_BOOLEAN
#define DBUS_STRUCT_BEGIN_CHAR
#define DBUS_TYPE_ARRAY_AS_STRING
#define DBUS_TYPE_STRING_AS_STRING
#define DBUS_TYPE_VARIANT_AS_STRING
#define DBUS_TYPE_DICT_ENTRY
#define DBUS_DICT_ENTRY_BEGIN_CHAR
#define DBUS_DICT_ENTRY_END_CHAR_AS_STRING
#define DBUS_STRUCT_END_CHAR
Q_DBUS_EXPORT bool isValidFixedType(int c)
Returns true if c is a valid, fixed D-Bus type.
Q_DBUS_EXPORT bool isValidBasicType(int c)
Returns true if c is a valid, basic D-Bus type.