static bool qVariantToIteratorInternal(DBusMessageIter *it, const QVariant &var, const QDBusType &type) { switch (type.dbusType()) { case DBUS_TYPE_BYTE: qIterAppend( it, type, QDBusTypeHelper<uchar>::fromVariant(var) ); break; case DBUS_TYPE_BOOLEAN: qIterAppend( it, type, static_cast<dbus_bool_t>(var.toBool()) ); break; case DBUS_TYPE_INT16: qIterAppend( it, type, QDBusTypeHelper<short>::fromVariant(var) ); break; case DBUS_TYPE_UINT16: qIterAppend( it, type, QDBusTypeHelper<ushort>::fromVariant(var) ); break; case DBUS_TYPE_INT32: qIterAppend( it, type, static_cast<dbus_int32_t>(var.toInt()) ); break; case DBUS_TYPE_UINT32: qIterAppend( it, type, static_cast<dbus_uint32_t>(var.toUInt()) ); break; case DBUS_TYPE_INT64: qIterAppend( it, type, static_cast<dbus_int64_t>(var.toLongLong()) ); break; case DBUS_TYPE_UINT64: qIterAppend( it, type, static_cast<dbus_uint64_t>(var.toULongLong()) ); break; case DBUS_TYPE_DOUBLE: qIterAppend( it, type, var.toDouble() ); break; case DBUS_TYPE_STRING: case DBUS_TYPE_OBJECT_PATH: case DBUS_TYPE_SIGNATURE: qIterAppend( it, type, var.toString().toUtf8().constData() ); break; // compound types: case DBUS_TYPE_ARRAY: // could be many things return qAppendArrayToMessage( it, type.arrayElement(), var ); case DBUS_TYPE_VARIANT: return qAppendVariantToMessage( it, type, var ); case DBUS_TYPE_STRUCT: return qAppendStructToMessage( it, type.subTypes(), var.toList() ); case DBUS_TYPE_DICT_ENTRY: qFatal("qVariantToIterator got a DICT_ENTRY!"); return false; default: qWarning("Found unknown DBus type '%s'", type.dbusSignature().constData()); return false; } return true; }
static void qAppendListToMessage(DBusMessageIter *it, const QDBusType &subType, const QVariant &var) { QList<QtType> list = QDBusTypeHelper<QList<QtType> >::fromVariant(var); foreach (const QtType &item, list) qIterAppend(it, subType, static_cast<DBusType>(item)); }
void QDBusMarshaller::append(const QString &arg) { QByteArray data = arg.toUtf8(); const char *cdata = data.constData(); if (!skipSignature) qIterAppend(&iterator, ba, DBUS_TYPE_STRING, &cdata); }
inline void QDBusMarshaller::append(const QDBusSignature &arg) { QByteArray data = arg.signature().toUtf8(); if (!ba && data.isEmpty()) error(); const char *cdata = data.constData(); qIterAppend(&iterator, ba, DBUS_TYPE_SIGNATURE, &cdata); }
inline void QDBusMarshaller::append(const QDBusObjectPath &arg) { QByteArray data = arg.path().toUtf8(); if (!ba && data.isEmpty()) error(QLatin1String("Invalid object path passed in arguments")); const char *cdata = data.constData(); qIterAppend(&iterator, ba, DBUS_TYPE_OBJECT_PATH, &cdata); }
inline void QDBusMarshaller::append(const QDBusSignature &arg) { QByteArray data = arg.signature().toUtf8(); if (!ba && data.isEmpty()) error(QLatin1String("Invalid signature passed in arguments")); const char *cdata = data.constData(); qIterAppend(&iterator, ba, DBUS_TYPE_SIGNATURE, &cdata); }
inline void QDBusMarshaller::append(const QDBusObjectPath &arg) { QByteArray data = arg.path().toUtf8(); if (!ba && data.isEmpty()) error(); const char *cdata = data.constData(); qIterAppend(&iterator, ba, DBUS_TYPE_OBJECT_PATH, &cdata); }
inline void QDBusMarshaller::append(const QDBusUnixFileDescriptor &arg) { int fd = arg.fileDescriptor(); if (!ba && fd == -1) { error(QLatin1String("Invalid file descriptor passed in arguments")); } else { qIterAppend(&iterator, ba, DBUS_TYPE_UNIX_FD, &fd); } }
bool QDBusMarshaller::appendVariantInternal(const QVariant &arg) { int id = arg.userType(); if (id == QVariant::Invalid) { qWarning("QDBusMarshaller: cannot add an invalid QVariant"); error(QLatin1String("Variant containing QVariant::Invalid passed in arguments")); return false; } // intercept QDBusArgument parameters here if (id == QDBusMetaTypeId::argument()) { QDBusArgument dbusargument = qvariant_cast<QDBusArgument>(arg); QDBusArgumentPrivate *d = QDBusArgumentPrivate::d(dbusargument); if (!d->message) return false; // can't append this one... QDBusDemarshaller demarshaller(capabilities); demarshaller.message = q_dbus_message_ref(d->message); if (d->direction == Demarshalling) { // it's demarshalling; just copy demarshaller.iterator = static_cast<QDBusDemarshaller *>(d)->iterator; } else { // it's marshalling; start over if (!q_dbus_message_iter_init(demarshaller.message, &demarshaller.iterator)) return false; // error! } return appendCrossMarshalling(&demarshaller); } const char *signature = QDBusMetaType::typeToSignature( QVariant::Type(id) ); if (!signature) { qWarning("QDBusMarshaller: type `%s' (%d) is not registered with D-BUS. " "Use qDBusRegisterMetaType to register it", QMetaType::typeName(id), id); error(QString::fromLatin1("Unregistered type %1 passed in arguments") .arg(QLatin1String(QMetaType::typeName(id)))); return false; } switch (*signature) { #ifdef __OPTIMIZE__ case DBUS_TYPE_BYTE: case DBUS_TYPE_INT16: case DBUS_TYPE_UINT16: case DBUS_TYPE_INT32: case DBUS_TYPE_UINT32: case DBUS_TYPE_INT64: case DBUS_TYPE_UINT64: case DBUS_TYPE_DOUBLE: qIterAppend(&iterator, ba, *signature, arg.constData()); return true; case DBUS_TYPE_BOOLEAN: append( arg.toBool() ); return true; #else case DBUS_TYPE_BYTE: append( qvariant_cast<uchar>(arg) ); return true; case DBUS_TYPE_BOOLEAN: append( arg.toBool() ); return true; case DBUS_TYPE_INT16: append( qvariant_cast<short>(arg) ); return true; case DBUS_TYPE_UINT16: append( qvariant_cast<ushort>(arg) ); return true; case DBUS_TYPE_INT32: append( static_cast<dbus_int32_t>(arg.toInt()) ); return true; case DBUS_TYPE_UINT32: append( static_cast<dbus_uint32_t>(arg.toUInt()) ); return true; case DBUS_TYPE_INT64: append( arg.toLongLong() ); return true; case DBUS_TYPE_UINT64: append( arg.toULongLong() ); return true; case DBUS_TYPE_DOUBLE: append( arg.toDouble() ); return true; #endif case DBUS_TYPE_STRING: append( arg.toString() ); return true; case DBUS_TYPE_OBJECT_PATH: append( qvariant_cast<QDBusObjectPath>(arg) ); return true; case DBUS_TYPE_SIGNATURE: append( qvariant_cast<QDBusSignature>(arg) ); return true; // compound types: case DBUS_TYPE_VARIANT: // nested QVariant return append( qvariant_cast<QDBusVariant>(arg) ); case DBUS_TYPE_ARRAY: // could be many things // find out what kind of array it is switch (arg.type()) { case QVariant::StringList: append( arg.toStringList() ); return true; case QVariant::ByteArray: append( arg.toByteArray() ); return true; default: ; } Q_FALLTHROUGH(); case DBUS_TYPE_STRUCT: case DBUS_STRUCT_BEGIN_CHAR: return appendRegisteredType( arg ); case DBUS_TYPE_DICT_ENTRY: case DBUS_DICT_ENTRY_BEGIN_CHAR: qFatal("QDBusMarshaller::appendVariantInternal got a DICT_ENTRY!"); return false; case DBUS_TYPE_UNIX_FD: if (capabilities & QDBusConnection::UnixFileDescriptorPassing || ba) { append(qvariant_cast<QDBusUnixFileDescriptor>(arg)); return true; } Q_FALLTHROUGH(); default: qWarning("QDBusMarshaller::appendVariantInternal: Found unknown D-BUS type '%s'", signature); return false; } return true; }
inline void QDBusMarshaller::append(double arg) { if (!skipSignature) qIterAppend(&iterator, ba, DBUS_TYPE_DOUBLE, &arg); }
inline void QDBusMarshaller::append(qulonglong arg) { if (!skipSignature) qIterAppend(&iterator, ba, DBUS_TYPE_UINT64, &arg); }
inline void QDBusMarshaller::append(qulonglong arg) { qIterAppend(&iterator, ba, DBUS_TYPE_UINT64, &arg); }
inline void QDBusMarshaller::append(uint arg) { qIterAppend(&iterator, ba, DBUS_TYPE_UINT32, &arg); }
inline void QDBusMarshaller::append(short arg) { if (!skipSignature) qIterAppend(&iterator, ba, DBUS_TYPE_INT16, &arg); }
inline void QDBusMarshaller::append(uchar arg) { if (!skipSignature) qIterAppend(&iterator, ba, DBUS_TYPE_BYTE, &arg); }
inline void QDBusMarshaller::append(double arg) { qIterAppend(&iterator, ba, DBUS_TYPE_DOUBLE, &arg); }
static bool qAppendArrayToMessage(DBusMessageIter *it, const QDBusType &subType, const QVariant &var) { bool ok = false; DBusMessageIter sub; dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, subType.dbusSignature(), &sub); switch (var.type()) { case QVariant::StringList: { const QStringList list = var.toStringList(); foreach (QString str, list) qIterAppend(&sub, subType, str.toUtf8().constData()); ok = true; break; } case QVariant::ByteArray: { const QByteArray array = var.toByteArray(); const char* cdata = array.constData(); dbus_message_iter_append_fixed_array(&sub, DBUS_TYPE_BYTE, &cdata, array.length()); ok = true; break; } case QVariant::Map: { const QVariantMap map = var.toMap(); const QDBusTypeList& subTypes = subType.subTypes(); ok = true; for (QMap<QString, QVariant>::const_iterator mit = map.constBegin(); ok && mit != map.constEnd(); ++mit) { DBusMessageIter itemIterator; dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, 0, &itemIterator); // let the string be converted to QVariant if (!qVariantToIteratorInternal(&itemIterator, mit.key(), subTypes[0])) ok = false; else if (!qVariantToIteratorInternal(&itemIterator, mit.value(), subTypes[1])) ok = false; dbus_message_iter_close_container(&sub, &itemIterator); } break; } case QVariant::List: { const QVariantList list = var.toList(); ok = true; foreach (QVariant v, list) if (!qVariantToIteratorInternal(&sub, v, subType)) { ok = false; break; } break; } default: { int id = var.userType(); ok = true; if (id == QDBusTypeHelper<bool>::listId()) qAppendListToMessage<dbus_bool_t,bool>(&sub, subType, var); else if (id == QDBusTypeHelper<short>::listId()) qAppendListToMessage<dbus_int16_t,short>(&sub, subType, var); else if (id == QDBusTypeHelper<ushort>::listId()) qAppendListToMessage<dbus_uint16_t,ushort>(&sub, subType, var); else if (id == QDBusTypeHelper<int>::listId()) qAppendListToMessage<dbus_int32_t,int>(&sub, subType, var); else if (id == QDBusTypeHelper<uint>::listId()) qAppendListToMessage<dbus_uint32_t,uint>(&sub, subType, var); else if (id == QDBusTypeHelper<qlonglong>::listId()) qAppendListToMessage<dbus_int64_t,qlonglong>(&sub, subType, var); else if (id == QDBusTypeHelper<qulonglong>::listId()) qAppendListToMessage<dbus_uint64_t,qulonglong>(&sub, subType, var); else if (id == QDBusTypeHelper<double>::listId()) qAppendListToMessage<double,double>(&sub, subType, var); #if 0 // never reached, since QVariant::List mached else if (id == QDBusTypeHelper<QVariant>::listId()) qAppendListToMessage<QVariant,QVariant>(&sub, subType, var); #endif else { qFatal("qAppendArrayToMessage got unknown type!"); ok = false; } break; } } dbus_message_iter_close_container(it, &sub); return ok; }
inline void QDBusMarshaller::append(bool arg) { dbus_bool_t cast = arg; if (!skipSignature) qIterAppend(&iterator, ba, DBUS_TYPE_BOOLEAN, &cast); }
inline void QDBusMarshaller::append(uchar arg) { qIterAppend(&iterator, ba, DBUS_TYPE_BYTE, &arg); }
inline void QDBusMarshaller::append(uint arg) { if (!skipSignature) qIterAppend(&iterator, ba, DBUS_TYPE_UINT32, &arg); }
inline void QDBusMarshaller::append(short arg) { qIterAppend(&iterator, ba, DBUS_TYPE_INT16, &arg); }