diff -r 000000000000 -r 1918ee327afb tests/auto/qdbusmarshall/common.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/auto/qdbusmarshall/common.h Mon Jan 11 14:00:40 2010 +0000 @@ -0,0 +1,686 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include // isnan + +Q_DECLARE_METATYPE(QVariant) +Q_DECLARE_METATYPE(QList) +Q_DECLARE_METATYPE(QList) +Q_DECLARE_METATYPE(QList) +Q_DECLARE_METATYPE(QList) +Q_DECLARE_METATYPE(QList) +Q_DECLARE_METATYPE(QList) +Q_DECLARE_METATYPE(QList) +Q_DECLARE_METATYPE(QList) +Q_DECLARE_METATYPE(QList) +Q_DECLARE_METATYPE(QList) + +Q_DECLARE_METATYPE(QList) +Q_DECLARE_METATYPE(QList) +Q_DECLARE_METATYPE(QList) +Q_DECLARE_METATYPE(QList >) +Q_DECLARE_METATYPE(QList >) +Q_DECLARE_METATYPE(QList >) +Q_DECLARE_METATYPE(QList >) +Q_DECLARE_METATYPE(QList >) +Q_DECLARE_METATYPE(QList >) +Q_DECLARE_METATYPE(QList >) +Q_DECLARE_METATYPE(QList >) +Q_DECLARE_METATYPE(QList >) +Q_DECLARE_METATYPE(QList >) + +typedef QMap IntStringMap; +typedef QMap StringStringMap; +typedef QMap ObjectPathStringMap; +typedef QHash LLDateTimeMap; +typedef QHash SignatureStringMap; +Q_DECLARE_METATYPE(IntStringMap) +Q_DECLARE_METATYPE(StringStringMap) +Q_DECLARE_METATYPE(ObjectPathStringMap) +Q_DECLARE_METATYPE(LLDateTimeMap) +Q_DECLARE_METATYPE(SignatureStringMap) + +struct MyStruct +{ + int i; + QString s; + + inline bool operator==(const MyStruct &other) const + { return i == other.i && s == other.s; } +}; +Q_DECLARE_METATYPE(MyStruct) + +QDBusArgument &operator<<(QDBusArgument &arg, const MyStruct &ms) +{ + arg.beginStructure(); + arg << ms.i << ms.s; + arg.endStructure(); + return arg; +} + +const QDBusArgument &operator>>(const QDBusArgument &arg, MyStruct &ms) +{ + arg.beginStructure(); + arg >> ms.i >> ms.s; + arg.endStructure(); + return arg; +} + +struct MyVariantMapStruct +{ + QString s; + QVariantMap map; + + inline bool operator==(const MyVariantMapStruct &other) const + { return s == other.s && map == other.map; } +}; +Q_DECLARE_METATYPE(MyVariantMapStruct) +Q_DECLARE_METATYPE(QList) + +QDBusArgument &operator<<(QDBusArgument &arg, const MyVariantMapStruct &ms) +{ + arg.beginStructure(); + arg << ms.s << ms.map; + arg.endStructure(); + return arg; +} + +const QDBusArgument &operator>>(const QDBusArgument &arg, MyVariantMapStruct &ms) +{ + arg.beginStructure(); + arg >> ms.s >> ms.map; + arg.endStructure(); + return arg; +} + + +void commonInit() +{ + qDBusRegisterMetaType >(); + qDBusRegisterMetaType >(); + qDBusRegisterMetaType >(); + qDBusRegisterMetaType > >(); + qDBusRegisterMetaType > >(); + qDBusRegisterMetaType > >(); + qDBusRegisterMetaType > >(); + qDBusRegisterMetaType > >(); + qDBusRegisterMetaType > >(); + qDBusRegisterMetaType > >(); + qDBusRegisterMetaType > >(); + qDBusRegisterMetaType > >(); + qDBusRegisterMetaType > >(); + qDBusRegisterMetaType >(); + + qDBusRegisterMetaType >(); + qDBusRegisterMetaType >(); + qDBusRegisterMetaType >(); + qDBusRegisterMetaType >(); + qDBusRegisterMetaType >(); + + qDBusRegisterMetaType(); + qDBusRegisterMetaType(); + qDBusRegisterMetaType >(); +} +#ifdef USE_PRIVATE_CODE +#include "private/qdbusintrospection_p.h" + +// just to make it easier: +typedef QDBusIntrospection::Interfaces InterfaceMap; +typedef QDBusIntrospection::Objects ObjectMap; +typedef QDBusIntrospection::Arguments ArgumentList; +typedef QDBusIntrospection::Annotations AnnotationsMap; +typedef QDBusIntrospection::Methods MethodMap; +typedef QDBusIntrospection::Signals SignalMap; +typedef QDBusIntrospection::Properties PropertyMap; + +Q_DECLARE_METATYPE(QDBusIntrospection::Method) +Q_DECLARE_METATYPE(QDBusIntrospection::Signal) +Q_DECLARE_METATYPE(QDBusIntrospection::Property) +Q_DECLARE_METATYPE(MethodMap) +Q_DECLARE_METATYPE(SignalMap) +Q_DECLARE_METATYPE(PropertyMap) + +inline QDBusIntrospection::Argument arg(const char* type, const char *name = 0) +{ + QDBusIntrospection::Argument retval; + retval.type = QLatin1String(type); + retval.name = QLatin1String(name); + return retval; +} + +template +inline QMap& operator<<(QMap& map, const T& m) +{ map.insertMulti(m.name, m); return map; } + +inline const char* mapName(const MethodMap&) +{ return "MethodMap"; } + +inline const char* mapName(const SignalMap&) +{ return "SignalMap"; } + +inline const char* mapName(const PropertyMap&) +{ return "PropertyMap"; } + +QString printable(const QDBusIntrospection::Method& m) +{ + QString result = "method " + m.name + "("; + foreach (QDBusIntrospection::Argument arg, m.inputArgs) + result += QString("in %1 %2, ") + .arg(arg.type, arg.name); + foreach (QDBusIntrospection::Argument arg, m.outputArgs) + result += QString("out %1 %2, ") + .arg(arg.type, arg.name); + AnnotationsMap::const_iterator it = m.annotations.begin(); + for ( ; it != m.annotations.end(); ++it) + result += QString("%1 \"%2\", ").arg(it.key()).arg(it.value()); + + result += ")"; + return result; +} + +QString printable(const QDBusIntrospection::Signal& s) +{ + QString result = "signal " + s.name + "("; + foreach (QDBusIntrospection::Argument arg, s.outputArgs) + result += QString("out %1 %2, ") + .arg(arg.type, arg.name); + AnnotationsMap::const_iterator it = s.annotations.begin(); + for ( ; it != s.annotations.end(); ++it) + result += QString("%1 \"%2\", ").arg(it.key()).arg(it.value()); + + result += ")"; + return result; +} + +QString printable(const QDBusIntrospection::Property& p) +{ + QString result; + if (p.access == QDBusIntrospection::Property::Read) + result = "property read %1 %2, "; + else if (p.access == QDBusIntrospection::Property::Write) + result = "property write %1 %2, "; + else + result = "property readwrite %1 %2, "; + result = result.arg(p.type, p.name); + + AnnotationsMap::const_iterator it = p.annotations.begin(); + for ( ; it != p.annotations.end(); ++it) + result += QString("%1 \"%2\", ").arg(it.key()).arg(it.value()); + + return result; +} + +template +char* printableMap(const QMap& map) +{ + QString contents = "\n"; + typename QMap::const_iterator it = map.begin(); + for ( ; it != map.end(); ++it) { + if (it.key() != it.value().name) + contents += it.value().name + ":"; + contents += printable(it.value()); + contents += ";\n"; + } + + QString result("%1(size = %2): {%3}"); + return qstrdup(qPrintable(result + .arg(mapName(map)) + .arg(map.size()) + .arg(contents))); +} + +QT_BEGIN_NAMESPACE +namespace QTest { + template<> + inline char* toString(const MethodMap& map) + { + return printableMap(map); + } + + template<> + inline char* toString(const SignalMap& map) + { + return printableMap(map); + } + + template<> + inline char* toString(const PropertyMap& map) + { + return printableMap(map); + } +} +QT_END_NAMESPACE + +#endif + +//bool compare(const QVariantList &l1, const QVariantList &l2); +//bool compare(const QVariantMap &m1, const QVariantMap &m2); +template +bool compare(const T &t1, const T &t2) +{ return t1 == t2; } + +template<> +bool compare(const QVariant &v1, const QVariant &v2); + +bool compare(double d1, double d2) +{ + if (isnan(d1) && isnan(d2)) + return true; + return d1 == d2; +} + +template<> +bool compare(const QString &s1, const QString &s2) +{ + if (s1.isEmpty() && s2.isEmpty()) + return true; // regardless of whether one of them is null + return s1 == s2; +} + +template<> +bool compare(const QByteArray &ba1, const QByteArray &ba2) +{ + if (ba1.isEmpty() && ba2.isEmpty()) + return true; // regardless of whether one of them is null + return ba1 == ba2; +} + +template<> +bool compare(const QDBusVariant &s1, const QDBusVariant &s2) +{ + return compare(s1.variant(), s2.variant()); +} + +template +bool compare(const QList &l1, const QList &l2) +{ + if (l1.count() != l2.count()) + return false; + + typename QList::ConstIterator it1 = l1.constBegin(); + typename QList::ConstIterator it2 = l2.constBegin(); + typename QList::ConstIterator end = l1.constEnd(); + for ( ; it1 != end; ++it1, ++it2) + if (!compare(*it1, *it2)) + return false; + return true; +} + +template +bool compare(const QMap &m1, const QMap &m2) +{ + if (m1.count() != m2.size()) + return false; + typename QMap::ConstIterator i1 = m1.constBegin(); + typename QMap::ConstIterator end = m1.constEnd(); + for ( ; i1 != end; ++i1) { + typename QMap::ConstIterator i2 = m2.find(i1.key()); + if (i2 == m2.constEnd()) + return false; + if (!compare(*i1, *i2)) + return false; + } + return true; +} + +template +bool compare(const QHash &m1, const QHash &m2) +{ + if (m1.count() != m2.size()) + return false; + typename QHash::ConstIterator i1 = m1.constBegin(); + typename QHash::ConstIterator end = m1.constEnd(); + for ( ; i1 != end; ++i1) { + typename QHash::ConstIterator i2 = m2.find(i1.key()); + if (i2 == m2.constEnd()) + return false; + if (!compare(*i1, *i2)) + return false; + } + return true; +} + +template +inline bool compare(const QDBusArgument &arg, const QVariant &v2, T * = 0) +{ + return compare(qdbus_cast(arg), qvariant_cast(v2)); +} + +bool compareToArgument(const QDBusArgument &arg, const QVariant &v2) +{ + if (arg.currentSignature() != QDBusMetaType::typeToSignature(v2.userType())) + return false; + + // try to demarshall the arg according to v2 + switch (v2.userType()) + { + case QVariant::Bool: + return compare(arg, v2); + case QMetaType::UChar: + return compare(arg, v2); + case QMetaType::Short: + return compare(arg, v2); + case QMetaType::UShort: + return compare(arg, v2); + case QVariant::Int: + return compare(arg, v2); + case QVariant::UInt: + return compare(arg, v2); + case QVariant::LongLong: + return compare(arg, v2); + case QVariant::ULongLong: + return compare(arg, v2); + case QVariant::Double: + return compare(arg, v2); + case QVariant::String: + return compare(arg, v2); + case QVariant::ByteArray: + return compare(arg, v2); + case QVariant::List: + return compare(arg, v2); + case QVariant::Map: + return compare(arg, v2); + case QVariant::Point: + return compare(arg, v2); + case QVariant::PointF: + return compare(arg, v2); + case QVariant::Size: + return compare(arg, v2); + case QVariant::SizeF: + return compare(arg, v2); + case QVariant::Line: + return compare(arg, v2); + case QVariant::LineF: + return compare(arg, v2); + case QVariant::Rect: + return compare(arg, v2); + case QVariant::RectF: + return compare(arg, v2); + case QVariant::Date: + return compare(arg, v2); + case QVariant::Time: + return compare(arg, v2); + case QVariant::DateTime: + return compare(arg, v2); + default: + register int id = v2.userType(); + if (id == qMetaTypeId()) + return compare(arg, v2); + else if (id == qMetaTypeId()) + return compare(arg, v2); + else if (id == qMetaTypeId()) + return compare(arg, v2); + else if (id == qMetaTypeId >()) + return compare >(arg, v2); + else if (id == qMetaTypeId >()) + return compare >(arg, v2); + else if (id == qMetaTypeId >()) + return compare >(arg, v2); + else if (id == qMetaTypeId >()) + return compare >(arg, v2); + else if (id == qMetaTypeId >()) + return compare >(arg, v2); + else if (id == qMetaTypeId >()) + return compare >(arg, v2); + else if (id == qMetaTypeId >()) + return compare >(arg, v2); + else if (id == qMetaTypeId >()) + return compare >(arg, v2); + else if (id == qMetaTypeId >()) + return compare >(arg, v2); + else if (id == qMetaTypeId >()) + return compare >(arg, v2); + else if (id == qMetaTypeId >()) + return compare >(arg, v2); + + else if (id == qMetaTypeId >()) + return compare >(arg, v2); + else if (id == qMetaTypeId >()) + return compare >(arg, v2); + else if (id == qMetaTypeId >()) + return compare >(arg, v2); + else if (id == qMetaTypeId >()) + return compare >(arg, v2); + else if (id == qMetaTypeId >()) + return compare >(arg, v2); + + else if (id == qMetaTypeId >()) + return compare >(arg, v2); + else if (id == qMetaTypeId > >()) + return compare > >(arg, v2); + else if (id == qMetaTypeId > >()) + return compare > >(arg, v2); + else if (id == qMetaTypeId > >()) + return compare > >(arg, v2); + else if (id == qMetaTypeId > >()) + return compare > >(arg, v2); + else if (id == qMetaTypeId > >()) + return compare > >(arg, v2); + else if (id == qMetaTypeId > >()) + return compare > >(arg, v2); + else if (id == qMetaTypeId > >()) + return compare > >(arg, v2); + else if (id == qMetaTypeId > >()) + return compare > >(arg, v2); + else if (id == qMetaTypeId >()) + return compare >(arg, v2); + else if (id == qMetaTypeId >()) + return compare >(arg, v2); + + else if (id == qMetaTypeId()) + return compare(arg, v2); + + else if (id == qMetaTypeId()) + return compare(arg, v2); + else if (id == qMetaTypeId >()) + return compare >(arg, v2); + } + + qWarning() << "Unexpected QVariant type" << v2.userType() + << QByteArray(QDBusMetaType::typeToSignature(v2.userType())) + << QVariant::typeToName(QVariant::Type(v2.userType())); + return false; +} + +template<> bool compare(const QVariant &v1, const QVariant &v2) +{ + // v1 is the one that came from the network + // v2 is the one that we sent + + if (v1.userType() == qMetaTypeId()) + // this argument has been left un-demarshalled + return compareToArgument(qvariant_cast(v1), v2); + + if (v1.userType() != v2.userType()) + return false; + + int id = v1.userType(); + if (id == QVariant::List) + return compare(v1.toList(), v2.toList()); + + else if (id == QVariant::Map) + return compare(v1.toMap(), v2.toMap()); + + else if (id == QVariant::String) + return compare(v1.toString(), v2.toString()); + + else if (id == QVariant::ByteArray) + return compare(v1.toByteArray(), v2.toByteArray()); + + else if (id < int(QVariant::UserType)) // yes, v1.type() + // QVariant can compare + return v1 == v2; + + else if (id == QMetaType::UChar) + return qvariant_cast(v1) == qvariant_cast(v2); + + else if (id == QMetaType::Short) + return qvariant_cast(v1) == qvariant_cast(v2); + + else if (id == QMetaType::UShort) + return qvariant_cast(v1) == qvariant_cast(v2); + + else if (id == qMetaTypeId()) + return qvariant_cast(v1).path() == qvariant_cast(v2).path(); + + else if (id == qMetaTypeId()) + return qvariant_cast(v1).signature() == qvariant_cast(v2).signature(); + + else if (id == qMetaTypeId()) + return compare(qvariant_cast(v1).variant(), qvariant_cast(v2).variant()); + + else if (id == qMetaTypeId()) + return compare(qvariant_cast(v1), qvariant_cast(v2)); + + else if (id == qMetaTypeId >()) + return qvariant_cast >(v1) == qvariant_cast >(v2); + + else if (id == qMetaTypeId >()) + return qvariant_cast >(v1) == qvariant_cast >(v2); + + else if (id == qMetaTypeId >()) + return qvariant_cast >(v1) == qvariant_cast >(v2); + + else if (id == qMetaTypeId >()) + return qvariant_cast >(v1) == qvariant_cast >(v2); + + else if (id == qMetaTypeId >()) + return qvariant_cast >(v1) == qvariant_cast >(v2); + + else if (id == qMetaTypeId >()) + return qvariant_cast >(v1) == qvariant_cast >(v2); + + else if (id == qMetaTypeId >()) + return qvariant_cast >(v2) == qvariant_cast >(v2); + + else if (id == qMetaTypeId >()) + return compare(qvariant_cast >(v1), qvariant_cast >(v2)); + + else if (id == qMetaTypeId()) + return compare(qvariant_cast(v1), qvariant_cast(v2)); + + else if (id == qMetaTypeId > >()) + return qvariant_cast > >(v1) == qvariant_cast > >(v2); + + else if (id == qMetaTypeId > >()) + return qvariant_cast > >(v1) == qvariant_cast > >(v2); + + else if (id == qMetaTypeId > >()) + return qvariant_cast > >(v1) == qvariant_cast > >(v2); + + else if (id == qMetaTypeId > >()) + return qvariant_cast > >(v1) == qvariant_cast > >(v2); + + else if (id == qMetaTypeId > >()) + return qvariant_cast > >(v1) == qvariant_cast > >(v2); + + else if (id == qMetaTypeId > >()) + return qvariant_cast > >(v1) == qvariant_cast > >(v2); + + else if (id == qMetaTypeId > >()) + return qvariant_cast > >(v1) == qvariant_cast > >(v2); + + else if (id == qMetaTypeId > >()) + return compare(qvariant_cast > >(v1), qvariant_cast > >(v2)); + + else if (id == qMetaTypeId >()) + return qvariant_cast >(v1) == qvariant_cast >(v2); + + else if (id == qMetaTypeId >()) + return qvariant_cast >(v1) == qvariant_cast >(v2); + + else if (id == qMetaTypeId >()) + return compare(qvariant_cast >(v1), qvariant_cast >(v2)); + + else if (id == qMetaTypeId >()) + return compare(qvariant_cast >(v1), qvariant_cast >(v2)); + + else if (id == qMetaTypeId >()) // ssmap + return compare(qvariant_cast >(v1), qvariant_cast >(v2)); + + else if (id == qMetaTypeId >()) + return compare(qvariant_cast >(v1), qvariant_cast >(v2)); + + else if (id == qMetaTypeId >()) // lldtmap + return compare(qvariant_cast >(v1), qvariant_cast >(v2)); + + else if (id == qMetaTypeId >()) + return compare(qvariant_cast >(v1), qvariant_cast >(v2)); + + else if (id == qMetaTypeId()) // (is) + return qvariant_cast(v1) == qvariant_cast(v2); + + else { + qWarning() << "Please write a comparison case for type" << v1.typeName(); + return false; // unknown type + } +} + +#if 0 +bool compare(const QVariantList &l1, const QVariantList &l2) +{ + if (l1.count() != l2.size()) + return false; + QVariantList::ConstIterator i1 = l1.constBegin(); + QVariantList::ConstIterator i2 = l2.constBegin(); + QVariantList::ConstIterator end = l1.constEnd(); + for ( ; i1 != end; ++i1, ++i2) { + if (!compare(*i1, *i2)) + return false; + } + return true; +} + +bool compare(const QVariantMap &m1, const QVariantMap &m2) +{ + if (m1.count() != m2.size()) + return false; + QVariantMap::ConstIterator i1 = m1.constBegin(); + QVariantMap::ConstIterator end = m1.constEnd(); + for ( ; i1 != end; ++i1) { + QVariantMap::ConstIterator i2 = m2.find(i1.key()); + if (i2 == m2.constEnd()) + return false; + if (!compare(*i1, *i2)) + return false; + } + return true; +} +#endif