From d42c8663e8fd441838a238bfb845a7c80c37b253 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 28 Mar 2006 18:56:08 +0000 Subject: * qt/*: * dbus/qdbus.h: Sync with KDE Subversion revision 523647. Hopefully, this will be the last of the source-incompatible changes. Documentation has been improved; support for QList has been added; QDBusObject is gone; QDBus(Abstract)Interface is now a QObject with auto-generated meta-object; QDBusIntrospection is marked private, since QMetaObject can be used now; lots of bugfixes. --- qt/qdbusmarshall.cpp | 212 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 152 insertions(+), 60 deletions(-) (limited to 'qt/qdbusmarshall.cpp') diff --git a/qt/qdbusmarshall.cpp b/qt/qdbusmarshall.cpp index eb9493b7..34202154 100644 --- a/qt/qdbusmarshall.cpp +++ b/qt/qdbusmarshall.cpp @@ -23,8 +23,8 @@ */ #include "qdbusmarshall_p.h" -#include "qdbustype.h" -#include "qdbusvariant.h" +#include "qdbustype_p.h" +#include "qdbustypehelper_p.h" #include #include @@ -36,6 +36,8 @@ #include +static QVariant qFetchParameter(DBusMessageIter *it); + template inline T qIterGet(DBusMessageIter *it) { @@ -44,6 +46,32 @@ inline T qIterGet(DBusMessageIter *it) return t; } +template<> +inline QVariant qIterGet(DBusMessageIter *it) +{ + DBusMessageIter sub; + dbus_message_iter_recurse(it, &sub); + return QDBusTypeHelper::toVariant(qFetchParameter(&sub)); +} + +template +inline QVariant qFetchList(DBusMessageIter *arrayIt) +{ + QList list; + + DBusMessageIter it; + dbus_message_iter_recurse(arrayIt, &it); + + if (!dbus_message_iter_has_next(&it)) + return QDBusTypeHelper >::toVariant(list); + + do { + list.append( static_cast( qIterGet(&it) ) ); + } while (dbus_message_iter_next(&it)); + + return QDBusTypeHelper >::toVariant(list); +} + static QStringList qFetchStringList(DBusMessageIter *arrayIt) { QStringList list; @@ -51,6 +79,9 @@ static QStringList qFetchStringList(DBusMessageIter *arrayIt) DBusMessageIter it; dbus_message_iter_recurse(arrayIt, &it); + if (!dbus_message_iter_has_next(&it)) + return list; + do { list.append(QString::fromUtf8(qIterGet(&it))); } while (dbus_message_iter_next(&it)); @@ -62,11 +93,11 @@ static QVariant qFetchParameter(DBusMessageIter *it) { switch (dbus_message_iter_get_arg_type(it)) { case DBUS_TYPE_BYTE: - return qIterGet(it); + return qVariantFromValue(qIterGet(it)); case DBUS_TYPE_INT16: - return qIterGet(it); + return qVariantFromValue(qIterGet(it)); case DBUS_TYPE_UINT16: - return qIterGet(it); + return qVariantFromValue(qIterGet(it)); case DBUS_TYPE_INT32: return qIterGet(it); case DBUS_TYPE_UINT32: @@ -74,7 +105,7 @@ static QVariant qFetchParameter(DBusMessageIter *it) case DBUS_TYPE_DOUBLE: return qIterGet(it); case DBUS_TYPE_BOOLEAN: - return qIterGet(it); + return bool(qIterGet(it)); case DBUS_TYPE_INT64: return static_cast(qIterGet(it)); case DBUS_TYPE_UINT64: @@ -83,19 +114,44 @@ static QVariant qFetchParameter(DBusMessageIter *it) case DBUS_TYPE_OBJECT_PATH: case DBUS_TYPE_SIGNATURE: return QString::fromUtf8(qIterGet(it)); + case DBUS_TYPE_VARIANT: + return qIterGet(it); case DBUS_TYPE_ARRAY: { int arrayType = dbus_message_iter_get_element_type(it); - if (arrayType == DBUS_TYPE_STRING || arrayType == DBUS_TYPE_OBJECT_PATH || - arrayType == DBUS_TYPE_SIGNATURE) { - return qFetchStringList(it); - } else if (arrayType == DBUS_TYPE_BYTE) { + switch (arrayType) + { + case DBUS_TYPE_BYTE: { + // QByteArray DBusMessageIter sub; dbus_message_iter_recurse(it, &sub); int len = dbus_message_iter_get_array_len(&sub); char* data; dbus_message_iter_get_fixed_array(&sub,&data,&len); return QByteArray(data,len); - } else if (arrayType == DBUS_TYPE_DICT_ENTRY) { + } + case DBUS_TYPE_INT16: + return qFetchList(it); + case DBUS_TYPE_UINT16: + return qFetchList(it); + case DBUS_TYPE_INT32: + return qFetchList(it); + case DBUS_TYPE_UINT32: + return qFetchList(it); + case DBUS_TYPE_BOOLEAN: + return qFetchList(it); + case DBUS_TYPE_DOUBLE: + return qFetchList(it); + case DBUS_TYPE_INT64: + return qFetchList(it); + case DBUS_TYPE_UINT64: + return qFetchList(it); + case DBUS_TYPE_STRING: + case DBUS_TYPE_OBJECT_PATH: + case DBUS_TYPE_SIGNATURE: + return qFetchStringList(it); + case DBUS_TYPE_VARIANT: + return qFetchList(it); + case DBUS_TYPE_DICT_ENTRY: { // ### support other types of maps? QMap map; DBusMessageIter sub; @@ -115,9 +171,10 @@ static QVariant qFetchParameter(DBusMessageIter *it) } while (dbus_message_iter_next(&sub)); return map; } + } } // fall through - // common handling for structs and lists + // common handling for structs and lists of lists (for now) case DBUS_TYPE_STRUCT: { QList list; DBusMessageIter sub; @@ -129,14 +186,6 @@ static QVariant qFetchParameter(DBusMessageIter *it) } while (dbus_message_iter_next(&sub)); return list; } - case DBUS_TYPE_VARIANT: { - QDBusVariant dvariant; - DBusMessageIter sub; - dbus_message_iter_recurse(it, &sub); - dvariant.type = QDBusType(dbus_message_iter_get_signature(&sub)); - dvariant.value = qFetchParameter(&sub); - return qVariantFromValue(dvariant); - } default: qWarning("Don't know how to handle type %d '%c'", dbus_message_iter_get_arg_type(it), dbus_message_iter_get_arg_type(it)); @@ -169,26 +218,20 @@ static bool checkType(QVariant &var, QDBusType &type) return true; } - // only catch the conversions that won't work - // let QVariant do the hard work - - // QVariant can't convert QDBusVariant: - if (var.userType() == qMetaTypeId()) { - if (type.dbusType() == DBUS_TYPE_VARIANT) - return true; // no change - - // convert manually - QDBusVariant dvariant = qvariant_cast(var); - var = dvariant.value; - return checkType(var, type); - } + int id = var.userType(); if (type.dbusType() == DBUS_TYPE_VARIANT) { - // variant can handle anything. Let it pass + // this is a non symmetrical operation: + // nest a QVariant if we want variant and it isn't so + if (id != QDBusTypeHelper::id()) { + QVariant tmp = var; + var = QDBusTypeHelper::toVariant(tmp); + } return true; } - switch (var.userType()) { + switch (id) { + case QVariant::Bool: case QMetaType::Short: case QMetaType::UShort: case QMetaType::UChar: @@ -249,10 +292,35 @@ static bool checkType(QVariant &var, QDBusType &type) return true; - case QVariant::Invalid: + case QVariant::Invalid: { // create an empty variant - var.convert(type.qvariantType()); - break; + void *null = 0; + var = QVariant(type.qvariantType(), null); + break; + } + + default: + if (id == QDBusTypeHelper::id()) { + // if we got here, it means the match above for DBUS_TYPE_VARIANT didn't work + qWarning("Invalid conversion from nested variant to '%s'", + type.dbusSignature().constData()); + return false; + } else if (type.dbusType() == DBUS_TYPE_ARRAY) { + int subType = type.arrayElement().dbusType(); + if ((id == QDBusTypeHelper::listId() && subType == DBUS_TYPE_BOOLEAN) || + (id == QDBusTypeHelper::listId() && subType == DBUS_TYPE_INT16) || + (id == QDBusTypeHelper::listId() && subType == DBUS_TYPE_UINT16) || + (id == QDBusTypeHelper::listId() && subType == DBUS_TYPE_INT32) || + (id == QDBusTypeHelper::listId() && subType == DBUS_TYPE_UINT32) || + (id == QDBusTypeHelper::listId() && subType == DBUS_TYPE_INT64) || + (id == QDBusTypeHelper::listId() && subType == DBUS_TYPE_UINT64) || + (id == QDBusTypeHelper::listId() && subType == DBUS_TYPE_DOUBLE)) + return true; + } + + qWarning("Invalid conversion from %s to '%s'", var.typeName(), + type.dbusSignature().constData()); + return false; } qWarning("Found unknown QVariant type %d (%s) when converting to DBus", (int)var.type(), @@ -271,7 +339,16 @@ template static void qIterAppend(DBusMessageIter *it, const QDBusType &type, T arg) { dbus_message_iter_append_basic(it, type.dbusType(), &arg); -} +} + +template +static void qAppendListToMessage(DBusMessageIter *it, const QDBusType &subType, + const QVariant &var) +{ + QList list = QDBusTypeHelper >::fromVariant(var); + foreach (const QtType &item, list) + qIterAppend(it, subType, static_cast(item)); +} static void qAppendArrayToMessage(DBusMessageIter *it, const QDBusType &subType, const QVariant &var) @@ -319,10 +396,33 @@ static void qAppendArrayToMessage(DBusMessageIter *it, const QDBusType &subType, break; } - default: - qFatal("qAppendArrayToMessage got unknown type!"); + default: { + int id = var.userType(); + if (id == QDBusTypeHelper::listId()) + qAppendListToMessage(&sub, subType, var); + else if (id == QDBusTypeHelper::listId()) + qAppendListToMessage(&sub, subType, var); + else if (id == QDBusTypeHelper::listId()) + qAppendListToMessage(&sub, subType, var); + else if (id == QDBusTypeHelper::listId()) + qAppendListToMessage(&sub, subType, var); + else if (id == QDBusTypeHelper::listId()) + qAppendListToMessage(&sub, subType, var); + else if (id == QDBusTypeHelper::listId()) + qAppendListToMessage(&sub, subType, var); + else if (id == QDBusTypeHelper::listId()) + qAppendListToMessage(&sub, subType, var); + else if (id == QDBusTypeHelper::listId()) + qAppendListToMessage(&sub, subType, var); +#if 0 // never reached, since QVariant::List mached + else if (id == QDBusTypeHelper::listId()) + qAppendListToMessage(&sub, subType, var); +#endif + else + qFatal("qAppendArrayToMessage got unknown type!"); break; } + } dbus_message_iter_close_container(it, &sub); } @@ -336,28 +436,21 @@ static void qAppendStructToMessage(DBusMessageIter *it, const QDBusTypeList &typ dbus_message_iter_close_container(it, &sub); } -static void qAppendVariantToMessage(DBusMessageIter *it, const QDBusType & /* type */, +static void qAppendVariantToMessage(DBusMessageIter *it, const QDBusType &type, const QVariant &var) { - QVariant v; - QDBusType t; - - if (var.userType() == qMetaTypeId()) { - QDBusVariant dvariant = qvariant_cast(var); - v = dvariant.value; - t = dvariant.type; - } - else { - v = var; - } + Q_UNUSED(type); // type is 'v' - if (!t.isValid()) - t = QDBusType::guessFromVariant(v); + QVariant arg = var; + if (var.userType() == QDBusTypeHelper::id()) + arg = QDBusTypeHelper::fromVariant(var); // extract the inner variant + + QDBusType t = QDBusType::guessFromVariant(arg); // now add this variant DBusMessageIter sub; dbus_message_iter_open_container(it, DBUS_TYPE_VARIANT, t.dbusSignature(), &sub); - qVariantToIteratorInternal(&sub, v, t); + qVariantToIteratorInternal(&sub, arg, t); dbus_message_iter_close_container(it, &sub); } @@ -376,16 +469,16 @@ static void qVariantToIteratorInternal(DBusMessageIter *it, const QVariant &var, { switch (type.dbusType()) { case DBUS_TYPE_BYTE: - qIterAppend( it, type, static_cast(var.toUInt()) ); + qIterAppend( it, type, QDBusTypeHelper::fromVariant(var) ); break; case DBUS_TYPE_BOOLEAN: qIterAppend( it, type, static_cast(var.toBool()) ); break; case DBUS_TYPE_INT16: - qIterAppend( it, type, static_cast(var.toInt()) ); + qIterAppend( it, type, QDBusTypeHelper::fromVariant(var) ); break; case DBUS_TYPE_UINT16: - qIterAppend( it, type, static_cast(var.toUInt()) ); + qIterAppend( it, type, QDBusTypeHelper::fromVariant(var) ); break; case DBUS_TYPE_INT32: qIterAppend( it, type, static_cast(var.toInt()) ); @@ -461,4 +554,3 @@ void QDBusMarshall::listToMessage(const QList &list, DBusMessage *msg, else qListToIterator(&it, list, QDBusTypeList(signature.toUtf8())); } - -- cgit