summaryrefslogtreecommitdiffstats
path: root/qt/src/qdbustype.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'qt/src/qdbustype.cpp')
-rw-r--r--qt/src/qdbustype.cpp847
1 files changed, 847 insertions, 0 deletions
diff --git a/qt/src/qdbustype.cpp b/qt/src/qdbustype.cpp
new file mode 100644
index 00000000..7f17a372
--- /dev/null
+++ b/qt/src/qdbustype.cpp
@@ -0,0 +1,847 @@
+/* -*- C++ -*-
+ *
+ * Copyright (C) 2005 Thiago Macieira <thiago@kde.org>
+ * Copyright (C) 2006 Trolltech AS. All rights reserved.
+ * Author: Thiago Macieira <thiago.macieira@trolltech.com>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "qdbustype_p.h"
+#include "qdbustypehelper_p.h"
+#include <dbus/dbus.h>
+
+#include <QtCore/qstringlist.h>
+
+class QDBusTypePrivate: public QSharedData
+{
+public:
+ int code;
+ mutable int qvariantType;
+ mutable QByteArray signature;
+ QDBusTypeList subTypes;
+
+ inline QDBusTypePrivate()
+ : code(0), qvariantType(QVariant::Invalid)
+ { }
+};
+
+/*!
+ \class QDBusType
+ \brief Represents one single D-Bus type.
+ \internal
+
+ D-Bus provides a set of primitive types that map to normal, C++ types and to QString, as well as
+ the possibility to extend the set with the so-called "container" types. The available types are
+ as follows:
+
+ - Primitive (or basic): integers of 16, 32 and 64 bits, both signed and unsigned; byte (8 bits);
+ double-precision floating point and Unicode strings
+ - Arrays: a homogeneous, ordered list of zero or more entries
+ - Maps: an unordered list of (key, value) pairs, where key must be a primitive type and value
+ can be any D-Bus type
+ - Structs: an ordered list of a fixed number of entries of any type
+ - Variants: a "wildcard" container that can assume the value of any other type, including
+ structs and arrays
+
+ Any type can be placed inside an array (including other arrays), but only entries of the same
+ type can be placed inside the same array. The analogous type for D-Bus arrays are the Qt
+ #QList template classes.
+
+ Structs have a fixed number of entries and each entry has a fixed type. They are analogous to C
+ and C++ structs (hence the name).
+
+ Maps or dictionaries are analogous to the Qt #QMap template class, with the additional
+ restriction that the key type must be a primitive one. D-Bus implements maps by using arrays of
+ a special type (a "dictionary entry"), so inspecting a QDBusType of a Map will reveal that it is
+ an array (see isArray()).
+
+ Variants contain exactly one entry, but the type can vary freely. It is analogous to the Qt
+ class #QVariant, but the QtDBus implementation uses #QDBusVariant to represent D-Bus Variants.
+*/
+
+/*!
+ Constructs an empty (invalid) type.
+*/
+QDBusType::QDBusType()
+ : d(0)
+{
+}
+
+/*!
+ Constructs the type based on the D-Bus type given by \a type.
+*/
+QDBusType::QDBusType(int type)
+{
+ char c[2] = { type, 0 };
+ *this = QDBusType(c);
+}
+
+/*!
+ Constructs the type based on the QVariant type given by \a type.
+
+ \sa QVariant::Type
+*/
+QDBusType::QDBusType(QVariant::Type type)
+{
+ const char *sig = dbusSignature(type);
+
+ // it never returns NULL
+ // but it may return an empty string:
+ if (sig[0] == '\0')
+ return;
+
+ if (qstrlen(sig) > 2) {
+ *this = QDBusType(sig);
+ } else {
+ d = new QDBusTypePrivate;
+ d->qvariantType = type;
+ d->code = sig[0];
+ if (sig[1] == '\0')
+ // single-letter type
+ return;
+ else {
+ // two-letter type
+ // must be an array
+ d->code = sig[0];
+ QDBusType t;
+ t.d = new QDBusTypePrivate;
+ t.d->code = sig[1];
+ d->subTypes << t;
+ }
+ }
+}
+
+/*!
+ Parses the D-Bus signature given by \a signature and constructs the type it represents.
+*/
+QDBusType::QDBusType(const char* signature)
+{
+ if ( !dbus_signature_validate_single(signature, 0) )
+ return;
+
+ DBusSignatureIter iter;
+ dbus_signature_iter_init(&iter, signature);
+ *this = QDBusType(&iter);
+ if (d)
+ d->signature = signature;
+}
+
+/*!
+ \overload
+ Parses the D-Bus signature given by \a str and constructs the type it represents.
+*/
+QDBusType::QDBusType(const QString& str)
+{
+ *this = QDBusType( str.toUtf8().constData() );
+}
+
+/*!
+ \overload
+ Parses the D-Bus signature given by \a str and constructs the type it represents.
+*/
+QDBusType::QDBusType(const QByteArray& str)
+{
+ *this = QDBusType( str.constData() );
+}
+
+/*!
+ \internal
+ Creates a QDBusType object based on the current element pointed to by \a iter.
+*/
+QDBusType::QDBusType(DBusSignatureIter* iter)
+ : d(new QDBusTypePrivate)
+{
+ if ( dbus_type_is_container( d->code = dbus_signature_iter_get_current_type(iter) ) ) {
+ // we have to recurse
+ if ( d->code == DBUS_TYPE_VARIANT )
+ return; // no we don't. dbus_type_is_container lies to us
+
+ // we have to recurse
+ DBusSignatureIter subiter;
+ dbus_signature_iter_recurse(iter, &subiter);
+
+ d->subTypes = QDBusTypeList(&subiter);
+
+ // sanity checking:
+ if ( d->code == DBUS_TYPE_ARRAY )
+ Q_ASSERT_X(d->subTypes.size() == 1, "QDBusType",
+ "more than one element in array");
+ else if (d->code == DBUS_TYPE_DICT_ENTRY )
+ Q_ASSERT_X(d->subTypes.size() == 2, "QDBusType",
+ "maps must have exactly two elements");
+ }
+}
+
+/*!
+ Copies the type from the object \a other.
+*/
+QDBusType::QDBusType(const QDBusType& other)
+ : d(other.d)
+{
+}
+
+/*!
+ Release the resources associated with this type.
+*/
+QDBusType::~QDBusType()
+{
+}
+
+/*!
+ Copies the type from the object given by \a other.
+*/
+QDBusType& QDBusType::operator=(const QDBusType& other)
+{
+ d = other.d;
+ return *this;
+}
+
+/*!
+ Returns the DBus type for this type.
+*/
+int QDBusType::dbusType() const
+{
+ return d ? d->code : DBUS_TYPE_INVALID;
+}
+
+/*!
+ Returns the DBus signature for this type and subtypes.
+*/
+QByteArray QDBusType::dbusSignature() const
+{
+ if (!d)
+ return QByteArray();
+
+ if (!d->signature.isEmpty())
+ return d->signature;
+
+ if (d->subTypes.isEmpty())
+ return d->signature = QByteArray(1, d->code);
+
+ QByteArray retval;
+ switch (d->code) {
+ // can only be array, map or struct
+
+ case DBUS_TYPE_ARRAY:
+ Q_ASSERT_X(d->subTypes.size() == 1, "QDBusType::dbusSignature",
+ "more than one element in array");
+
+ retval += DBUS_TYPE_ARRAY;
+ retval += d->subTypes.at(0).dbusSignature();
+ break;
+
+ case DBUS_TYPE_DICT_ENTRY: {
+ Q_ASSERT_X(d->subTypes.size() == 2, "QDBusType::dbusSignature",
+ "maps must have exactly two elements");
+
+ QByteArray value = d->subTypes.at(1).dbusSignature();
+ char key = d->subTypes.at(0).dbusType();
+
+ Q_ASSERT(key != DBUS_TYPE_INVALID);
+ Q_ASSERT(!value.isEmpty());
+
+ retval.reserve(value.length() + 3);
+ retval = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING;
+ retval += key;
+ retval += value;
+ retval += DBUS_DICT_ENTRY_END_CHAR;
+ break;
+ }
+
+ case DBUS_TYPE_STRUCT:
+ retval = d->subTypes.dbusSignature();
+ retval.prepend(DBUS_STRUCT_BEGIN_CHAR);
+ retval.append(DBUS_STRUCT_END_CHAR);
+ break;
+
+ default:
+ Q_ASSERT_X(false, "QDBusType::dbusSignature", "invalid container type");
+ }
+
+ d->signature = retval;
+ return retval;
+}
+
+/*!
+ Returns the QVariant::Type for this entry.
+*/
+int QDBusType::qvariantType() const
+{
+ if (d && d->qvariantType != QVariant::Invalid)
+ return d->qvariantType;
+
+ if (!d)
+ return QVariant::Invalid;
+
+ return d->qvariantType = qvariantType(dbusSignature().constData());
+}
+
+/*!
+ Returns true if this type is a valid one.
+*/
+bool QDBusType::isValid() const
+{
+ return d && d->code != DBUS_TYPE_INVALID;
+}
+
+/*!
+ Returns true if this type is a basic one.
+*/
+bool QDBusType::isBasic() const
+{
+ return d && dbus_type_is_basic(d->code);
+}
+
+/*!
+ Returns true if this type is a container.
+*/
+bool QDBusType::isContainer() const
+{
+ return d && dbus_type_is_container(d->code);
+}
+
+/*!
+ Returns the subtypes of this type, if this is a container.
+
+ \sa isContainer()
+*/
+QDBusTypeList QDBusType::subTypes() const
+{
+ if (d)
+ return d->subTypes;
+ return QDBusTypeList();
+}
+
+/*!
+ Returns true if this type is an array.
+
+ \sa isContainer(), arrayElement()
+*/
+bool QDBusType::isArray() const
+{
+ return dbusType() == DBUS_TYPE_ARRAY;
+}
+
+/*!
+ This is a convenience function that returns the element type of an array.
+ If this object is not an array, it returns an invalid QDBusType.
+
+ \sa isArray()
+*/
+QDBusType QDBusType::arrayElement() const
+{
+ if (isArray() && d->subTypes.count() == 1)
+ return d->subTypes.first();
+ return QDBusType();
+}
+
+/*!
+ Returns true if this type is a map (i.e., an array of dictionary entries).
+
+ \sa isContainer(), isArray(), arrayElement()
+*/
+bool QDBusType::isMap() const
+{
+ return arrayElement().dbusType() == DBUS_TYPE_DICT_ENTRY;
+}
+
+/*!
+ If this object is a map, returns the (basic) type that corresponds to the key type.
+ If this object is not a map, returns an invalid QDBusType.
+
+ \sa isMap()
+*/
+QDBusType QDBusType::mapKey() const
+{
+ if (isMap())
+ return arrayElement().d->subTypes.first();
+ return QDBusType();
+}
+
+/*!
+ If this object is a map, returns the type that corresponds to the value type.
+ If this object is not a map, returns an invalid QDBusType.
+
+ \sa isMap()
+*/
+QDBusType QDBusType::mapValue() const
+{
+ if (isMap())
+ return arrayElement().d->subTypes.at(1);
+ return QDBusType();
+}
+
+/*!
+ Returns true if this type is the same one as \a other.
+*/
+bool QDBusType::operator==(const QDBusType& other) const
+{
+ if (!d && !other.d)
+ return true;
+ if (!d || !other.d)
+ return false;
+ return d->code == other.d->code && d->subTypes == other.d->subTypes;
+}
+
+/*!
+ \fn QDBusType::operator!=(const QDBusType &other) const
+ Returns true if the this type and the one given by \a other are different.
+*/
+
+/*!
+ Converts the DBus type code \a type to QVariant::Type.
+*/
+int QDBusType::qvariantType(int type)
+{
+ char c[2] = { type, 0 };
+ return qvariantType(c);
+}
+
+/*!
+ Converts the DBus type signature \a signature to QVariant::Type.
+*/
+int QDBusType::qvariantType(const char* signature)
+{
+ if (!signature)
+ return QVariant::Invalid;
+
+ // three special cases that don't validate as single:
+ if (qstrlen(signature) == 1) {
+ if (signature[0] == DBUS_TYPE_STRUCT)
+ return QVariant::List;
+ else if (signature[0] == DBUS_TYPE_DICT_ENTRY)
+ return QVariant::Map;
+ else if (signature[0] == DBUS_TYPE_ARRAY)
+ return QVariant::List;
+ }
+
+ // now we can validate
+ if ( !dbus_signature_validate_single(signature, 0) )
+ return QVariant::Invalid;
+
+ switch (signature[0])
+ {
+ case DBUS_TYPE_BOOLEAN:
+ return QVariant::Bool;
+
+ case DBUS_TYPE_BYTE:
+ return QMetaType::UChar;
+
+ case DBUS_TYPE_INT16:
+ return QMetaType::Short;
+
+ case DBUS_TYPE_UINT16:
+ return QMetaType::UShort;
+
+ case DBUS_TYPE_INT32:
+ return QVariant::Int;
+
+ case DBUS_TYPE_UINT32:
+ return QVariant::UInt;
+
+ case DBUS_TYPE_INT64:
+ return QVariant::LongLong;
+
+ case DBUS_TYPE_UINT64:
+ return QVariant::ULongLong;
+
+ case DBUS_TYPE_DOUBLE:
+ return QVariant::Double;
+
+ case DBUS_TYPE_STRING:
+ case DBUS_TYPE_OBJECT_PATH:
+ case DBUS_TYPE_SIGNATURE:
+ return QVariant::String;
+
+ case DBUS_STRUCT_BEGIN_CHAR:
+ return QVariant::List; // change to QDBusStruct in the future
+
+ case DBUS_TYPE_VARIANT:
+ return QDBusTypeHelper<QVariant>::id();
+
+ case DBUS_TYPE_ARRAY: // special case
+ switch (signature[1]) {
+ case DBUS_TYPE_BOOLEAN:
+ return QDBusTypeHelper<bool>::listId();
+
+ case DBUS_TYPE_BYTE:
+ return QVariant::ByteArray;
+
+ case DBUS_TYPE_INT16:
+ return QDBusTypeHelper<short>::listId();
+
+ case DBUS_TYPE_UINT16:
+ return QDBusTypeHelper<ushort>::listId();
+
+ case DBUS_TYPE_INT32:
+ return QDBusTypeHelper<int>::listId();
+
+ case DBUS_TYPE_UINT32:
+ return QDBusTypeHelper<uint>::listId();
+
+ case DBUS_TYPE_INT64:
+ return QDBusTypeHelper<qlonglong>::listId();
+
+ case DBUS_TYPE_UINT64:
+ return QDBusTypeHelper<qulonglong>::listId();
+
+ case DBUS_TYPE_DOUBLE:
+ return QDBusTypeHelper<double>::listId();
+
+ case DBUS_TYPE_STRING:
+ case DBUS_TYPE_OBJECT_PATH:
+ case DBUS_TYPE_SIGNATURE:
+ return QVariant::StringList;
+
+ case DBUS_TYPE_VARIANT:
+ return QVariant::List;
+
+ case DBUS_DICT_ENTRY_BEGIN_CHAR:
+ return QVariant::Map;
+
+ default:
+ return QVariant::List;
+ }
+ default:
+ return QVariant::Invalid;
+
+ }
+}
+
+/*!
+ Converts the QVariant::Type \a t to a DBus type code.
+*/
+int QDBusType::dbusType(QVariant::Type t)
+{
+ switch (t)
+ {
+ case QVariant::Bool:
+ return DBUS_TYPE_BOOLEAN;
+
+ case QVariant::Int:
+ return DBUS_TYPE_INT32;
+
+ case QVariant::UInt:
+ return DBUS_TYPE_UINT32;
+
+ case QVariant::LongLong:
+ return DBUS_TYPE_INT64;
+
+ case QVariant::ULongLong:
+ return DBUS_TYPE_UINT64;
+
+ case QVariant::Double:
+ return DBUS_TYPE_DOUBLE;
+
+ // from QMetaType:
+ case QMetaType::Short:
+ return DBUS_TYPE_INT16;
+
+ case QMetaType::UShort:
+ return DBUS_TYPE_UINT16;
+
+ case QMetaType::UChar:
+ return DBUS_TYPE_BYTE;
+
+ case QVariant::String:
+ return DBUS_TYPE_STRING;
+
+ case QVariant::Map:
+ // internal type information has been lost
+ return DBUS_TYPE_DICT_ENTRY;
+
+ case QVariant::List:
+ case QVariant::StringList:
+ case QVariant::ByteArray:
+ // could also be a struct...
+ return DBUS_TYPE_ARRAY;
+
+ case QVariant::UserType:
+ return DBUS_TYPE_INVALID; // invalid
+
+ default:
+ break; // avoid compiler warnings
+ }
+
+ if (int(t) == QDBusTypeHelper<QVariant>::id())
+ return DBUS_TYPE_VARIANT;
+
+ return DBUS_TYPE_INVALID;
+}
+
+/*!
+ Converts the QVariant::Type \a t to a DBus type signature.
+*/
+const char* QDBusType::dbusSignature(QVariant::Type t)
+{
+ switch (t)
+ {
+ case QVariant::Bool:
+ return DBUS_TYPE_BOOLEAN_AS_STRING;
+
+ case QVariant::Int:
+ return DBUS_TYPE_INT32_AS_STRING;
+
+ case QVariant::UInt:
+ return DBUS_TYPE_UINT32_AS_STRING;
+
+ case QMetaType::Short:
+ return DBUS_TYPE_INT16_AS_STRING;
+
+ case QMetaType::UShort:
+ return DBUS_TYPE_UINT16_AS_STRING;
+
+ case QMetaType::UChar:
+ return DBUS_TYPE_BYTE_AS_STRING;
+
+ case QVariant::LongLong:
+ return DBUS_TYPE_INT64_AS_STRING;
+
+ case QVariant::ULongLong:
+ return DBUS_TYPE_UINT64_AS_STRING;
+
+ case QVariant::Double:
+ return DBUS_TYPE_DOUBLE_AS_STRING;
+
+ case QVariant::String:
+ return DBUS_TYPE_STRING_AS_STRING;
+
+ case QVariant::Map:
+ // internal type information has been lost
+ return DBUS_TYPE_ARRAY_AS_STRING
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING; // a{sv}
+
+ case QVariant::StringList:
+ return DBUS_TYPE_ARRAY_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING; // as
+
+ case QVariant::ByteArray:
+ return DBUS_TYPE_ARRAY_AS_STRING
+ DBUS_TYPE_BYTE_AS_STRING; // ay
+
+ case QVariant::List:
+ // not a string list
+ // internal list data has been lost
+ // could also be a struct...
+ return DBUS_TYPE_ARRAY_AS_STRING
+ DBUS_TYPE_VARIANT_AS_STRING; // av
+
+ default:
+ if (int(t) == QDBusTypeHelper<QVariant>::id())
+ return DBUS_TYPE_VARIANT_AS_STRING;
+ if (int(t) == QDBusTypeHelper<bool>::listId())
+ return DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BOOLEAN_AS_STRING;
+ if (int(t) == QDBusTypeHelper<short>::listId())
+ return DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT16_AS_STRING;
+ if (int(t) == QDBusTypeHelper<ushort>::listId())
+ return DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_UINT16_AS_STRING;
+ if (int(t) == QDBusTypeHelper<int>::listId())
+ return DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT32_AS_STRING;
+ if (int(t) == QDBusTypeHelper<uint>::listId())
+ return DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_UINT32_AS_STRING;
+ if (int(t) == QDBusTypeHelper<qlonglong>::listId())
+ return DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT64_AS_STRING;
+ if (int(t) == QDBusTypeHelper<qulonglong>::listId())
+ return DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_UINT64_AS_STRING;
+ if (int(t) == QDBusTypeHelper<double>::listId())
+ return DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_DOUBLE_AS_STRING;
+
+ return DBUS_TYPE_INVALID_AS_STRING;
+ }
+}
+
+/*!
+ \enum QDBusType::VariantListMode
+ Defines how the guessFromVariant() function will behave when the QVariant is of type
+ QVariant::List.
+*/
+
+/*!
+ Guesses the DBus type from the given \a variant.
+*/
+QDBusType QDBusType::guessFromVariant(const QVariant& variant, VariantListMode mode)
+{
+ if (variant.type() == QVariant::List) {
+ // investigate deeper
+ QDBusType t;
+ t.d = new QDBusTypePrivate;
+ const QVariantList list = variant.toList();
+
+ t.d->code = DBUS_TYPE_ARRAY;
+ if (!list.isEmpty()) {
+ // check if all elements have the same type
+ QVariant::Type type = list.first().type();
+ foreach (const QVariant& v, list)
+ if (type != v.type()) {
+ // at least one is different
+ type = QVariant::Invalid;
+ break;
+ }
+
+ if (type != QVariant::Invalid) {
+ // all are of the same type
+ t.d->subTypes << guessFromVariant(list.first());
+ return t;
+ }
+ } else {
+ // an array of "something"
+ t.d->subTypes << QDBusType('v');
+ return t;
+ }
+
+ // treat it as a struct
+ t.d->code = DBUS_TYPE_STRUCT;
+ foreach (const QVariant& v, list)
+ t.d->subTypes << guessFromVariant(v, mode);
+
+ return t;
+ }
+ else if (variant.type() == QVariant::Map) {
+ // investigate deeper
+ QDBusType t, t2, t3;
+ t2.d = new QDBusTypePrivate;
+ t2.d->code = DBUS_TYPE_DICT_ENTRY;
+
+ // the key
+ t3.d = new QDBusTypePrivate;
+ t3.d->code = DBUS_TYPE_STRING;
+ t2.d->subTypes << t3;
+
+ const QVariantMap map = variant.toMap();
+ if (!map.isEmpty()) {
+ // check if all elements have the same type
+ QVariantMap::const_iterator it = map.constBegin(),
+ end = map.constEnd();
+ QVariant::Type type = it.value().type();
+ for ( ; it != end; ++it)
+ if (type != it.value().type()) {
+ // at least one is different
+ type = QVariant::Invalid;
+ break;
+ }
+
+ if (type != QVariant::Invalid)
+ t2.d->subTypes << guessFromVariant(map.constBegin().value());
+ else {
+ // multiple types
+ t3.d->code = DBUS_TYPE_VARIANT;
+ t2.d->subTypes << t3;
+ }
+ }
+ else {
+ // information lost
+ t3.d->code = DBUS_TYPE_VARIANT;
+ t2.d->subTypes << t3;
+ }
+
+ t.d = new QDBusTypePrivate;
+ t.d->code = DBUS_TYPE_ARRAY;
+ t.d->subTypes << t2;
+ return t;
+ }
+ else
+ return QDBusType( QVariant::Type( variant.userType() ) );
+}
+
+/*!
+ \class QDBusTypeList
+ \brief A list of DBus types.
+ \internal
+
+ Represents zero or more DBus types in sequence, such as those used in argument lists
+ or in subtypes of structs and maps.
+*/
+
+/*!
+ \fn QDBusTypeList::QDBusTypeList()
+
+ Default constructor.
+ */
+
+/*!
+ \fn QDBusTypeList::QDBusTypeList(const QDBusTypeList& other)
+
+ Copy constructor: copies the type list from \a other.
+*/
+
+/*!
+ \fn QDBusTypeList::QDBusTypeList(const QList<QDBusType>& other)
+
+ Copy constructor: copies the type list from \a other.
+*/
+
+/*!
+ Constructs a type list by parsing the given \a signature.
+*/
+QDBusTypeList::QDBusTypeList(const char* signature)
+{
+ if (!signature || !*signature)
+ return; // empty
+
+ // validate it first
+ if ( !dbus_signature_validate(signature, 0) )
+ return;
+
+ // split it into components
+ DBusSignatureIter iter;
+ dbus_signature_iter_init(&iter, signature);
+
+ do {
+ *this << QDBusType(&iter);
+ } while (dbus_signature_iter_next(&iter));
+}
+
+/*!
+ \internal
+ Constructs a type list by parsing the elements on this iterator level.
+*/
+QDBusTypeList::QDBusTypeList(DBusSignatureIter* iter)
+{
+ do {
+ QDBusType item(iter);
+ if (!item.isValid()) {
+ clear();
+ return;
+ }
+
+ *this << item;
+ } while (dbus_signature_iter_next(iter));
+}
+
+/*!
+ Returns true if this type list can represent the inner components of a map.
+*/
+bool QDBusTypeList::canBeMap() const
+{
+ return size() == 2 && at(0).isBasic();
+}
+
+/*!
+ Reconstructs the type signature that this type list represents.
+*/
+QByteArray QDBusTypeList::dbusSignature() const
+{
+ QByteArray retval;
+ foreach (QDBusType t, *this)
+ retval += t.dbusSignature();
+ return retval;
+}