QDBusDataList &QDBusDataList::operator=(const QValueList< QDBusData > &other) { d->list.clear(); d->type = QDBusData::Invalid; d->containerItem = QDBusData(); if(other.isEmpty()) return *this; QValueList< QDBusData >::const_iterator it = other.begin(); QValueList< QDBusData >::const_iterator endIt = other.end(); d->type = (*it).type(); QCString elementSignature; if(hasContainerItemType()) { d->containerItem = other[0]; // would be nice to get an empty one elementSignature = d->containerItem.buildDBusSignature(); } for(++it; it != endIt; ++it) { if(d->type != (*it).type()) { d->type = QDBusData::Invalid; d->containerItem = QDBusData(); return *this; } else if(hasContainerItemType()) { if((*it).buildDBusSignature() != elementSignature) { d->type = QDBusData::Invalid; d->containerItem = QDBusData(); return *this; } } } d->list = other; return *this; }
QDBusDataList &QDBusDataList::operator=(const QStringList &other) { d->list.clear(); d->type = QDBusData::String; d->containerItem = QDBusData(); QStringList::const_iterator it = other.begin(); QStringList::const_iterator endIt = other.end(); for(; it != endIt; ++it) { d->list << QDBusData::fromString(*it); } return *this; }
static QValueList<QDBusData> parseSignature(QCString& signature) { // qDebug("parseSignature(%s)", signature.data()); QValueList<QDBusData> result; while (!signature.isEmpty()) { switch (signature[0]) { case '(': { signature = signature.mid(1); QValueList<QDBusData> memberList = parseSignature(signature); result << QDBusData::fromStruct(memberList); Q_ASSERT(!signature.isEmpty() && signature[0] == ')'); signature = signature.mid(1); break; } case ')': return result; case '{': { QDBusData::Type keyType = qSingleTypeForDBusSignature(signature[1]); QDBusData::Type valueType = qSingleTypeForDBusSignature(signature[2]); if (valueType != QDBusData::Invalid) { switch (keyType) { case QDBusData::Byte: result << QDBusData::fromByteKeyMap( QDBusDataMap<Q_UINT8>(valueType)); break; case QDBusData::Int16: result << QDBusData::fromInt16KeyMap( QDBusDataMap<Q_INT16>(valueType)); break; case QDBusData::UInt16: result << QDBusData::fromUInt16KeyMap( QDBusDataMap<Q_UINT16>(valueType)); break; case QDBusData::Int32: result << QDBusData::fromInt32KeyMap( QDBusDataMap<Q_INT32>(valueType)); break; case QDBusData::UInt32: result << QDBusData::fromUInt32KeyMap( QDBusDataMap<Q_UINT32>(valueType)); break; case QDBusData::Int64: result << QDBusData::fromInt64KeyMap( QDBusDataMap<Q_INT64>(valueType)); break; case QDBusData::UInt64: result << QDBusData::fromUInt64KeyMap( QDBusDataMap<Q_UINT64>(valueType)); break; case QDBusData::String: result << QDBusData::fromStringKeyMap( QDBusDataMap<QString>(valueType)); break; case QDBusData::ObjectPath: result << QDBusData::fromObjectPathKeyMap( QDBusDataMap<QDBusObjectPath>(valueType)); break; default: qWarning("QDBusMarshall: unsupported map key type %s " "at de-marshalling", QDBusData::typeName(keyType)); break; } signature = signature.mid(3); } else { signature = signature.mid(2); QValueList<QDBusData> valueContainer = parseSignature(signature); Q_ASSERT(valueContainer.count() == 1); switch (keyType) { case QDBusData::Byte: result << QDBusData::fromByteKeyMap( QDBusDataMap<Q_UINT8>(valueContainer[0])); break; case QDBusData::Int16: result << QDBusData::fromInt16KeyMap( QDBusDataMap<Q_INT16>(valueContainer[0])); break; case QDBusData::UInt16: result << QDBusData::fromUInt16KeyMap( QDBusDataMap<Q_UINT16>(valueContainer[0])); break; case QDBusData::Int32: result << QDBusData::fromInt32KeyMap( QDBusDataMap<Q_INT32>(valueContainer[0])); break; case QDBusData::UInt32: result << QDBusData::fromUInt32KeyMap( QDBusDataMap<Q_UINT32>(valueContainer[0])); break; case QDBusData::Int64: result << QDBusData::fromInt64KeyMap( QDBusDataMap<Q_INT64>(valueContainer[0])); break; case QDBusData::UInt64: result << QDBusData::fromUInt64KeyMap( QDBusDataMap<Q_UINT64>(valueContainer[0])); break; case QDBusData::String: result << QDBusData::fromStringKeyMap( QDBusDataMap<QString>(valueContainer[0])); break; case QDBusData::ObjectPath: result << QDBusData::fromObjectPathKeyMap( QDBusDataMap<QDBusObjectPath>(valueContainer[0])); break; default: qWarning("QDBusMarshall: unsupported map key type %s " "at de-marshalling", QDBusData::typeName(keyType)); break; } } Q_ASSERT(!signature.isEmpty() && signature[0] == '}'); signature = signature.mid(1); break; } case '}': return result; case 'a': { QDBusData::Type elementType = qSingleTypeForDBusSignature(signature[1]); if (elementType != QDBusData::Invalid) { QDBusDataList list(elementType); result << QDBusData::fromList(list); signature = signature.mid(2); } else { signature = signature.mid(1); bool array = signature[0] != '{'; QValueList<QDBusData> elementContainer = parseSignature(signature); Q_ASSERT(elementContainer.count() == 1); if (array) { QDBusDataList list(elementContainer[0]); result << QDBusData::fromList(list); } else result << elementContainer[0]; } break; } default: result << QDBusData(); signature = signature.mid(1); break; } } return result; }
static QDBusData qFetchParameter(DBusMessageIter *it) { switch (dbus_message_iter_get_arg_type(it)) { case DBUS_TYPE_BOOLEAN: return QDBusData::fromBool(qIterGet<dbus_bool_t>(it)); case DBUS_TYPE_BYTE: return QDBusData::fromByte(qIterGet<unsigned char>(it)); case DBUS_TYPE_INT16: return QDBusData::fromInt16(qIterGet<dbus_int16_t>(it)); case DBUS_TYPE_UINT16: return QDBusData::fromUInt16(qIterGet<dbus_uint16_t>(it)); case DBUS_TYPE_INT32: return QDBusData::fromInt32(qIterGet<dbus_int32_t>(it)); case DBUS_TYPE_UINT32: return QDBusData::fromUInt32(qIterGet<dbus_uint32_t>(it)); case DBUS_TYPE_INT64: return QDBusData::fromInt64(qIterGet<dbus_int64_t>(it)); case DBUS_TYPE_UINT64: return QDBusData::fromUInt64(qIterGet<dbus_uint64_t>(it)); case DBUS_TYPE_DOUBLE: return QDBusData::fromDouble(qIterGet<double>(it)); case DBUS_TYPE_STRING: case DBUS_TYPE_SIGNATURE: return QDBusData::fromString(QString::fromUtf8(qIterGet<char *>(it))); case DBUS_TYPE_OBJECT_PATH: return QDBusData::fromObjectPath(QDBusObjectPath(qIterGet<char *>(it))); case DBUS_TYPE_ARRAY: { int arrayType = dbus_message_iter_get_element_type(it); char* sig = dbus_message_iter_get_signature(it); QCString signature = sig; dbus_free(sig); QValueList<QDBusData> prototypeList = parseSignature(signature); if (arrayType == DBUS_TYPE_DICT_ENTRY) { DBusMessageIter sub; dbus_message_iter_recurse(it, &sub); return qFetchMap(&sub, prototypeList[0]); // } else if (arrayType == DBUS_TYPE_BYTE) { // 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 QCString(data,len); // } else { } else { QDBusDataList list = prototypeList[0].toList(); DBusMessageIter arrayIt; dbus_message_iter_recurse(it, &arrayIt); while (dbus_message_iter_get_arg_type(&arrayIt) != DBUS_TYPE_INVALID) { list << qFetchParameter(&arrayIt); dbus_message_iter_next(&arrayIt); } return QDBusData::fromList(list); } } case DBUS_TYPE_VARIANT: { QDBusVariant dvariant; DBusMessageIter sub; dbus_message_iter_recurse(it, &sub); char* signature = dbus_message_iter_get_signature(&sub); dvariant.signature = QString::fromUtf8(signature); dbus_free(signature); dvariant.value = qFetchParameter(&sub); return QDBusData::fromVariant(dvariant); } case DBUS_TYPE_STRUCT: { QValueList<QDBusData> memberList; DBusMessageIter subIt; dbus_message_iter_recurse(it, &subIt); uint index = 0; while (dbus_message_iter_get_arg_type(&subIt) != DBUS_TYPE_INVALID) { memberList << qFetchParameter(&subIt); dbus_message_iter_next(&subIt); ++index; } return QDBusData::fromStruct(memberList); } #if 0 case DBUS_TYPE_INVALID: // TODO: check if there is better way to detect empty arrays return QDBusData(); break; #endif default: qWarning("QDBusMarshall: Don't know how to de-marshall type %d '%c'", dbus_message_iter_get_arg_type(it), dbus_message_iter_get_arg_type(it)); return QDBusData(); break; } }