From 171c8b3dd904d3adf26d00ebaa0f372c1a8a5c71 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 22 Feb 2011 10:45:16 +0100 Subject: Autotest: Use the shadow-build trick in all platforms --- tests/auto/qsslkey/tst_qsslkey.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/auto/qsslkey/tst_qsslkey.cpp b/tests/auto/qsslkey/tst_qsslkey.cpp index e7b4740..86da09e 100644 --- a/tests/auto/qsslkey/tst_qsslkey.cpp +++ b/tests/auto/qsslkey/tst_qsslkey.cpp @@ -108,10 +108,8 @@ tst_QSslKey::tst_QSslKey() #ifdef Q_WS_MAC // applicationDirPath() points to a path inside the app bundle on Mac. QDir dir(qApp->applicationDirPath() + QLatin1String("/../../../keys")); -#elif defined(Q_OS_WIN) || defined (Q_OS_SYMBIAN) - QDir dir(SRCDIR + QLatin1String("/keys")); // prefer this way to avoid ifdeffery and support shadow builds? #else - QDir dir(qApp->applicationDirPath() + QLatin1String("/keys")); + QDir dir(SRCDIR + QLatin1String("/keys")); // prefer this way to avoid ifdeffery and support shadow builds? #endif QFileInfoList fileInfoList = dir.entryInfoList(QDir::Files | QDir::Readable); QRegExp rx(QLatin1String("^(rsa|dsa)-(pub|pri)-(\\d+)\\.(pem|der)$")); -- cgit v0.12 From 38d92bd2511ed56d7a7eece20a370e818fb8d05c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 13 Apr 2011 14:33:55 +0200 Subject: Disable the JavaScriptCore JIT in ICC. As of ICC 12.0.2, ICC is known to miscompile some "fastcall" code, which causes runtime crashes. This fault has been reported to Intel and a fix is being prepared. Reviewed-by: Olivier Goffart --- configure | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/configure b/configure index 1369b82..30647c8 100755 --- a/configure +++ b/configure @@ -6750,8 +6750,15 @@ if [ "$CFG_JAVASCRIPTCORE_JIT" = "yes" ] || [ "$CFG_JAVASCRIPTCORE_JIT" = "auto" if [ $? != "0" ]; then CFG_JAVASCRIPTCORE_JIT=no fi - elif [ "$XPLATFORM" = "symbian-gcce" ]; then - CFG_JAVASCRIPTCORE_JIT=no + else + case "$XPLATFORM" in + symbian-gcce) + CFG_JAVASCRIPTCORE_JIT=no + ;; + linux-icc*) + CFG_JAVASCRIPTCORE_JIT=no + ;; + esac fi fi @@ -8585,7 +8592,7 @@ case "$CFG_WEBKIT" in debug) echo "WebKit module .......... yes (debug)" ;; no) echo "WebKit module .......... no" ;; esac -if [ "$CFG_WEBKIT" != "no" ]; then +if [ "$CFG_WEBKIT" != "no" ] || [ "$CFG_SCRIPT" != "no" ]; then if [ "$CFG_JAVASCRIPTCORE_JIT" = "auto" ]; then echo "JavaScriptCore JIT ..... To be decided by JavaScriptCore" else -- cgit v0.12 From 240ef633b827b33e2af63ff605eff5e1e71e623d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 15 Feb 2011 09:49:34 +0100 Subject: Add the QDBusUnixFileDescriptor class This class holds one Unix file descriptor. It's implicitly shared, but it makes a copy of your file descriptor (via dup(2) or dup2(2)). This class is supposed to work even outside Unix systems, just that it will never do anything. Documentation in a later commit. Task-number: QTBUG-17477 --- src/dbus/dbus.pro | 6 +- src/dbus/qdbusunixfiledescriptor.cpp | 175 +++++++++++++++++++++++++++++++++++ src/dbus/qdbusunixfiledescriptor.h | 103 +++++++++++++++++++++ 3 files changed, 282 insertions(+), 2 deletions(-) create mode 100644 src/dbus/qdbusunixfiledescriptor.cpp create mode 100644 src/dbus/qdbusunixfiledescriptor.h diff --git a/src/dbus/dbus.pro b/src/dbus/dbus.pro index 52ed217..08c9ea1 100644 --- a/src/dbus/dbus.pro +++ b/src/dbus/dbus.pro @@ -59,7 +59,8 @@ HEADERS += $$PUB_HEADERS \ qdbusintegrator_p.h \ qdbuspendingcall_p.h \ qdbus_symbols_p.h \ - qdbusservicewatcher.h + qdbusservicewatcher.h \ + qdbusunixfiledescriptor.h SOURCES += qdbusconnection.cpp \ qdbusconnectioninterface.cpp \ qdbuserror.cpp \ @@ -85,4 +86,5 @@ SOURCES += qdbusconnection.cpp \ qdbuspendingcall.cpp \ qdbuspendingreply.cpp \ qdbus_symbols.cpp \ - qdbusservicewatcher.cpp + qdbusservicewatcher.cpp \ + qdbusunixfiledescriptor.cpp diff --git a/src/dbus/qdbusunixfiledescriptor.cpp b/src/dbus/qdbusunixfiledescriptor.cpp new file mode 100644 index 0000000..368753c --- /dev/null +++ b/src/dbus/qdbusunixfiledescriptor.cpp @@ -0,0 +1,175 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the FOO module 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 "qdbusunixfiledescriptor.h" +#include + +#ifdef Q_OS_UNIX +# include +#endif + +class QDBusUnixFileDescriptorPrivate : public QSharedData { +public: + QDBusUnixFileDescriptorPrivate() : fd(-1) { } + QDBusUnixFileDescriptorPrivate(const QDBusUnixFileDescriptorPrivate &other) + : QSharedData(other), fd(-1) + { } + ~QDBusUnixFileDescriptorPrivate(); + + QAtomicInt fd; +}; + +template<> inline +QExplicitlySharedDataPointer::~QExplicitlySharedDataPointer() +{ if (d && !d->ref.deref()) delete d; } + +QDBusUnixFileDescriptor::QDBusUnixFileDescriptor() + : d(0) +{ +} + +QDBusUnixFileDescriptor::QDBusUnixFileDescriptor(int fileDescriptor) + : d(0) +{ + if (fileDescriptor != -1) + setFileDescriptor(fileDescriptor); +} + +QDBusUnixFileDescriptor::QDBusUnixFileDescriptor(const QDBusUnixFileDescriptor &other) + : d(other.d) +{ +} + +QDBusUnixFileDescriptor &QDBusUnixFileDescriptor::operator=(const QDBusUnixFileDescriptor &other) +{ + if (this != &other) + d.operator=(other.d); + return *this; +} + +QDBusUnixFileDescriptor::~QDBusUnixFileDescriptor() +{ +} + +bool QDBusUnixFileDescriptor::isValid() const +{ + return d ? d->fd != -1 : false; +} + +bool QDBusUnixFileDescriptor::isShared() const +{ + return d && d->ref == 1; +} + +int QDBusUnixFileDescriptor::fileDescriptor() const +{ + return d ? d->fd.operator int() : -1; +} + +// actual implementation +#ifdef Q_OS_UNIX + +bool QDBusUnixFileDescriptor::isSupported() +{ + return true; +} + +void QDBusUnixFileDescriptor::setFileDescriptor(int fileDescriptor) +{ + if (fileDescriptor != -1) + giveFileDescriptor(qt_safe_dup(fileDescriptor)); +} + +void QDBusUnixFileDescriptor::giveFileDescriptor(int fileDescriptor) +{ + // if we are the sole ref, d remains unchanged + // if detaching happens, d->fd will be -1 + if (d) + d.detach(); + else + d = new QDBusUnixFileDescriptorPrivate; + + if (d->fd != -1) + qt_safe_close(d->fd); + + if (fileDescriptor != -1) + d->fd = fileDescriptor; +} + +int QDBusUnixFileDescriptor::takeFileDescriptor() +{ + if (!d) + return -1; + + return d->fd.fetchAndStoreRelaxed(-1); +} + +QDBusUnixFileDescriptorPrivate::~QDBusUnixFileDescriptorPrivate() +{ + if (fd != -1) + qt_safe_close(fd); +} + +#else +bool QDBusUnixFileDescriptor::isSupported() +{ + return false; +} + +void QDBusUnixFileDescriptor::setFileDescriptor(int) +{ +} + +void QDBusUnixFileDescriptor::giveFileDescriptor(int) +{ +} + +int QDBusUnixFileDescriptor::takeFileDescriptor() +{ + return -1; +} + +QDBusUnixFileDescriptorPrivate::~QDBusUnixFileDescriptorPrivate() +{ +} + +#endif diff --git a/src/dbus/qdbusunixfiledescriptor.h b/src/dbus/qdbusunixfiledescriptor.h new file mode 100644 index 0000000..3ac3f9f --- /dev/null +++ b/src/dbus/qdbusunixfiledescriptor.h @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the FOO module 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$ +** +****************************************************************************/ + + +#ifndef QDBUSUNIXFILEDESCRIPTOR_H +#define QDBUSUNIXFILEDESCRIPTOR_H + +#include +#include + +#ifndef QT_NO_DBUS + +#ifdef Q_COMPILER_RVALUE_REFS +# include +#endif + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(DBus) + +class QDBusUnixFileDescriptorPrivate; +template<> QExplicitlySharedDataPointer::~QExplicitlySharedDataPointer(); + +class Q_DBUS_EXPORT QDBusUnixFileDescriptor +{ +public: + QDBusUnixFileDescriptor(); + explicit QDBusUnixFileDescriptor(int fileDescriptor); + QDBusUnixFileDescriptor(const QDBusUnixFileDescriptor &other); + QDBusUnixFileDescriptor &operator=(const QDBusUnixFileDescriptor &other); + ~QDBusUnixFileDescriptor(); + + bool isValid() const; + bool isShared() const; + + int fileDescriptor() const; + void setFileDescriptor(int fileDescriptor); + + void giveFileDescriptor(int fileDescriptor); + int takeFileDescriptor(); + + static bool isSupported(); + +#if defined(Q_COMPILER_RVALUE_REFS) + QDBusUnixFileDescriptor(QDBusUnixFileDescriptor &&other) : d(static_cast(other.d)) + { } + inline QDBusUnixFileDescriptor &operator=(QDBusUnixFileDescriptor &&other) + { d.swap(other.d); return *this; } +#endif + +protected: + typedef QExplicitlySharedDataPointer Data; + Data d; +}; + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QDBusUnixFileDescriptor) + +QT_END_HEADER + +#endif // QT_NO_DBUS +#endif // QDBUSUNIXFILEDESCRIPTOR_H -- cgit v0.12 From 65c2711cadeaa0f543cf56d7172d37b90b15be27 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 15 Feb 2011 09:53:33 +0100 Subject: Add QDBusUnixFileDescriptor to the QtDBus metatype system Task-number: QTBUG-17477 --- src/dbus/qdbusmetatype.cpp | 15 ++++++++++++++- src/dbus/qdbusmetatype_p.h | 1 + src/dbus/qdbusutil.cpp | 5 +++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/dbus/qdbusmetatype.cpp b/src/dbus/qdbusmetatype.cpp index 9f29205..a361762 100644 --- a/src/dbus/qdbusmetatype.cpp +++ b/src/dbus/qdbusmetatype.cpp @@ -50,12 +50,18 @@ #include #include "qdbusmessage.h" +#include "qdbusunixfiledescriptor.h" #include "qdbusutil_p.h" #include "qdbusmetatype_p.h" #include "qdbusargument_p.h" #ifndef QT_NO_DBUS +#ifndef DBUS_TYPE_UNIX_FD +# define DBUS_TYPE_UNIX_FD int('h') +# define DBUS_TYPE_UNIX_FD_AS_STRING "h" +#endif + Q_DECLARE_METATYPE(QList) Q_DECLARE_METATYPE(QList) Q_DECLARE_METATYPE(QList) @@ -96,6 +102,7 @@ int QDBusMetaTypeId::variant; int QDBusMetaTypeId::objectpath; int QDBusMetaTypeId::signature; int QDBusMetaTypeId::error; +int QDBusMetaTypeId::unixfd; void QDBusMetaTypeId::init() { @@ -110,7 +117,8 @@ void QDBusMetaTypeId::init() variant = qRegisterMetaType("QDBusVariant"); objectpath = qRegisterMetaType("QDBusObjectPath"); signature = qRegisterMetaType("QDBusSignature"); - error = qRegisterMetaType("QDBusError"); + error = qRegisterMetaType("QDBusError"); + unixfd = qRegisterMetaType("QDBusUnixFileDescriptor"); #ifndef QDBUS_NO_SPECIALTYPES // and register QtCore's with us @@ -343,6 +351,9 @@ int QDBusMetaType::signatureToType(const char *signature) case DBUS_TYPE_SIGNATURE: return QDBusMetaTypeId::signature; + case DBUS_TYPE_UNIX_FD: + return QDBusMetaTypeId::unixfd; + case DBUS_TYPE_VARIANT: return QDBusMetaTypeId::variant; @@ -432,6 +443,8 @@ const char *QDBusMetaType::typeToSignature(int type) return DBUS_TYPE_OBJECT_PATH_AS_STRING; else if (type == QDBusMetaTypeId::signature) return DBUS_TYPE_SIGNATURE_AS_STRING; + else if (type == QDBusMetaTypeId::unixfd) + return DBUS_TYPE_UNIX_FD_AS_STRING; // try the database QVector *ct = customTypes(); diff --git a/src/dbus/qdbusmetatype_p.h b/src/dbus/qdbusmetatype_p.h index 2fce133..b931c75 100644 --- a/src/dbus/qdbusmetatype_p.h +++ b/src/dbus/qdbusmetatype_p.h @@ -65,6 +65,7 @@ struct QDBusMetaTypeId static int objectpath; // QDBusObjectPath static int signature; // QDBusSignature static int error; // QDBusError + static int unixfd; // QDBusUnixFileDescriptor static void init(); }; diff --git a/src/dbus/qdbusutil.cpp b/src/dbus/qdbusutil.cpp index 9730f54..844af9a 100644 --- a/src/dbus/qdbusutil.cpp +++ b/src/dbus/qdbusutil.cpp @@ -46,6 +46,7 @@ #include #include "qdbusargument.h" +#include "qdbusunixfiledescriptor.h" #ifndef QT_NO_DBUS @@ -130,6 +131,10 @@ static bool variantToString(const QVariant &arg, QString &out) } else if (argType == qMetaTypeId()) { out += QLatin1String("[Signature: ") + qvariant_cast(arg).signature(); out += QLatin1Char(']'); + } else if (argType == qMetaTypeId()) { + out += QLatin1String("[Unix FD: "); + out += QLatin1String(qvariant_cast(arg).isValid() ? "valid" : "not valid"); + out += QLatin1Char(']'); } else if (argType == qMetaTypeId()) { const QVariant v = qvariant_cast(arg).variant(); out += QLatin1String("[Variant"); -- cgit v0.12 From fe5822786526c69fc5566d480d4b37a5365db4e2 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 16 Feb 2011 12:14:03 +0100 Subject: Add support for D-Bus 1.4 features in QtDBus code Task-number: QTBUG-17477 --- src/dbus/qdbus_symbols_p.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/dbus/qdbus_symbols_p.h b/src/dbus/qdbus_symbols_p.h index c5f55af..d0a4b3e 100644 --- a/src/dbus/qdbus_symbols_p.h +++ b/src/dbus/qdbus_symbols_p.h @@ -296,6 +296,12 @@ DEFINEFUNC(dbus_bool_t , dbus_message_set_sender, (DBusMessage *message, DEFINEFUNC(void , dbus_message_unref, (DBusMessage *message), (message), ) +/* dbus-misc.h */ +DEFINEFUNC(void , dbus_get_version , (int *major_version_p, + int *minor_version_p, + int *micro_version_p), + (major_version_p, minor_version_p, micro_version_p), ) + /* dbus-pending-call.h */ DEFINEFUNC(dbus_bool_t , dbus_pending_call_set_notify, (DBusPendingCall *pending, DBusPendingCallNotifyFunction function, @@ -367,6 +373,14 @@ DEFINEFUNC(dbus_bool_t , dbus_type_is_fixed, (int typecode), /* dbus-thread.h */ DEFINEFUNC(dbus_bool_t , dbus_threads_init_default, (), (), return) + +/* D-Bus 1.4 symbols */ +#if !defined(QT_LINKED_LIBDBUS) || (DBUS_VERSION >= 0x010400) +DEFINEFUNC(dbus_bool_t , dbus_connection_can_send_type , (DBusConnection *connection, + int type), + (connection, type), return) +#endif + QT_END_NAMESPACE #endif // QT_NO_DBUS -- cgit v0.12 From 8334e79a0340c9fcd5ccedeb867a84044d4d83dd Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 16 Feb 2011 12:25:09 +0100 Subject: Retrieve the connection capabilities in QDBusConnection Task-number: QTBUG-17477 --- src/dbus/qdbusintegrator.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index ee917a5..aaf19cf 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1667,6 +1667,28 @@ void QDBusConnectionPrivate::setPeer(DBusConnection *c, const QDBusErrorInternal QMetaObject::invokeMethod(this, "doDispatch", Qt::QueuedConnection); } +static QDBusConnection::ConnectionCapabilities connectionCapabilies(DBusConnection *connection) +{ + QDBusConnection::ConnectionCapabilities result = 0; + +#if defined(QT_LINKED_LIBDBUS) && DBUS_VERSION < 0x010400 + // no capabilities are possible +#else +# if !defined(QT_LINKED_LIBDBUS) + // run-time check if the next functions are available + int major, minor, micro; + q_dbus_get_version(&major, &minor, µ); + if (major == 1 && minor < 4) + return result; +# endif + + if (q_dbus_connection_can_send_type(connection, DBUS_TYPE_UNIX_FD)) + result |= QDBusConnection::UnixFileDescriptorPassing; +#endif + + return result; +} + void QDBusConnectionPrivate::setConnection(DBusConnection *dbc, const QDBusErrorInternal &error) { if (!dbc) { @@ -1680,6 +1702,7 @@ void QDBusConnectionPrivate::setConnection(DBusConnection *dbc, const QDBusError const char *service = q_dbus_bus_get_unique_name(connection); Q_ASSERT(service); baseService = QString::fromUtf8(service); + capabilities = connectionCapabilies(connection); q_dbus_connection_set_exit_on_disconnect(connection, false); q_dbus_connection_set_watch_functions(connection, qDBusAddWatch, qDBusRemoveWatch, -- cgit v0.12 From 6d325d6f70c419d1fee49da1738633a3e03b46d4 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 16 Feb 2011 15:04:57 +0100 Subject: Add support for Unix file-descriptor passing to QtDBus Task-number: QTBUG-17477 --- src/dbus/qdbusargument.cpp | 28 ++++++++++++++++++++++++++ src/dbus/qdbusargument.h | 4 ++++ src/dbus/qdbusargument_p.h | 8 ++++++++ src/dbus/qdbusdemarshaller.cpp | 17 ++++++++++++++++ src/dbus/qdbusmarshaller.cpp | 20 +++++++++++++++++- src/dbus/qdbusmetatype.cpp | 1 + src/dbus/qdbusunixfiledescriptor.h | 1 + tests/auto/qdbusmarshall/common.h | 11 ++++++++++ tests/auto/qdbusmarshall/qdbusmarshall.pro | 2 ++ tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp | 23 +++++++++++++++++++++ 10 files changed, 114 insertions(+), 1 deletion(-) diff --git a/src/dbus/qdbusargument.cpp b/src/dbus/qdbusargument.cpp index 09f0e82..806b7fe 100644 --- a/src/dbus/qdbusargument.cpp +++ b/src/dbus/qdbusargument.cpp @@ -487,6 +487,20 @@ QDBusArgument &QDBusArgument::operator<<(const QDBusSignature &arg) /*! \overload + \since 4.8 + \internal + Appends the primitive value \a arg of type \c{UNIX_FILE_DESCRIPTOR} (Unix + File Descriptor) to the D-Bus stream. +*/ +QDBusArgument &QDBusArgument::operator<<(const QDBusUnixFileDescriptor &arg) +{ + if (QDBusArgumentPrivate::checkWrite(d)) + d->marshaller()->append(arg); + return *this; +} + +/*! + \overload Appends the primitive value \a arg of type \c{VARIANT} to the D-Bus stream. A D-Bus variant type can contain any type, including other @@ -729,6 +743,20 @@ const QDBusArgument &QDBusArgument::operator>>(QDBusSignature &arg) const /*! \overload + \since 4.8 + \internal + Extracts one D-Bus primitive argument of type \c{UNIX_FILE_DESCRIPTOR} + (Unix file descriptor) from the D-Bus stream. +*/ +const QDBusArgument &QDBusArgument::operator>>(QDBusUnixFileDescriptor &arg) const +{ + if (QDBusArgumentPrivate::checkReadAndDetach(d)) + arg = d->demarshaller()->toUnixFileDescriptor(); + return *this; +} + +/*! + \overload Extracts one D-Bus primitive argument of type \c{VARIANT} from the D-Bus stream. diff --git a/src/dbus/qdbusargument.h b/src/dbus/qdbusargument.h index e331d8f..f80723e 100644 --- a/src/dbus/qdbusargument.h +++ b/src/dbus/qdbusargument.h @@ -61,6 +61,8 @@ QT_BEGIN_NAMESPACE QT_MODULE(DBus) +class QDBusUnixFileDescriptor; + class QDBusArgumentPrivate; class QDBusDemarshaller; class QDBusMarshaller; @@ -96,6 +98,7 @@ public: QDBusArgument &operator<<(const QDBusVariant &arg); QDBusArgument &operator<<(const QDBusObjectPath &arg); QDBusArgument &operator<<(const QDBusSignature &arg); + QDBusArgument &operator<<(const QDBusUnixFileDescriptor &arg); QDBusArgument &operator<<(const QStringList &arg); QDBusArgument &operator<<(const QByteArray &arg); @@ -127,6 +130,7 @@ public: const QDBusArgument &operator>>(QDBusVariant &arg) const; const QDBusArgument &operator>>(QDBusObjectPath &arg) const; const QDBusArgument &operator>>(QDBusSignature &arg) const; + const QDBusArgument &operator>>(QDBusUnixFileDescriptor &arg) const; const QDBusArgument &operator>>(QStringList &arg) const; const QDBusArgument &operator>>(QByteArray &arg) const; diff --git a/src/dbus/qdbusargument_p.h b/src/dbus/qdbusargument_p.h index 89a383f..1c713a3 100644 --- a/src/dbus/qdbusargument_p.h +++ b/src/dbus/qdbusargument_p.h @@ -54,10 +54,16 @@ // #include +#include "qdbusunixfiledescriptor.h" #include "qdbus_symbols_p.h" #ifndef QT_NO_DBUS +#ifndef DBUS_TYPE_UNIX_FD +# define DBUS_TYPE_UNIX_FD int('h') +# define DBUS_TYPE_UNIX_FD_AS_STRING "h" +#endif + QT_BEGIN_NAMESPACE class QDBusMarshaller; @@ -117,6 +123,7 @@ public: void append(const QString &arg); void append(const QDBusObjectPath &arg); void append(const QDBusSignature &arg); + void append(const QDBusUnixFileDescriptor &arg); void append(const QStringList &arg); void append(const QByteArray &arg); bool append(const QDBusVariant &arg); // this one can fail @@ -172,6 +179,7 @@ public: QString toString(); QDBusObjectPath toObjectPath(); QDBusSignature toSignature(); + QDBusUnixFileDescriptor toUnixFileDescriptor(); QDBusVariant toVariant(); QStringList toStringList(); QByteArray toByteArray(); diff --git a/src/dbus/qdbusdemarshaller.cpp b/src/dbus/qdbusdemarshaller.cpp index 111122e..3910381 100644 --- a/src/dbus/qdbusdemarshaller.cpp +++ b/src/dbus/qdbusdemarshaller.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qdbusargument_p.h" +#include "qdbusconnection.h" #include QT_BEGIN_NAMESPACE @@ -126,6 +127,13 @@ inline QDBusSignature QDBusDemarshaller::toSignature() return QDBusSignature(QString::fromUtf8(qIterGet(&iterator))); } +inline QDBusUnixFileDescriptor QDBusDemarshaller::toUnixFileDescriptor() +{ + QDBusUnixFileDescriptor fd; + fd.giveFileDescriptor(qIterGet(&iterator)); + return fd; +} + inline QDBusVariant QDBusDemarshaller::toVariant() { QDBusDemarshaller sub(capabilities); @@ -173,6 +181,10 @@ QDBusArgument::ElementType QDBusDemarshaller::currentType() case DBUS_TYPE_DICT_ENTRY: return QDBusArgument::MapEntryType; + case DBUS_TYPE_UNIX_FD: + return capabilities & QDBusConnection::UnixFileDescriptorPassing ? + QDBusArgument::BasicType : QDBusArgument::UnknownType; + case DBUS_TYPE_INVALID: return QDBusArgument::UnknownType; @@ -231,6 +243,11 @@ QVariant QDBusDemarshaller::toVariantInternal() case DBUS_TYPE_STRUCT: return QVariant::fromValue(duplicate()); + case DBUS_TYPE_UNIX_FD: + if (capabilities & QDBusConnection::UnixFileDescriptorPassing) + return qVariantFromValue(toUnixFileDescriptor()); + // fall through + default: // qWarning("QDBusDemarshaller: Found unknown D-Bus type %d '%c'", // q_dbus_message_iter_get_arg_type(&iterator), diff --git a/src/dbus/qdbusmarshaller.cpp b/src/dbus/qdbusmarshaller.cpp index 76d76cc..edf743e 100644 --- a/src/dbus/qdbusmarshaller.cpp +++ b/src/dbus/qdbusmarshaller.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qdbusargument_p.h" +#include "qdbusconnection.h" #include "qdbusmetatype_p.h" #include "qdbusutil_p.h" @@ -138,6 +139,16 @@ inline void QDBusMarshaller::append(const QDBusSignature &arg) qIterAppend(&iterator, ba, DBUS_TYPE_SIGNATURE, &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); + } +} + inline void QDBusMarshaller::append(const QByteArray &arg) { if (ba) { @@ -474,6 +485,13 @@ bool QDBusMarshaller::appendVariantInternal(const QVariant &arg) qFatal("QDBusMarshaller::appendVariantInternal got a DICT_ENTRY!"); return false; + case DBUS_TYPE_UNIX_FD: + if (capabilities & QDBusConnection::UnixFileDescriptorPassing || ba) { + append(qvariant_cast(arg)); + return true; + } + // fall through + default: qWarning("QDBusMarshaller::appendVariantInternal: Found unknown D-BUS type '%s'", signature); @@ -507,7 +525,7 @@ bool QDBusMarshaller::appendCrossMarshalling(QDBusDemarshaller *demarshaller) if (code == DBUS_TYPE_ARRAY) { int element = q_dbus_message_iter_get_element_type(&demarshaller->iterator); - if (q_dbus_type_is_fixed(element)) { + if (q_dbus_type_is_fixed(element) && element != DBUS_TYPE_UNIX_FD) { // another optimization: fixed size arrays // code is exactly like QDBusDemarshaller::toByteArray DBusMessageIter sub; diff --git a/src/dbus/qdbusmetatype.cpp b/src/dbus/qdbusmetatype.cpp index a361762..9d9112c 100644 --- a/src/dbus/qdbusmetatype.cpp +++ b/src/dbus/qdbusmetatype.cpp @@ -147,6 +147,7 @@ void QDBusMetaTypeId::init() qDBusRegisterMetaType >(); qDBusRegisterMetaType >(); qDBusRegisterMetaType >(); + qDBusRegisterMetaType >(); #endif initialized = true; diff --git a/src/dbus/qdbusunixfiledescriptor.h b/src/dbus/qdbusunixfiledescriptor.h index 3ac3f9f..92a770c 100644 --- a/src/dbus/qdbusunixfiledescriptor.h +++ b/src/dbus/qdbusunixfiledescriptor.h @@ -96,6 +96,7 @@ protected: QT_END_NAMESPACE Q_DECLARE_METATYPE(QDBusUnixFileDescriptor) +Q_DECLARE_METATYPE(QList) QT_END_HEADER diff --git a/tests/auto/qdbusmarshall/common.h b/tests/auto/qdbusmarshall/common.h index 532394a..b32b581 100644 --- a/tests/auto/qdbusmarshall/common.h +++ b/tests/auto/qdbusmarshall/common.h @@ -377,6 +377,14 @@ bool compare(const QHash &m1, const QHash &m2) return true; } +bool compare(const QDBusUnixFileDescriptor &t1, const QDBusUnixFileDescriptor &t2) +{ + int fd1 = t1.fileDescriptor(); + int fd2 = t2.fileDescriptor(); + + return (fd1 == -1) == (fd2 == -1); +} + template inline bool compare(const QDBusArgument &arg, const QVariant &v2, T * = 0) { @@ -563,6 +571,9 @@ template<> bool compare(const QVariant &v1, const QVariant &v2) else if (id == qMetaTypeId()) return qvariant_cast(v1).signature() == qvariant_cast(v2).signature(); + else if (id == qMetaTypeId()) + return compare(qvariant_cast(v1), qvariant_cast(v2)); + else if (id == qMetaTypeId()) return compare(qvariant_cast(v1).variant(), qvariant_cast(v2).variant()); diff --git a/tests/auto/qdbusmarshall/qdbusmarshall.pro b/tests/auto/qdbusmarshall/qdbusmarshall.pro index f8e0875..ad40c0d 100644 --- a/tests/auto/qdbusmarshall/qdbusmarshall.pro +++ b/tests/auto/qdbusmarshall/qdbusmarshall.pro @@ -3,6 +3,8 @@ contains(QT_CONFIG,dbus): { TEMPLATE = subdirs CONFIG += ordered SUBDIRS = qpong test + + requires(contains(QT_CONFIG,private_tests)) } else { SOURCES += dummy.cpp } diff --git a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp index 9bae6af..828a807 100644 --- a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp +++ b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include "common.h" #include @@ -167,6 +168,9 @@ void tst_QDBusMarshall::sendBasic_data() QTest::newRow("signature") << qVariantFromValue(QDBusSignature("g")) << "g" << "[Signature: g]"; QTest::newRow("emptystring") << QVariant("") << "s" << "\"\""; QTest::newRow("nullstring") << QVariant(QString()) << "s" << "\"\""; + + if (QDBusConnection::sessionBus().connectionCapabilities() & QDBusConnection::UnixFileDescriptorPassing) + QTest::newRow("file-descriptor") << qVariantFromValue(QDBusUnixFileDescriptor(0)) << "h" << "[Unix FD: valid]"; #endif } @@ -967,6 +971,21 @@ typedef QScopedPointer ScopedDBusConnection; typedef QScopedPointer > ScopedDBusMessage; typedef QScopedPointer > ScopedDBusPendingCall; +template struct SetResetValue +{ + const T oldValue; + T &value; +public: + SetResetValue(T &v, T newValue) : oldValue(v), value(v) + { + value = newValue; + } + ~SetResetValue() + { + value = oldValue; + } +}; + void tst_QDBusMarshall::receiveUnknownType() { #ifndef DBUS_TYPE_UNIX_FD @@ -986,6 +1005,10 @@ void tst_QDBusMarshall::receiveUnknownType() if (!dbus_connection_can_send_type(rawcon.data(), DBUS_TYPE_UNIX_FD)) QSKIP("Your session bus does not allow sending Unix file descriptors", SkipAll); + // make sure this QDBusConnection won't handle Unix file descriptors + QDBusConnection::ConnectionCapabilities &capabRef = QDBusConnectionPrivate::d(con)->capabilities; + SetResetValue resetter(capabRef, capabRef & ~QDBusConnection::UnixFileDescriptorPassing); + if (qstrcmp(QTest::currentDataTag(), "in-call") == 0) { // create a call back to us containing a file descriptor QDBusMessageSpy spy; -- cgit v0.12 From 376239da147f7954f49e1c18dd53afcd57c3f771 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 16 Feb 2011 15:30:49 +0100 Subject: Autotest: Test QDBusUnixFileDescriptor support in arrays Task-number: QTBUG-17477 --- tests/auto/qdbusmarshall/common.h | 2 ++ tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/tests/auto/qdbusmarshall/common.h b/tests/auto/qdbusmarshall/common.h index b32b581..dfa5206 100644 --- a/tests/auto/qdbusmarshall/common.h +++ b/tests/auto/qdbusmarshall/common.h @@ -475,6 +475,8 @@ bool compareToArgument(const QDBusArgument &arg, const QVariant &v2) 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); diff --git a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp index 828a807..df31ca2 100644 --- a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp +++ b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp @@ -95,6 +95,7 @@ private slots: private: QProcess proc; + bool fileDescriptorPassing; }; class QDBusMessageSpy: public QObject @@ -117,6 +118,7 @@ void tst_QDBusMarshall::initTestCase() { commonInit(); QDBusConnection con = QDBusConnection::sessionBus(); + fileDescriptorPassing = con.connectionCapabilities() & QDBusConnection::UnixFileDescriptorPassing; #ifdef Q_OS_WIN proc.start("qpong"); #else @@ -169,7 +171,7 @@ void tst_QDBusMarshall::sendBasic_data() QTest::newRow("emptystring") << QVariant("") << "s" << "\"\""; QTest::newRow("nullstring") << QVariant(QString()) << "s" << "\"\""; - if (QDBusConnection::sessionBus().connectionCapabilities() & QDBusConnection::UnixFileDescriptorPassing) + if (fileDescriptorPassing) QTest::newRow("file-descriptor") << qVariantFromValue(QDBusUnixFileDescriptor(0)) << "h" << "[Unix FD: valid]"; #endif } @@ -259,6 +261,18 @@ void tst_QDBusMarshall::sendArrays_data() << std::numeric_limits::quiet_NaN(); QTest::newRow("doublelist") << qVariantFromValue(doubles) << "ad" << "[Argument: ad {1.2, 2.2, 4.4, -inf, inf, nan}]"; + QList objectPaths; + QTest::newRow("emptyobjectpathlist") << qVariantFromValue(objectPaths) << "ao" << "[Argument: ao {}]"; + objectPaths << QDBusObjectPath("/") << QDBusObjectPath("/foo"); + QTest::newRow("objectpathlist") << qVariantFromValue(objectPaths) << "ao" << "[Argument: ao {[ObjectPath: /], [ObjectPath: /foo]}]"; + + if (fileDescriptorPassing) { + QList fileDescriptors; + QTest::newRow("emptyfiledescriptorlist") << qVariantFromValue(fileDescriptors) << "ah" << "[Argument: ah {}]"; + fileDescriptors << QDBusUnixFileDescriptor(0) << QDBusUnixFileDescriptor(1); + QTest::newRow("filedescriptorlist") << qVariantFromValue(fileDescriptors) << "ah" << "[Argument: ah {[Unix FD: valid], [Unix FD: valid]}]"; + } + QVariantList variants; QTest::newRow("emptyvariantlist") << QVariant(variants) << "av" << "[Argument: av {}]"; variants << QString("Hello") << QByteArray("World") << 42 << -43.0 << 44U << Q_INT64_C(-45) -- cgit v0.12 From f60b8f84332fcf5cb8be94ba8143595285baf134 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 16 Feb 2011 16:57:10 +0100 Subject: Autotest: more file-descriptor passing tests Task-number: QTBUG-17477 --- tests/auto/qdbusmarshall/common.h | 48 +++++++++++++++++++++----- tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp | 45 ++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 8 deletions(-) diff --git a/tests/auto/qdbusmarshall/common.h b/tests/auto/qdbusmarshall/common.h index dfa5206..53bd0e5 100644 --- a/tests/auto/qdbusmarshall/common.h +++ b/tests/auto/qdbusmarshall/common.h @@ -77,6 +77,14 @@ Q_DECLARE_METATYPE(ObjectPathStringMap) Q_DECLARE_METATYPE(LLDateTimeMap) Q_DECLARE_METATYPE(SignatureStringMap) +static bool compare(const QDBusUnixFileDescriptor &t1, const QDBusUnixFileDescriptor &t2) +{ + int fd1 = t1.fileDescriptor(); + int fd2 = t2.fileDescriptor(); + + return (fd1 == -1) == (fd2 == -1); +} + struct MyStruct { int i; @@ -130,6 +138,32 @@ const QDBusArgument &operator>>(const QDBusArgument &arg, MyVariantMapStruct &ms return arg; } +struct MyFileDescriptorStruct +{ + QDBusUnixFileDescriptor fd; + + inline bool operator==(const MyFileDescriptorStruct &other) const + { return compare(fd, other.fd); } +}; +Q_DECLARE_METATYPE(MyFileDescriptorStruct) +Q_DECLARE_METATYPE(QList) + +QDBusArgument &operator<<(QDBusArgument &arg, const MyFileDescriptorStruct &ms) +{ + arg.beginStructure(); + arg << ms.fd; + arg.endStructure(); + return arg; +} + +const QDBusArgument &operator>>(const QDBusArgument &arg, MyFileDescriptorStruct &ms) +{ + arg.beginStructure(); + arg >> ms.fd; + arg.endStructure(); + return arg; +} + void commonInit() { @@ -157,6 +191,8 @@ void commonInit() qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType >(); + qDBusRegisterMetaType(); + qDBusRegisterMetaType >(); } #ifdef USE_PRIVATE_CODE #include "private/qdbusintrospection_p.h" @@ -377,14 +413,6 @@ bool compare(const QHash &m1, const QHash &m2) return true; } -bool compare(const QDBusUnixFileDescriptor &t1, const QDBusUnixFileDescriptor &t2) -{ - int fd1 = t1.fileDescriptor(); - int fd2 = t2.fileDescriptor(); - - return (fd1 == -1) == (fd2 == -1); -} - template inline bool compare(const QDBusArgument &arg, const QVariant &v2, T * = 0) { @@ -521,6 +549,10 @@ bool compareToArgument(const QDBusArgument &arg, const QVariant &v2) 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() diff --git a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp index df31ca2..b7cec3e 100644 --- a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp +++ b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp @@ -474,6 +474,12 @@ void tst_QDBusMarshall::sendMaps_data() QTest::newRow("gs-map") << qVariantFromValue(gsmap) << "a{gs}" << "[Argument: a{gs} {[Signature: a{gs}] = \"array of dict_entry of (signature, string)\", [Signature: i] = \"int32\", [Signature: s] = \"string\"}]"; + if (fileDescriptorPassing) { + svmap["zzfiledescriptor"] = qVariantFromValue(QDBusUnixFileDescriptor(0)); + QTest::newRow("sv-map1-fd") << qVariantFromValue(svmap) << "a{sv}" + << "[Argument: a{sv} {\"a\" = [Variant(int): 1], \"b\" = [Variant(QByteArray): {99}], \"c\" = [Variant(QString): \"b\"], \"d\" = [Variant(uint): 42], \"e\" = [Variant(short): -47], \"f\" = [Variant: [Variant(int): 0]], \"zzfiledescriptor\" = [Variant(QDBusUnixFileDescriptor): [Unix FD: valid]]}]"; + } + svmap.clear(); svmap["ismap"] = qVariantFromValue(ismap); svmap["ssmap"] = qVariantFromValue(ssmap); @@ -527,6 +533,18 @@ void tst_QDBusMarshall::sendStructs_data() QTest::newRow("empty-list-of-string-variantmap") << qVariantFromValue(list) << "a(sa{sv})" << "[Argument: a(sa{sv}) {}]"; list << mvms; QTest::newRow("list-of-string-variantmap") << qVariantFromValue(list) << "a(sa{sv})" << "[Argument: a(sa{sv}) {[Argument: (sa{sv}) \"Hello, World\", [Argument: a{sv} {\"bytearray\" = [Variant(QByteArray): {72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100}], \"int\" = [Variant(int): 42], \"short\" = [Variant(short): -47], \"uint\" = [Variant(uint): 42]}]]}]"; + + if (fileDescriptorPassing) { + MyFileDescriptorStruct fds; + fds.fd = QDBusUnixFileDescriptor(0); + QTest::newRow("fdstruct") << qVariantFromValue(fds) << "(h)" << "[Argument: (h) [Unix FD: valid]]"; + + QList fdlist; + QTest::newRow("empty-list-of-fdstruct") << qVariantFromValue(fdlist) << "a(h)" << "[Argument: a(h) {}]"; + + fdlist << fds; + QTest::newRow("list-of-fdstruct") << qVariantFromValue(fdlist) << "a(h)" << "[Argument: a(h) {[Argument: (h) [Unix FD: valid]]}]"; + } } void tst_QDBusMarshall::sendComplex_data() @@ -660,6 +678,12 @@ void tst_QDBusMarshall::sendArgument_data() arg << QString(); QTest::newRow("nullstring") << qVariantFromValue(arg) << "s" << int(QDBusArgument::BasicType); + if (fileDescriptorPassing) { + arg = QDBusArgument(); + arg << QDBusUnixFileDescriptor(0); + QTest::newRow("filedescriptor") << qVariantFromValue(arg) << "h" << int(QDBusArgument::BasicType); + } + arg = QDBusArgument(); arg << QDBusVariant(1); QTest::newRow("variant") << qVariantFromValue(arg) << "v" << int(QDBusArgument::VariantType); @@ -920,6 +944,27 @@ void tst_QDBusMarshall::sendCallErrors_data() << "Marshalling failed: Unregistered type UnregisteredType passed in arguments" << QString("QDBusMarshaller: type `UnregisteredType' (%1) is not registered with D-BUS. Use qDBusRegisterMetaType to register it") .arg(qMetaTypeId()); + + QTest::newRow("invalid-object-path-arg") << serviceName << objectPath << interfaceName << "ping" + << (QVariantList() << qVariantFromValue(QDBusObjectPath())) + << "org.freedesktop.DBus.Error.Failed" + << "Marshalling failed: Invalid object path passed in arguments" + << ""; + + QTest::newRow("invalid-signature-arg") << serviceName << objectPath << interfaceName << "ping" + << (QVariantList() << qVariantFromValue(QDBusSignature())) + << "org.freedesktop.DBus.Error.Failed" + << "Marshalling failed: Invalid signature passed in arguments" + << ""; + + // invalid file descriptor + if (fileDescriptorPassing) { + QTest::newRow("invalid-file-descriptor") << serviceName << objectPath << interfaceName << "ping" + << (QVariantList() << qVariantFromValue(QDBusUnixFileDescriptor(-1))) + << "org.freedesktop.DBus.Error.Failed" + << "Marshalling failed: Invalid file descriptor passed in arguments" + << ""; + } } void tst_QDBusMarshall::sendCallErrors() -- cgit v0.12 From 7647521500b0d1c1e382fff0d1a0f497f1fac70c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 17 Feb 2011 17:01:14 +0100 Subject: Autotest: really ensure that two fds are equal Instead of checking that they are both valid or both invalid, test that they point to the same file on the filesystem. So we create a QTemporaryFile and pass its file descriptor to the remote side and back. If the two fds point to the same file on disk later (same st_dev and st_ino), they are equal. This probably works on non-Unix too, but I can't test and there's no point anyway. Task-number: QTBUG-17477 --- tests/auto/qdbusmarshall/common.h | 26 +++++++++++++++++++++++++- tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp | 22 +++++++++++++++++----- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/tests/auto/qdbusmarshall/common.h b/tests/auto/qdbusmarshall/common.h index 53bd0e5..8f7f3c3 100644 --- a/tests/auto/qdbusmarshall/common.h +++ b/tests/auto/qdbusmarshall/common.h @@ -39,6 +39,22 @@ ** ****************************************************************************/ #include // isnan +#include + +#ifdef Q_OS_UNIX +# include + +static bool compareFileDescriptors(int fd1, int fd2) +{ + QT_STATBUF st1, st2; + if (QT_FSTAT(fd1, &st1) == -1 || QT_FSTAT(fd2, &st2) == -1) { + perror("fstat"); + return false; + } + + return (st1.st_dev == st2.st_dev) && (st1.st_ino == st2.st_ino); +} +#endif Q_DECLARE_METATYPE(QVariant) Q_DECLARE_METATYPE(QList) @@ -81,8 +97,16 @@ static bool compare(const QDBusUnixFileDescriptor &t1, const QDBusUnixFileDescri { int fd1 = t1.fileDescriptor(); int fd2 = t2.fileDescriptor(); + if ((fd1 == -1 || fd2 == -1) && fd1 != fd2) { + // one is valid, the other isn't + return false; + } - return (fd1 == -1) == (fd2 == -1); +#ifdef Q_OS_UNIX + return compareFileDescriptors(fd1, fd2); +#else + return true; +#endif } struct MyStruct diff --git a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp index b7cec3e..737f0cf 100644 --- a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp +++ b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp @@ -94,7 +94,10 @@ private slots: void receiveUnknownType(); private: + int fileDescriptorForTest(); + QProcess proc; + QTemporaryFile tempFile; bool fileDescriptorPassing; }; @@ -147,6 +150,15 @@ void tst_QDBusMarshall::cleanupTestCase() proc.waitForFinished(200); } +int tst_QDBusMarshall::fileDescriptorForTest() +{ + if (!tempFile.isOpen()) { + tempFile.setFileTemplate(QDir::tempPath() + "/qdbusmarshalltestXXXXXX.tmp"); + tempFile.open(); + } + return tempFile.handle(); +} + void tst_QDBusMarshall::sendBasic_data() { QTest::addColumn("value"); @@ -172,7 +184,7 @@ void tst_QDBusMarshall::sendBasic_data() QTest::newRow("nullstring") << QVariant(QString()) << "s" << "\"\""; if (fileDescriptorPassing) - QTest::newRow("file-descriptor") << qVariantFromValue(QDBusUnixFileDescriptor(0)) << "h" << "[Unix FD: valid]"; + QTest::newRow("file-descriptor") << qVariantFromValue(QDBusUnixFileDescriptor(fileDescriptorForTest())) << "h" << "[Unix FD: valid]"; #endif } @@ -269,7 +281,7 @@ void tst_QDBusMarshall::sendArrays_data() if (fileDescriptorPassing) { QList fileDescriptors; QTest::newRow("emptyfiledescriptorlist") << qVariantFromValue(fileDescriptors) << "ah" << "[Argument: ah {}]"; - fileDescriptors << QDBusUnixFileDescriptor(0) << QDBusUnixFileDescriptor(1); + fileDescriptors << QDBusUnixFileDescriptor(fileDescriptorForTest()) << QDBusUnixFileDescriptor(1); QTest::newRow("filedescriptorlist") << qVariantFromValue(fileDescriptors) << "ah" << "[Argument: ah {[Unix FD: valid], [Unix FD: valid]}]"; } @@ -475,7 +487,7 @@ void tst_QDBusMarshall::sendMaps_data() << "[Argument: a{gs} {[Signature: a{gs}] = \"array of dict_entry of (signature, string)\", [Signature: i] = \"int32\", [Signature: s] = \"string\"}]"; if (fileDescriptorPassing) { - svmap["zzfiledescriptor"] = qVariantFromValue(QDBusUnixFileDescriptor(0)); + svmap["zzfiledescriptor"] = qVariantFromValue(QDBusUnixFileDescriptor(fileDescriptorForTest())); QTest::newRow("sv-map1-fd") << qVariantFromValue(svmap) << "a{sv}" << "[Argument: a{sv} {\"a\" = [Variant(int): 1], \"b\" = [Variant(QByteArray): {99}], \"c\" = [Variant(QString): \"b\"], \"d\" = [Variant(uint): 42], \"e\" = [Variant(short): -47], \"f\" = [Variant: [Variant(int): 0]], \"zzfiledescriptor\" = [Variant(QDBusUnixFileDescriptor): [Unix FD: valid]]}]"; } @@ -536,7 +548,7 @@ void tst_QDBusMarshall::sendStructs_data() if (fileDescriptorPassing) { MyFileDescriptorStruct fds; - fds.fd = QDBusUnixFileDescriptor(0); + fds.fd = QDBusUnixFileDescriptor(fileDescriptorForTest()); QTest::newRow("fdstruct") << qVariantFromValue(fds) << "(h)" << "[Argument: (h) [Unix FD: valid]]"; QList fdlist; @@ -680,7 +692,7 @@ void tst_QDBusMarshall::sendArgument_data() if (fileDescriptorPassing) { arg = QDBusArgument(); - arg << QDBusUnixFileDescriptor(0); + arg << QDBusUnixFileDescriptor(fileDescriptorForTest()); QTest::newRow("filedescriptor") << qVariantFromValue(arg) << "h" << int(QDBusArgument::BasicType); } -- cgit v0.12 From 0c8fa16ef1964c3d102413b44e18964f6b4793ec Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 13 Apr 2011 14:50:03 +0200 Subject: Doc: document the QDBusUnixFileDescriptor class --- src/dbus/qdbusunixfiledescriptor.cpp | 145 +++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) diff --git a/src/dbus/qdbusunixfiledescriptor.cpp b/src/dbus/qdbusunixfiledescriptor.cpp index 368753c..9cbaa8f 100644 --- a/src/dbus/qdbusunixfiledescriptor.cpp +++ b/src/dbus/qdbusunixfiledescriptor.cpp @@ -47,6 +47,59 @@ # include #endif +/*! + \class QDBusUnixFileDescriptor + \inmodule QtDBus + \since 4.8 + + \brief The QDBusUnixFileDescriptor class holds one Unix file descriptor. + + The QDBusUnixFileDescriptor class is used to hold one Unix file + descriptor for use with the QtDBus module. This allows applications to + send and receive Unix file descriptors over the D-Bus connection, mapping + automatically to the D-Bus type 'h'. + + Objects of type QDBusUnixFileDescriptors can be used also as parameters + in signals and slots that get exported to D-Bus by registering with + QDBusConnection::registerObject. + + QDBusUnixFileDescriptor does not take ownership of the file descriptor. + Instead, it will use the Unix system call \c dup(2) to make a copy of the + file descriptor. This file descriptor belongs to the + QDBusUnixFileDescriptor object and should not be stored or closed by the + user. Instead, you should make your own copy if you need that. + + \section2 Availability + + Unix file descriptor passing is not available in all D-Bus connections. + This feature is present with D-Bus library and bus daemon version 1.4 and + upwards on Unix systems. QtDBus automatically enables the feature if such + a version was found at compile-time and run-time. + + To verify that your connection does support passing file descriptors, + check if the QDBusConnection::UnixFileDescriptorPassing capability is set + with QDBusConnection::connectionCapabilities(). If the flag is not + active, then you will not be able to make calls to methods that have + QDBusUnixFileDescriptor as arguments or even embed such a type in a + variant. You will also not receive calls containing that type. + + Note also that remote applications may not have support for Unix file + descriptor passing. If you make a D-Bus to a remote application that + cannot receive such a type, you will receive an error reply. If you try + to send a signal containing a D-Bus file descriptor or return one from a + method call, the message will be silently dropped. + + Even if the feature is not available, QDBusUnixFileDescriptor will + continue to operate, so code need not have compile-time checks for the + availability of this feature. + + On non-Unix systems, QDBusUnixFileDescriptor will always report an + invalid state and QDBusUnixFileDescriptor::isSupported() will return + false. + + \sa QDBusConnection::ConnectionCapabilities, QDBusConnection::connectionCapabilities +*/ + class QDBusUnixFileDescriptorPrivate : public QSharedData { public: QDBusUnixFileDescriptorPrivate() : fd(-1) { } @@ -62,11 +115,31 @@ template<> inline QExplicitlySharedDataPointer::~QExplicitlySharedDataPointer() { if (d && !d->ref.deref()) delete d; } +/*! + Constructs a QDBusUnixFileDescriptor without a wrapped file descriptor. + This is equivalent to constructing the object with an invalid file + descriptor (like -1). + + \sa fileDescriptor, isValid +*/ QDBusUnixFileDescriptor::QDBusUnixFileDescriptor() : d(0) { } +/*! + Constructs a QDBusUnixFileDescriptor object by copying the \a + fileDescriptor parameter. The original file descriptor is not touched and + must be closed by the user. + + Note that the value returned by fileDescriptor() will be different from + the \a fileDescriptor parameter passed. + + If the \a fileDescriptor parameter is not valid, isValid() will return + false and fileDescriptor() will return -1. + + \sa setFileDescriptor, fileDescriptor +*/ QDBusUnixFileDescriptor::QDBusUnixFileDescriptor(int fileDescriptor) : d(0) { @@ -74,11 +147,19 @@ QDBusUnixFileDescriptor::QDBusUnixFileDescriptor(int fileDescriptor) setFileDescriptor(fileDescriptor); } +/*! + Constructs a QDBusUnixFileDescriptor object by copying \a other. +*/ QDBusUnixFileDescriptor::QDBusUnixFileDescriptor(const QDBusUnixFileDescriptor &other) : d(other.d) { } +/*! + Copies the Unix file descriptor from the \a other QDBusUnixFileDescriptor + object. If the current object contained a file descriptor, it will be + properly disposed of before. +*/ QDBusUnixFileDescriptor &QDBusUnixFileDescriptor::operator=(const QDBusUnixFileDescriptor &other) { if (this != &other) @@ -86,20 +167,45 @@ QDBusUnixFileDescriptor &QDBusUnixFileDescriptor::operator=(const QDBusUnixFileD return *this; } +/*! + Destroys this QDBusUnixFileDescriptor object and disposes of the Unix file descriptor that it contained. +*/ QDBusUnixFileDescriptor::~QDBusUnixFileDescriptor() { } +/*! + Returns true if this Unix file descriptor is valid. A valid Unix file + descriptor is not -1. + + \sa fileDescriptor() +*/ bool QDBusUnixFileDescriptor::isValid() const { return d ? d->fd != -1 : false; } +/*! + \internal +*/ bool QDBusUnixFileDescriptor::isShared() const { return d && d->ref == 1; } +/*! + Returns the Unix file descriptor contained by this + QDBusUnixFileDescriptor object. An invalid file descriptor is represented + by the value -1. + + Note that the file descriptor returned by this function is owned by the + QDBusUnixFileDescriptor object and must not be stored past the lifetime + of this object. It is ok to use it while this object is valid, but if one + wants to store it for longer use, the file descriptor should be cloned + using the Unix \c dup(2), \c dup2(2) or \c dup3(2) functions. + + \sa isValid() +*/ int QDBusUnixFileDescriptor::fileDescriptor() const { return d ? d->fd.operator int() : -1; @@ -108,17 +214,48 @@ int QDBusUnixFileDescriptor::fileDescriptor() const // actual implementation #ifdef Q_OS_UNIX +// qdoc documentation is generated on Unix + +/*! + Returns true if Unix file descriptors are supported on this platform. In + other words, this function returns true if this is a Unix platform. + + Note that QDBusUnixFileDescriptor continues to operate even if this + function returns false. The only difference is that the + QDBusUnixFileDescriptor objects will always be in the isValid() == false + state and fileDescriptor() will always return -1. The class will not + consume any operating system resources. +*/ bool QDBusUnixFileDescriptor::isSupported() { return true; } +/*! + Sets the file descriptor that this QDBusUnixFileDescriptor object holds + to a copy of \a fileDescriptor.T he original file descriptor is not + touched and must be closed by the user. + + Note that the value returned by fileDescriptor() will be different from + the \a fileDescriptor parameter passed. + + If the \a fileDescriptor parameter is not valid, isValid() will return + false and fileDescriptor() will return -1. + + \sa isValid(), fileDescriptor() +*/ void QDBusUnixFileDescriptor::setFileDescriptor(int fileDescriptor) { if (fileDescriptor != -1) giveFileDescriptor(qt_safe_dup(fileDescriptor)); } +/*! + \internal + Sets the Unix file descriptor to \a fileDescriptor without copying. + + \sa setFileDescriptor() +*/ void QDBusUnixFileDescriptor::giveFileDescriptor(int fileDescriptor) { // if we are the sole ref, d remains unchanged @@ -135,6 +272,14 @@ void QDBusUnixFileDescriptor::giveFileDescriptor(int fileDescriptor) d->fd = fileDescriptor; } +/*! + \internal + Extracts the Unix file descriptor from the QDBusUnixFileDescriptor object + and transfers ownership. + + Note: since QDBusUnixFileDescriptor is implicitly shared, this function + is inherently racy and should be avoided. +*/ int QDBusUnixFileDescriptor::takeFileDescriptor() { if (!d) -- cgit v0.12 From 0ee167c7d47c28d747e9ca73aa35fef21171b97f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 13 Apr 2011 14:52:49 +0200 Subject: Remove the unused QDBusUnixFileDescriptor::isShared function --- src/dbus/qdbusunixfiledescriptor.cpp | 8 -------- src/dbus/qdbusunixfiledescriptor.h | 1 - 2 files changed, 9 deletions(-) diff --git a/src/dbus/qdbusunixfiledescriptor.cpp b/src/dbus/qdbusunixfiledescriptor.cpp index 9cbaa8f..4817d95 100644 --- a/src/dbus/qdbusunixfiledescriptor.cpp +++ b/src/dbus/qdbusunixfiledescriptor.cpp @@ -186,14 +186,6 @@ bool QDBusUnixFileDescriptor::isValid() const } /*! - \internal -*/ -bool QDBusUnixFileDescriptor::isShared() const -{ - return d && d->ref == 1; -} - -/*! Returns the Unix file descriptor contained by this QDBusUnixFileDescriptor object. An invalid file descriptor is represented by the value -1. diff --git a/src/dbus/qdbusunixfiledescriptor.h b/src/dbus/qdbusunixfiledescriptor.h index 92a770c..d0a2f3c 100644 --- a/src/dbus/qdbusunixfiledescriptor.h +++ b/src/dbus/qdbusunixfiledescriptor.h @@ -71,7 +71,6 @@ public: ~QDBusUnixFileDescriptor(); bool isValid() const; - bool isShared() const; int fileDescriptor() const; void setFileDescriptor(int fileDescriptor); -- cgit v0.12 From b53a80ff1e1a1a5e8c66eaa20076be2745ffb88f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 21 Feb 2011 20:01:03 +0100 Subject: Add routines to validate D-Bus signature in QtDBus --- src/dbus/qdbusutil.cpp | 95 +++++++++++- src/dbus/qdbusutil_p.h | 4 + tests/auto/dbus.pro | 1 + tests/auto/qdbustype/qdbustype.pro | 10 ++ tests/auto/qdbustype/tst_qdbustype.cpp | 271 +++++++++++++++++++++++++++++++++ 5 files changed, 379 insertions(+), 2 deletions(-) create mode 100644 tests/auto/qdbustype/qdbustype.pro create mode 100644 tests/auto/qdbustype/tst_qdbustype.cpp diff --git a/src/dbus/qdbusutil.cpp b/src/dbus/qdbusutil.cpp index 844af9a..a4bd168 100644 --- a/src/dbus/qdbusutil.cpp +++ b/src/dbus/qdbusutil.cpp @@ -238,6 +238,68 @@ bool argToString(const QDBusArgument &busArg, QString &out) return true; } +//------- D-Bus Types -------- +static const char oneLetterTypes[] = "vsogybnqiuxtdh"; +static const char basicTypes[] = "sogybnqiuxtdh"; +static const char fixedTypes[] = "ybnqiuxtdh"; + +static bool isBasicType(int c) +{ + return c != DBUS_TYPE_INVALID && strchr(basicTypes, c) != NULL; +} + +static bool isFixedType(int c) +{ + return c != DBUS_TYPE_INVALID && strchr(fixedTypes, c) != NULL; +} + +// Returns a pointer to one-past-end of this type if it's valid; +// returns NULL if it isn't valid. +static const char *validateSingleType(const char *signature) +{ + register char c = *signature; + if (c == DBUS_TYPE_INVALID) + return false; + + // is it one of the one-letter types? + if (strchr(oneLetterTypes, c) != NULL) + return signature + 1; + + // is it an array? + if (c == DBUS_TYPE_ARRAY) { + // then it's valid if the next type is valid + // or if it's a dict-entry + c = *++signature; + if (c == DBUS_DICT_ENTRY_BEGIN_CHAR) { + // beginning of a dictionary entry + // a dictionary entry has a key which is of basic types + // and a free value + c = *++signature; + if (!isBasicType(c)) + return 0; + signature = validateSingleType(signature + 1); + return signature && *signature == DBUS_DICT_ENTRY_END_CHAR ? signature + 1 : 0; + } + + return validateSingleType(signature); + } + + if (c == DBUS_STRUCT_BEGIN_CHAR) { + // beginning of a struct + ++signature; + while (true) { + signature = validateSingleType(signature); + if (!signature) + return 0; + if (*signature == DBUS_STRUCT_END_CHAR) + return signature + 1; + } + } + + // invalid/unknown type + return 0; +} + /*! \namespace QDBusUtil \inmodule QtDBus @@ -447,6 +509,25 @@ namespace QDBusUtil } /*! + \fn bool QDBusUtil::isValidBasicType(int type) + Returns true if \a c is a valid, basic D-Bus type. + */ + bool isValidBasicType(int c) + { + return isBasicType(c); + } + + /*! + \fn bool QDBusUtil::isValidFixedType(int type) + Returns true if \a c is a valid, fixed D-Bus type. + */ + bool isValidFixedType(int c) + { + return isFixedType(c); + } + + + /*! \fn bool QDBusUtil::isValidSignature(const QString &signature) Returns true if \a signature is a valid D-Bus type signature for one or more types. This function returns true if it can all of \a signature into valid, individual types and no @@ -456,7 +537,15 @@ namespace QDBusUtil */ bool isValidSignature(const QString &signature) { - return q_dbus_signature_validate(signature.toUtf8(), 0); + QByteArray ba = signature.toLatin1(); + const char *data = ba.constData(); + while (true) { + data = validateSingleType(data); + if (!data) + return false; + if (*data == '\0') + return true; + } } /*! @@ -467,7 +556,9 @@ namespace QDBusUtil */ bool isValidSingleSignature(const QString &signature) { - return q_dbus_signature_validate_single(signature.toUtf8(), 0); + QByteArray ba = signature.toLatin1(); + const char *data = validateSingleType(ba.constData()); + return data && *data == '\0'; } } // namespace QDBusUtil diff --git a/src/dbus/qdbusutil_p.h b/src/dbus/qdbusutil_p.h index 3721e98..24b5cea 100644 --- a/src/dbus/qdbusutil_p.h +++ b/src/dbus/qdbusutil_p.h @@ -81,6 +81,10 @@ namespace QDBusUtil Q_DBUS_EXPORT bool isValidObjectPath(const QString &path); + Q_DBUS_EXPORT bool isValidFixedType(int c); + + Q_DBUS_EXPORT bool isValidBasicType(int c); + Q_DBUS_EXPORT bool isValidSignature(const QString &signature); Q_DBUS_EXPORT bool isValidSingleSignature(const QString &signature); diff --git a/tests/auto/dbus.pro b/tests/auto/dbus.pro index e5f87e3..fe21475 100644 --- a/tests/auto/dbus.pro +++ b/tests/auto/dbus.pro @@ -14,6 +14,7 @@ SUBDIRS=\ qdbusperformance \ qdbusreply \ qdbusservicewatcher \ + qdbustype \ qdbusthreading \ qdbusxmlparser \ diff --git a/tests/auto/qdbustype/qdbustype.pro b/tests/auto/qdbustype/qdbustype.pro new file mode 100644 index 0000000..e2f0c90 --- /dev/null +++ b/tests/auto/qdbustype/qdbustype.pro @@ -0,0 +1,10 @@ +load(qttest_p4) +QT = core +contains(QT_CONFIG,dbus): { + SOURCES += tst_qdbustype.cpp + QT += dbus + QMAKE_CXXFLAGS += $$QT_CFLAGS_DBUS + LIBS_PRIVATE += $$QT_LIBS_DBUS +} else { + SOURCES += ../qdbusmarshall/dummy.cpp +} diff --git a/tests/auto/qdbustype/tst_qdbustype.cpp b/tests/auto/qdbustype/tst_qdbustype.cpp new file mode 100644 index 0000000..0469719 --- /dev/null +++ b/tests/auto/qdbustype/tst_qdbustype.cpp @@ -0,0 +1,271 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the FOO module 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 +#include + +#include + +#include + +class tst_QDBusType : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void isValidFixedType_data(); + void isValidFixedType(); + void isValidBasicType_data(); + void isValidBasicType(); + void isValidSingleSignature_data(); + void isValidSingleSignature(); + void isValidArray_data(); + void isValidArray(); + void isValidSignature_data(); + void isValidSignature(); +}; + +enum { Invalid = false, Valid = true }; + +static void addColumns() +{ + // All tests use these two columns only + QTest::addColumn("data"); + QTest::addColumn("result"); + QTest::addColumn("isValid"); +} + +// ---- type adds --- +static void addFixedTypes() +{ + QTest::newRow("bool") << DBUS_TYPE_BOOLEAN_AS_STRING << true << true; + QTest::newRow("byte") << DBUS_TYPE_BYTE_AS_STRING << true << true; + QTest::newRow("int16") << DBUS_TYPE_INT16_AS_STRING << true << true; + QTest::newRow("uint16") << DBUS_TYPE_UINT16_AS_STRING << true << true; + QTest::newRow("int32") << DBUS_TYPE_INT32_AS_STRING << true << true; + QTest::newRow("uint32") << DBUS_TYPE_UINT32_AS_STRING << true << true; + QTest::newRow("int64") << DBUS_TYPE_INT64_AS_STRING << true << true; + QTest::newRow("uint64") << DBUS_TYPE_UINT64_AS_STRING << true << true; + QTest::newRow("double") << DBUS_TYPE_DOUBLE_AS_STRING << true << true; + QTest::newRow("unixfd") << "h" << true << true; +} + +static void addInvalidSingleLetterTypes() +{ + QChar nulString[] = { 0 }; + QTest::newRow("nul") << QString(nulString, 1) << false << false; + QTest::newRow("tilde") << "~" << false << false; + QTest::newRow("struct-begin") << "(" << false << false; + QTest::newRow("struct-end") << ")" << false << false; + QTest::newRow("dict-entry-begin") << "{" << false << false; + QTest::newRow("dict-entry-end") << "}" << false << false; + QTest::newRow("array-no-element") << "a" << false << false; +} + +static void addBasicTypes(bool basicsAreValid) +{ + addFixedTypes(); + QTest::newRow("string") << DBUS_TYPE_STRING_AS_STRING << basicsAreValid << true; + QTest::newRow("object-path") << DBUS_TYPE_OBJECT_PATH_AS_STRING << basicsAreValid << true; + QTest::newRow("signature") << DBUS_TYPE_SIGNATURE_AS_STRING << basicsAreValid << true; +} + +static void addVariant(bool variantIsValid) +{ + QTest::newRow("variant") << "v" << variantIsValid << true; +} + +static void addSingleSignatures() +{ + addBasicTypes(Valid); + addVariant(Valid); + QTest::newRow("struct-1") << "(y)" << true; + QTest::newRow("struct-2") << "(yy)" << true; + QTest::newRow("struct-3") << "(yyv)" << true; + + QTest::newRow("struct-nested-1") << "((y))" << true; + QTest::newRow("struct-nested-2") << "((yy))" << true; + QTest::newRow("struct-nested-3") << "(y(y))" << true; + QTest::newRow("struct-nested-4") << "((y)y)" << true; + QTest::newRow("struct-nested-5") << "(y(y)y)" << true; + QTest::newRow("struct-nested-6") << "((y)(y))" << true; + + QTest::newRow("array-1") << "as" << true; + QTest::newRow("struct-array-1") << "(as)" << true; + QTest::newRow("struct-array-2") << "(yas)" << true; + QTest::newRow("struct-array-3") << "(asy)" << true; + QTest::newRow("struct-array-4") << "(yasy)" << true; + + QTest::newRow("dict-1") << "a{sy}" << true; + QTest::newRow("dict-2") << "a{sv}" << true; + QTest::newRow("dict-struct-1") << "a{s(y)}" << true; + QTest::newRow("dict-struct-2") << "a{s(yyyy)}" << true; + QTest::newRow("dict-struct-array") << "a{s(ay)}" << true; + QTest::newRow("dict-array") << "a{sas}" << true; + QTest::newRow("dict-array-struct") << "a{sa(y)}" << true; + + addInvalidSingleLetterTypes(); + QTest::newRow("naked-dict-empty") << "{}" << false; + QTest::newRow("naked-dict-missing-value") << "{i}" << false; + + QTest::newRow("dict-empty") << "a{}" << false; + QTest::newRow("dict-missing-value") << "a{i}" << false; + QTest::newRow("dict-non-basic-key") << "a{vi}" << false; + QTest::newRow("dict-struct-key") << "a{(y)y}" << false; + QTest::newRow("dict-missing-close") << "a{sv" << false; + QTest::newRow("dict-mismatched-close") << "a{sv)" << false; + QTest::newRow("dict-missing-value-close") << "a{s" << false; + + QTest::newRow("empty-struct") << "()" << false; + QTest::newRow("struct-missing-close") << "(s" << false; + QTest::newRow("struct-nested-missing-close-1") << "((s)" << false; + QTest::newRow("struct-nested-missing-close-2") << "((s" << false; + + QTest::newRow("struct-ending-array-no-element") << "(a)" << false; +} + +static void addNakedDictEntry() +{ + QTest::newRow("naked-dict-entry") << "{sv}" << false; +} + +// ---- tests ---- + +void tst_QDBusType::isValidFixedType_data() +{ + addColumns(); + addFixedTypes(); + addBasicTypes(Invalid); + addVariant(Invalid); + addInvalidSingleLetterTypes(); +} + +void tst_QDBusType::isValidFixedType() +{ + QFETCH(QString, data); + QFETCH(bool, result); + QFETCH(bool, isValid); + Q_ASSERT_X(data.length() == 1, "tst_QDBusType", "Test is malformed, this function must test only one-letter types"); + Q_ASSERT(isValid || (!isValid && !result)); + + int type = data.at(0).unicode(); + if (isValid) + QCOMPARE(bool(dbus_type_is_fixed(type)), result); + QCOMPARE(QDBusUtil::isValidFixedType(type), result); +} + +void tst_QDBusType::isValidBasicType_data() +{ + addColumns(); + addBasicTypes(Valid); + addVariant(Invalid); + addInvalidSingleLetterTypes(); +} + +void tst_QDBusType::isValidBasicType() +{ + QFETCH(QString, data); + QFETCH(bool, result); + QFETCH(bool, isValid); + Q_ASSERT_X(data.length() == 1, "tst_QDBusType", "Test is malformed, this function must test only one-letter types"); + Q_ASSERT(isValid || (!isValid && !result)); + + int type = data.at(0).unicode(); + if (isValid) + QCOMPARE(bool(dbus_type_is_basic(type)), result); + QCOMPARE(QDBusUtil::isValidBasicType(type), result); +} + +void tst_QDBusType::isValidSingleSignature_data() +{ + addColumns(); + addSingleSignatures(); + addNakedDictEntry(); +} + +void tst_QDBusType::isValidSingleSignature() +{ + QFETCH(QString, data); + QFETCH(bool, result); + + QCOMPARE(bool(dbus_signature_validate_single(data.toLatin1(), 0)), result); + QCOMPARE(QDBusUtil::isValidSingleSignature(data), result); +} + +void tst_QDBusType::isValidArray_data() +{ + addColumns(); + addSingleSignatures(); +} + +void tst_QDBusType::isValidArray() +{ + QFETCH(QString, data); + QFETCH(bool, result); + + data.prepend("a"); + QCOMPARE(bool(dbus_signature_validate_single(data.toLatin1(), 0)), result); + QCOMPARE(QDBusUtil::isValidSingleSignature(data), result); + + data.prepend("a"); + QCOMPARE(bool(dbus_signature_validate_single(data.toLatin1(), 0)), result); + QCOMPARE(QDBusUtil::isValidSingleSignature(data), result); +} + +void tst_QDBusType::isValidSignature_data() +{ + isValidSingleSignature_data(); +} + +void tst_QDBusType::isValidSignature() +{ + QFETCH(QString, data); + QFETCH(bool, result); + + data.append(data); + if (data.at(0).unicode()) + QCOMPARE(bool(dbus_signature_validate(data.toLatin1(), 0)), result); + QCOMPARE(QDBusUtil::isValidSignature(data), result); +} + +QTEST_MAIN(tst_QDBusType) + +#include "tst_qdbustype.moc" -- cgit v0.12 From 08cecc882bf23253b3e447cde037e10529f56cdf Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 21 Feb 2011 20:15:31 +0100 Subject: Use the Qt code for validating types in QtDBus --- src/dbus/qdbus_symbols_p.h | 12 ------------ src/dbus/qdbusmarshaller.cpp | 6 +++--- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/src/dbus/qdbus_symbols_p.h b/src/dbus/qdbus_symbols_p.h index d0a4b3e..039657e 100644 --- a/src/dbus/qdbus_symbols_p.h +++ b/src/dbus/qdbus_symbols_p.h @@ -358,18 +358,6 @@ DEFINEFUNC(dbus_bool_t , dbus_server_set_watch_functions, (DBusServer DEFINEFUNC(void , dbus_server_unref, (DBusServer *server), (server), ) -/* dbus-signature.h */ -DEFINEFUNC(dbus_bool_t , dbus_signature_validate, (const char *signature, - DBusError *error), - (signature, error), return) -DEFINEFUNC(dbus_bool_t , dbus_signature_validate_single, (const char *signature, - DBusError *error), - (signature, error), return) -DEFINEFUNC(dbus_bool_t , dbus_type_is_basic, (int typecode), - (typecode), return) -DEFINEFUNC(dbus_bool_t , dbus_type_is_fixed, (int typecode), - (typecode), return) - /* dbus-thread.h */ DEFINEFUNC(dbus_bool_t , dbus_threads_init_default, (), (), return) diff --git a/src/dbus/qdbusmarshaller.cpp b/src/dbus/qdbusmarshaller.cpp index edf743e..6dec359 100644 --- a/src/dbus/qdbusmarshaller.cpp +++ b/src/dbus/qdbusmarshaller.cpp @@ -254,7 +254,7 @@ inline QDBusMarshaller *QDBusMarshaller::beginMap(int kid, int vid) .arg(QLatin1String(QVariant::typeToName(QVariant::Type(kid))))); return this; } - if (ksignature[1] != 0 || !q_dbus_type_is_basic(*ksignature)) { + if (ksignature[1] != 0 || !QDBusUtil::isValidBasicType(*ksignature)) { qWarning("QDBusMarshaller: type '%s' (%d) cannot be used as the key type in a D-BUS map.", QVariant::typeToName( QVariant::Type(kid) ), kid); error(QString::fromLatin1("Type %1 passed in arguments cannot be used as a key in a map") @@ -511,7 +511,7 @@ bool QDBusMarshaller::appendRegisteredType(const QVariant &arg) bool QDBusMarshaller::appendCrossMarshalling(QDBusDemarshaller *demarshaller) { int code = q_dbus_message_iter_get_arg_type(&demarshaller->iterator); - if (q_dbus_type_is_basic(code)) { + if (QDBusUtil::isValidBasicType(code)) { // easy: just append // do exactly like the D-BUS docs suggest // (see apidocs for q_dbus_message_iter_get_basic) @@ -525,7 +525,7 @@ bool QDBusMarshaller::appendCrossMarshalling(QDBusDemarshaller *demarshaller) if (code == DBUS_TYPE_ARRAY) { int element = q_dbus_message_iter_get_element_type(&demarshaller->iterator); - if (q_dbus_type_is_fixed(element) && element != DBUS_TYPE_UNIX_FD) { + if (QDBusUtil::isValidFixedType(element) && element != DBUS_TYPE_UNIX_FD) { // another optimization: fixed size arrays // code is exactly like QDBusDemarshaller::toByteArray DBusMessageIter sub; -- cgit v0.12 From c22f52ce22f998d35ccc6ee0caa60d4e0af3b783 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 23 Feb 2011 16:59:54 +0100 Subject: Move the QDBusPerformance test to the tests/benchmark dir --- tests/auto/dbus.pro | 1 - tests/auto/qdbusperformance/.gitignore | 2 - tests/auto/qdbusperformance/qdbusperformance.pro | 8 - tests/auto/qdbusperformance/server/server.cpp | 64 ------ tests/auto/qdbusperformance/server/server.pro | 5 - tests/auto/qdbusperformance/serverobject.h | 115 ----------- tests/auto/qdbusperformance/test/test.pro | 7 - .../auto/qdbusperformance/tst_qdbusperformance.cpp | 230 --------------------- tests/benchmarks/benchmarks.pro | 1 + tests/benchmarks/dbus/dbus.pro | 3 + tests/benchmarks/dbus/qdbusperformance/.gitignore | 2 + .../dbus/qdbusperformance/qdbusperformance.pro | 4 + .../dbus/qdbusperformance/server/server.cpp | 64 ++++++ .../dbus/qdbusperformance/server/server.pro | 5 + .../dbus/qdbusperformance/serverobject.h | 115 +++++++++++ .../benchmarks/dbus/qdbusperformance/test/test.pro | 7 + .../dbus/qdbusperformance/tst_qdbusperformance.cpp | 230 +++++++++++++++++++++ 17 files changed, 431 insertions(+), 432 deletions(-) delete mode 100644 tests/auto/qdbusperformance/.gitignore delete mode 100644 tests/auto/qdbusperformance/qdbusperformance.pro delete mode 100644 tests/auto/qdbusperformance/server/server.cpp delete mode 100644 tests/auto/qdbusperformance/server/server.pro delete mode 100644 tests/auto/qdbusperformance/serverobject.h delete mode 100644 tests/auto/qdbusperformance/test/test.pro delete mode 100644 tests/auto/qdbusperformance/tst_qdbusperformance.cpp create mode 100644 tests/benchmarks/dbus/dbus.pro create mode 100644 tests/benchmarks/dbus/qdbusperformance/.gitignore create mode 100644 tests/benchmarks/dbus/qdbusperformance/qdbusperformance.pro create mode 100644 tests/benchmarks/dbus/qdbusperformance/server/server.cpp create mode 100644 tests/benchmarks/dbus/qdbusperformance/server/server.pro create mode 100644 tests/benchmarks/dbus/qdbusperformance/serverobject.h create mode 100644 tests/benchmarks/dbus/qdbusperformance/test/test.pro create mode 100644 tests/benchmarks/dbus/qdbusperformance/tst_qdbusperformance.cpp diff --git a/tests/auto/dbus.pro b/tests/auto/dbus.pro index fe21475..31b46a3 100644 --- a/tests/auto/dbus.pro +++ b/tests/auto/dbus.pro @@ -11,7 +11,6 @@ SUBDIRS=\ qdbusmetatype \ qdbuspendingcall \ qdbuspendingreply \ - qdbusperformance \ qdbusreply \ qdbusservicewatcher \ qdbustype \ diff --git a/tests/auto/qdbusperformance/.gitignore b/tests/auto/qdbusperformance/.gitignore deleted file mode 100644 index 4cd8399..0000000 --- a/tests/auto/qdbusperformance/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -tst_qdbusperformance -server/server diff --git a/tests/auto/qdbusperformance/qdbusperformance.pro b/tests/auto/qdbusperformance/qdbusperformance.pro deleted file mode 100644 index 6880518..0000000 --- a/tests/auto/qdbusperformance/qdbusperformance.pro +++ /dev/null @@ -1,8 +0,0 @@ -load(qttest_p4) -contains(QT_CONFIG,dbus): { - TEMPLATE = subdirs - CONFIG += ordered - SUBDIRS = server test -} else { - SOURCES += ../qdbusmarshall/dummy.cpp -} diff --git a/tests/auto/qdbusperformance/server/server.cpp b/tests/auto/qdbusperformance/server/server.cpp deleted file mode 100644 index 3bd5efc..0000000 --- a/tests/auto/qdbusperformance/server/server.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 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 -#include - -#include "../serverobject.h" - -static const char serviceName[] = "com.trolltech.autotests.performance"; -static const char objectPath[] = "/"; - -int main(int argc, char *argv[]) -{ - QCoreApplication app(argc, argv); - - QDBusConnection con = QDBusConnection::sessionBus(); - if (!con.isConnected()) - exit(1); - - if (!con.registerService(serviceName)) - exit(2); - - ServerObject obj(objectPath, con); - printf("ready.\n"); - return app.exec(); -} - diff --git a/tests/auto/qdbusperformance/server/server.pro b/tests/auto/qdbusperformance/server/server.pro deleted file mode 100644 index 30f81dd..0000000 --- a/tests/auto/qdbusperformance/server/server.pro +++ /dev/null @@ -1,5 +0,0 @@ -SOURCES = server.cpp -HEADERS = ../serverobject.h -TARGET = server -CONFIG += qdbus -QT -= gui diff --git a/tests/auto/qdbusperformance/serverobject.h b/tests/auto/qdbusperformance/serverobject.h deleted file mode 100644 index 6f85bb4..0000000 --- a/tests/auto/qdbusperformance/serverobject.h +++ /dev/null @@ -1,115 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 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$ -** -****************************************************************************/ - - -#ifndef SERVEROBJECT_H -#define SERVEROBJECT_H - -#include -#include - -class ServerObject: public QObject -{ - Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "com.trolltech.autotests.Performance") -public: - ServerObject(const QString &objectPath, QDBusConnection conn, QObject *parent = 0) - : QObject(parent) - { - conn.registerObject(objectPath, this, QDBusConnection::ExportAllSlots); - } - -public slots: - Q_NOREPLY void noReply(const QByteArray &) - { - // black hole - } - Q_NOREPLY void noReply(const QString &) - { - // black hole - } - Q_NOREPLY void noReply(const QDBusVariant &) - { - // black hole - } - - int size(const QByteArray &data) - { - return data.size(); - } - int size(const QString &data) - { - return data.size(); - } - int size(const QDBusVariant &data) - { - QVariant v = data.variant(); - switch (v.type()) - { - case QVariant::ByteArray: - return v.toByteArray().size(); - case QVariant::StringList: - return v.toStringList().size(); - case QVariant::String: - default: - return v.toString().size(); - } - } - - QByteArray echo(const QByteArray &data) - { - return data; - } - QString echo(const QString &data) - { - return data; - } - QDBusVariant echo(const QDBusVariant &data) - { - return data; - } - - void nothing() - { - } -}; - -#endif diff --git a/tests/auto/qdbusperformance/test/test.pro b/tests/auto/qdbusperformance/test/test.pro deleted file mode 100644 index 9f5712e..0000000 --- a/tests/auto/qdbusperformance/test/test.pro +++ /dev/null @@ -1,7 +0,0 @@ -load(qttest_p4) -SOURCES += ../tst_qdbusperformance.cpp -HEADERS += ../serverobject.h -TARGET = ../tst_qdbusperformance - -QT = core -CONFIG += qdbus diff --git a/tests/auto/qdbusperformance/tst_qdbusperformance.cpp b/tests/auto/qdbusperformance/tst_qdbusperformance.cpp deleted file mode 100644 index a5b4b98..0000000 --- a/tests/auto/qdbusperformance/tst_qdbusperformance.cpp +++ /dev/null @@ -1,230 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 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 -#include -#include - -#include "./serverobject.h" - -static const char serviceName[] = "com.trolltech.autotests.performance"; -static const int runTime = 500; - -class tst_QDBusPerformance: public QObject -{ - Q_OBJECT - QProcess proc; - QDBusInterface *target; - - QDBusInterface *remote; - QDBusInterface *local; - - bool executeTest(const char *funcname, int size, const QVariant &data); - -public slots: - void initTestCase_data(); - void initTestCase(); - void init(); - -private slots: - void callSpeed(); - - void oneWay_data(); - void oneWay(); - void oneWayVariant_data(); - void oneWayVariant(); - - void roundTrip_data(); - void roundTrip(); - void roundTripVariant_data(); - void roundTripVariant(); -}; -Q_DECLARE_METATYPE(QVariant) - -void tst_QDBusPerformance::initTestCase() -{ - QDBusConnection con = QDBusConnection::sessionBus(); - QVERIFY(con.isConnected()); - - QDBusServiceWatcher watcher(serviceName, con, - QDBusServiceWatcher::WatchForRegistration); - connect(&watcher, SIGNAL(serviceRegistered(QString)), - &QTestEventLoop::instance(), SLOT(exitLoop())); - -#ifdef Q_OS_WIN - proc.start("server"); -#else - proc.start("./server/server"); -#endif - QVERIFY(proc.waitForStarted()); - - QTestEventLoop::instance().enterLoop(5); - QVERIFY(con.interface()->isServiceRegistered(serviceName)); - - remote = new QDBusInterface(serviceName, "/", "com.trolltech.autotests.Performance", con, this); - QVERIFY(remote->isValid()); - - new ServerObject("/", con, this); - local = new QDBusInterface(con.baseService(), "/", "com.trolltech.autotests.Performance", con, this); - QVERIFY(local->isValid()); -} - -void tst_QDBusPerformance::initTestCase_data() -{ - QTest::addColumn("loopback"); - - QTest::newRow("normal") << false; - QTest::newRow("loopback") << true; -} - -void tst_QDBusPerformance::init() -{ - QFETCH_GLOBAL(bool, loopback); - if (loopback) - target = local; - else - target = remote; -} - -void tst_QDBusPerformance::callSpeed() -{ - QElapsedTimer timer; - - int callCount = 0; - timer.start(); - while (timer.elapsed() < runTime) { - QDBusReply reply = target->call("nothing"); - QVERIFY(reply.isValid()); - - ++callCount; - } - qDebug() << callCount << "calls in" << timer.elapsed() << "ms:" - << (callCount * 1000.0 / timer.elapsed()) << "calls/sec"; -} - -bool tst_QDBusPerformance::executeTest(const char *funcname, int size, const QVariant &data) -{ - QElapsedTimer timer; - - int callCount = 0; - qint64 transferred = 0; - timer.start(); - while (timer.elapsed() < runTime) { - QDBusMessage reply = target->call(funcname, data); - if (reply.type() != QDBusMessage::ReplyMessage) - return false; - - transferred += size; - ++callCount; - } - qDebug() << transferred << "bytes in" << timer.elapsed() << "ms" - << "(in" << callCount << "calls):" - << (transferred * 1000.0 / timer.elapsed() / 1024 / 1024) << "MB/s"; - - return true; -} - -void tst_QDBusPerformance::oneWay_data() -{ - QTest::addColumn("data"); - QTest::addColumn("size"); - - QByteArray ba(256, 'a'); - while (ba.size() < 8193) { - QTest::newRow(QString("%1-byteArray").arg(ba.size()).toAscii()) << qVariantFromValue(ba) << ba.size(); - ba += ba; - } - - QString s(256, QLatin1Char('a')); - while (s.size() < 8193) { - QTest::newRow(QString("%1-string").arg(s.size()).toAscii()) << qVariantFromValue(s) << s.size(); - s += s; - } -} - -void tst_QDBusPerformance::oneWay() -{ - QFETCH(QVariant, data); - QFETCH(int, size); - - QVERIFY(executeTest("size", size, data)); -} - -void tst_QDBusPerformance::oneWayVariant_data() -{ - oneWay_data(); -} - -void tst_QDBusPerformance::oneWayVariant() -{ - QFETCH(QVariant, data); - QFETCH(int, size); - - QVERIFY(executeTest("size", size, qVariantFromValue(QDBusVariant(data)))); -} - -void tst_QDBusPerformance::roundTrip_data() -{ - oneWay_data(); -} - -void tst_QDBusPerformance::roundTrip() -{ - QFETCH(QVariant, data); - QFETCH(int, size); - - QVERIFY(executeTest("echo", size, data)); -} - -void tst_QDBusPerformance::roundTripVariant_data() -{ - oneWay_data(); -} - -void tst_QDBusPerformance::roundTripVariant() -{ - QFETCH(QVariant, data); - QFETCH(int, size); - - QVERIFY(executeTest("echo", size, qVariantFromValue(QDBusVariant(data)))); -} - -QTEST_MAIN(tst_QDBusPerformance) -#include "tst_qdbusperformance.moc" diff --git a/tests/benchmarks/benchmarks.pro b/tests/benchmarks/benchmarks.pro index 00a1b37..b5e3a4b 100644 --- a/tests/benchmarks/benchmarks.pro +++ b/tests/benchmarks/benchmarks.pro @@ -7,6 +7,7 @@ SUBDIRS = \ svg contains(QT_CONFIG, opengl): SUBDIRS += opengl contains(QT_CONFIG, declarative): SUBDIRS += declarative +contains(QT_CONFIG, dbus): SUBDIRS += dbus check-trusted.CONFIG += recursive QMAKE_EXTRA_TARGETS += check-trusted diff --git a/tests/benchmarks/dbus/dbus.pro b/tests/benchmarks/dbus/dbus.pro new file mode 100644 index 0000000..b02d070 --- /dev/null +++ b/tests/benchmarks/dbus/dbus.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs +SUBDIRS = \ + qdbusperformance diff --git a/tests/benchmarks/dbus/qdbusperformance/.gitignore b/tests/benchmarks/dbus/qdbusperformance/.gitignore new file mode 100644 index 0000000..4cd8399 --- /dev/null +++ b/tests/benchmarks/dbus/qdbusperformance/.gitignore @@ -0,0 +1,2 @@ +tst_qdbusperformance +server/server diff --git a/tests/benchmarks/dbus/qdbusperformance/qdbusperformance.pro b/tests/benchmarks/dbus/qdbusperformance/qdbusperformance.pro new file mode 100644 index 0000000..90f88a7 --- /dev/null +++ b/tests/benchmarks/dbus/qdbusperformance/qdbusperformance.pro @@ -0,0 +1,4 @@ +load(qttest_p4) +TEMPLATE = subdirs +CONFIG += ordered +SUBDIRS = server test diff --git a/tests/benchmarks/dbus/qdbusperformance/server/server.cpp b/tests/benchmarks/dbus/qdbusperformance/server/server.cpp new file mode 100644 index 0000000..3bd5efc --- /dev/null +++ b/tests/benchmarks/dbus/qdbusperformance/server/server.cpp @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 +#include + +#include "../serverobject.h" + +static const char serviceName[] = "com.trolltech.autotests.performance"; +static const char objectPath[] = "/"; + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + + QDBusConnection con = QDBusConnection::sessionBus(); + if (!con.isConnected()) + exit(1); + + if (!con.registerService(serviceName)) + exit(2); + + ServerObject obj(objectPath, con); + printf("ready.\n"); + return app.exec(); +} + diff --git a/tests/benchmarks/dbus/qdbusperformance/server/server.pro b/tests/benchmarks/dbus/qdbusperformance/server/server.pro new file mode 100644 index 0000000..30f81dd --- /dev/null +++ b/tests/benchmarks/dbus/qdbusperformance/server/server.pro @@ -0,0 +1,5 @@ +SOURCES = server.cpp +HEADERS = ../serverobject.h +TARGET = server +CONFIG += qdbus +QT -= gui diff --git a/tests/benchmarks/dbus/qdbusperformance/serverobject.h b/tests/benchmarks/dbus/qdbusperformance/serverobject.h new file mode 100644 index 0000000..6f85bb4 --- /dev/null +++ b/tests/benchmarks/dbus/qdbusperformance/serverobject.h @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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$ +** +****************************************************************************/ + + +#ifndef SERVEROBJECT_H +#define SERVEROBJECT_H + +#include +#include + +class ServerObject: public QObject +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.trolltech.autotests.Performance") +public: + ServerObject(const QString &objectPath, QDBusConnection conn, QObject *parent = 0) + : QObject(parent) + { + conn.registerObject(objectPath, this, QDBusConnection::ExportAllSlots); + } + +public slots: + Q_NOREPLY void noReply(const QByteArray &) + { + // black hole + } + Q_NOREPLY void noReply(const QString &) + { + // black hole + } + Q_NOREPLY void noReply(const QDBusVariant &) + { + // black hole + } + + int size(const QByteArray &data) + { + return data.size(); + } + int size(const QString &data) + { + return data.size(); + } + int size(const QDBusVariant &data) + { + QVariant v = data.variant(); + switch (v.type()) + { + case QVariant::ByteArray: + return v.toByteArray().size(); + case QVariant::StringList: + return v.toStringList().size(); + case QVariant::String: + default: + return v.toString().size(); + } + } + + QByteArray echo(const QByteArray &data) + { + return data; + } + QString echo(const QString &data) + { + return data; + } + QDBusVariant echo(const QDBusVariant &data) + { + return data; + } + + void nothing() + { + } +}; + +#endif diff --git a/tests/benchmarks/dbus/qdbusperformance/test/test.pro b/tests/benchmarks/dbus/qdbusperformance/test/test.pro new file mode 100644 index 0000000..9f5712e --- /dev/null +++ b/tests/benchmarks/dbus/qdbusperformance/test/test.pro @@ -0,0 +1,7 @@ +load(qttest_p4) +SOURCES += ../tst_qdbusperformance.cpp +HEADERS += ../serverobject.h +TARGET = ../tst_qdbusperformance + +QT = core +CONFIG += qdbus diff --git a/tests/benchmarks/dbus/qdbusperformance/tst_qdbusperformance.cpp b/tests/benchmarks/dbus/qdbusperformance/tst_qdbusperformance.cpp new file mode 100644 index 0000000..a5b4b98 --- /dev/null +++ b/tests/benchmarks/dbus/qdbusperformance/tst_qdbusperformance.cpp @@ -0,0 +1,230 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 +#include +#include + +#include "./serverobject.h" + +static const char serviceName[] = "com.trolltech.autotests.performance"; +static const int runTime = 500; + +class tst_QDBusPerformance: public QObject +{ + Q_OBJECT + QProcess proc; + QDBusInterface *target; + + QDBusInterface *remote; + QDBusInterface *local; + + bool executeTest(const char *funcname, int size, const QVariant &data); + +public slots: + void initTestCase_data(); + void initTestCase(); + void init(); + +private slots: + void callSpeed(); + + void oneWay_data(); + void oneWay(); + void oneWayVariant_data(); + void oneWayVariant(); + + void roundTrip_data(); + void roundTrip(); + void roundTripVariant_data(); + void roundTripVariant(); +}; +Q_DECLARE_METATYPE(QVariant) + +void tst_QDBusPerformance::initTestCase() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QVERIFY(con.isConnected()); + + QDBusServiceWatcher watcher(serviceName, con, + QDBusServiceWatcher::WatchForRegistration); + connect(&watcher, SIGNAL(serviceRegistered(QString)), + &QTestEventLoop::instance(), SLOT(exitLoop())); + +#ifdef Q_OS_WIN + proc.start("server"); +#else + proc.start("./server/server"); +#endif + QVERIFY(proc.waitForStarted()); + + QTestEventLoop::instance().enterLoop(5); + QVERIFY(con.interface()->isServiceRegistered(serviceName)); + + remote = new QDBusInterface(serviceName, "/", "com.trolltech.autotests.Performance", con, this); + QVERIFY(remote->isValid()); + + new ServerObject("/", con, this); + local = new QDBusInterface(con.baseService(), "/", "com.trolltech.autotests.Performance", con, this); + QVERIFY(local->isValid()); +} + +void tst_QDBusPerformance::initTestCase_data() +{ + QTest::addColumn("loopback"); + + QTest::newRow("normal") << false; + QTest::newRow("loopback") << true; +} + +void tst_QDBusPerformance::init() +{ + QFETCH_GLOBAL(bool, loopback); + if (loopback) + target = local; + else + target = remote; +} + +void tst_QDBusPerformance::callSpeed() +{ + QElapsedTimer timer; + + int callCount = 0; + timer.start(); + while (timer.elapsed() < runTime) { + QDBusReply reply = target->call("nothing"); + QVERIFY(reply.isValid()); + + ++callCount; + } + qDebug() << callCount << "calls in" << timer.elapsed() << "ms:" + << (callCount * 1000.0 / timer.elapsed()) << "calls/sec"; +} + +bool tst_QDBusPerformance::executeTest(const char *funcname, int size, const QVariant &data) +{ + QElapsedTimer timer; + + int callCount = 0; + qint64 transferred = 0; + timer.start(); + while (timer.elapsed() < runTime) { + QDBusMessage reply = target->call(funcname, data); + if (reply.type() != QDBusMessage::ReplyMessage) + return false; + + transferred += size; + ++callCount; + } + qDebug() << transferred << "bytes in" << timer.elapsed() << "ms" + << "(in" << callCount << "calls):" + << (transferred * 1000.0 / timer.elapsed() / 1024 / 1024) << "MB/s"; + + return true; +} + +void tst_QDBusPerformance::oneWay_data() +{ + QTest::addColumn("data"); + QTest::addColumn("size"); + + QByteArray ba(256, 'a'); + while (ba.size() < 8193) { + QTest::newRow(QString("%1-byteArray").arg(ba.size()).toAscii()) << qVariantFromValue(ba) << ba.size(); + ba += ba; + } + + QString s(256, QLatin1Char('a')); + while (s.size() < 8193) { + QTest::newRow(QString("%1-string").arg(s.size()).toAscii()) << qVariantFromValue(s) << s.size(); + s += s; + } +} + +void tst_QDBusPerformance::oneWay() +{ + QFETCH(QVariant, data); + QFETCH(int, size); + + QVERIFY(executeTest("size", size, data)); +} + +void tst_QDBusPerformance::oneWayVariant_data() +{ + oneWay_data(); +} + +void tst_QDBusPerformance::oneWayVariant() +{ + QFETCH(QVariant, data); + QFETCH(int, size); + + QVERIFY(executeTest("size", size, qVariantFromValue(QDBusVariant(data)))); +} + +void tst_QDBusPerformance::roundTrip_data() +{ + oneWay_data(); +} + +void tst_QDBusPerformance::roundTrip() +{ + QFETCH(QVariant, data); + QFETCH(int, size); + + QVERIFY(executeTest("echo", size, data)); +} + +void tst_QDBusPerformance::roundTripVariant_data() +{ + oneWay_data(); +} + +void tst_QDBusPerformance::roundTripVariant() +{ + QFETCH(QVariant, data); + QFETCH(int, size); + + QVERIFY(executeTest("echo", size, qVariantFromValue(QDBusVariant(data)))); +} + +QTEST_MAIN(tst_QDBusPerformance) +#include "tst_qdbusperformance.moc" -- cgit v0.12 From eb0262ae71d4a8576cd8ba5885d8218c9f566371 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 23 Feb 2011 17:02:23 +0100 Subject: Add a benchmark for testing our QtDBus type-validation Our code is much faster than libdbus-1, even when built in debug mode. --- tests/benchmarks/dbus/dbus.pro | 3 +- tests/benchmarks/dbus/qdbustype/main.cpp | 115 ++++++++++++++++++++++++++ tests/benchmarks/dbus/qdbustype/qdbustype.pro | 8 ++ 3 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 tests/benchmarks/dbus/qdbustype/main.cpp create mode 100644 tests/benchmarks/dbus/qdbustype/qdbustype.pro diff --git a/tests/benchmarks/dbus/dbus.pro b/tests/benchmarks/dbus/dbus.pro index b02d070..989a0db 100644 --- a/tests/benchmarks/dbus/dbus.pro +++ b/tests/benchmarks/dbus/dbus.pro @@ -1,3 +1,4 @@ TEMPLATE = subdirs SUBDIRS = \ - qdbusperformance + qdbusperformance \ + qdbustype diff --git a/tests/benchmarks/dbus/qdbustype/main.cpp b/tests/benchmarks/dbus/qdbustype/main.cpp new file mode 100644 index 0000000..abaae7e --- /dev/null +++ b/tests/benchmarks/dbus/qdbustype/main.cpp @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the FOO module 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 +#include + +#include + +#include + +class tst_QDBusType: public QObject +{ + Q_OBJECT +private Q_SLOTS: + void benchmarkSignature_data(); + void benchmarkSignature(); +}; + +static inline void benchmarkAddRow(const char *name, const char *data) +{ + QTest::newRow(QByteArray("native-") + name) << data << true; + QTest::newRow(name) << data << false; +} + +void tst_QDBusType::benchmarkSignature_data() +{ + QTest::addColumn("data"); + QTest::addColumn("useNative"); + + for (int loopCount = 0; loopCount < 2; ++loopCount) { + bool useNative = loopCount; + QByteArray prefix = useNative ? "native-" : ""; + + benchmarkAddRow("single-invalid", "~"); + benchmarkAddRow("single-invalid-array", "a~"); + benchmarkAddRow("single-invalid-struct", "(.)"); + + benchmarkAddRow("single-char", "b"); + benchmarkAddRow("single-array", "as"); + benchmarkAddRow("single-simplestruct", "(y)"); + benchmarkAddRow("single-simpledict", "a{sv}"); + benchmarkAddRow("single-complexdict", "a{s(aya{io})}"); + + benchmarkAddRow("multiple-char", "ssg"); + benchmarkAddRow("multiple-arrays", "asasay"); + + benchmarkAddRow("struct-missingclose", "(ayyyy"); + benchmarkAddRow("longstruct", "(yyyyyyayasy)"); + benchmarkAddRow("invalid-longstruct", "(yyyyyyayas.y)"); + benchmarkAddRow("complexstruct", "(y(aasay)oga{sv})"); + benchmarkAddRow("multiple-simple-structs", "(y)(y)(y)"); + } +} + +void tst_QDBusType::benchmarkSignature() +{ + QFETCH(QString, data); + QFETCH(bool, useNative); + + bool result; + if (useNative) { + dbus_signature_validate(data.toLatin1(), 0); + QBENCHMARK { + result = dbus_signature_validate(data.toLatin1(), 0); + } + } else { + QDBusUtil::isValidSignature(data); + QBENCHMARK { + result = QDBusUtil::isValidSignature(data); + } + } + Q_UNUSED(result); +} + +QTEST_MAIN(tst_QDBusType) + +#include "main.moc" diff --git a/tests/benchmarks/dbus/qdbustype/qdbustype.pro b/tests/benchmarks/dbus/qdbustype/qdbustype.pro new file mode 100644 index 0000000..d480a05 --- /dev/null +++ b/tests/benchmarks/dbus/qdbustype/qdbustype.pro @@ -0,0 +1,8 @@ +load(qttest_p4) +TARGET = tst_bench_qdbustype +QT -= gui +QT += dbus +QMAKE_CXXFLAGS += $$QT_CFLAGS_DBUS +LIBS_PRIVATE += $$QT_LIBS_DBUS + +SOURCES += main.cpp -- cgit v0.12 From 162ee8d83c72990c33952a99bd959f18842dde10 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 28 Jan 2011 11:14:46 +0100 Subject: Change the error message in the timer ID deallocator. This is really an internal error since the upper layers of the event dispatcher should have already caught a timer ID that isn't valid. Reviewed-By: Olivier Goffart --- src/corelib/kernel/qabstracteventdispatcher.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp index e79f87a..07f04b2 100644 --- a/src/corelib/kernel/qabstracteventdispatcher.cpp +++ b/src/corelib/kernel/qabstracteventdispatcher.cpp @@ -187,7 +187,8 @@ void QAbstractEventDispatcherPrivate::releaseTimerId(int timerId) int at = bucketIndex(bucket, which); int *b = timerIds[bucket]; - Q_ASSERT(b[at] == -timerId); + Q_ASSERT_X(timerId == -b[at], "QAbstractEventDispatcher::releaseTimerId", + "Internal error: timer ID not found"); int freeId, newTimerId; do { -- cgit v0.12 From 8f08be2bd372c581d578ed81c2f57cf1adc0ae79 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 13 Dec 2010 17:22:33 +0100 Subject: Change the number of entries in the first timer bucket. 8 timers are too few for common applications. 32 is more likely to reach >90% of the applications. This way, we avoid a memory allocation. Reviewed-by: Olivier Goffart --- src/corelib/kernel/qabstracteventdispatcher.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp index 07f04b2..b1b1380 100644 --- a/src/corelib/kernel/qabstracteventdispatcher.cpp +++ b/src/corelib/kernel/qabstracteventdispatcher.cpp @@ -49,14 +49,18 @@ QT_BEGIN_NAMESPACE // we allow for 2^24 = 8^8 = 16777216 simultaneously running timers -enum { NumberOfBuckets = 8, FirstBucketSize = 8 }; +enum { NumberOfBuckets = 8, FirstBucketSize = 32 }; static const int BucketSize[NumberOfBuckets] = - { 8, 64, 512, 4096, 32768, 262144, 2097152, 16777216 - 2396744 }; + { 32, 64, 512, 4096, 32768, 262144, 2097152, 16777216 - 2364000 }; static const int BucketOffset[NumberOfBuckets] = - { 0, 8, 72, 584, 4680, 37448, 299592, 2396744 }; + { 0, 32, 96, 608, 4704, 37448, 266848, 2364000 }; + +static int FirstBucket[] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 +}; -static int FirstBucket[FirstBucketSize] = { 1, 2, 3, 4, 5, 6, 7, 8 }; static QBasicAtomicPointer timerIds[NumberOfBuckets] = { Q_BASIC_ATOMIC_INITIALIZER(FirstBucket), Q_BASIC_ATOMIC_INITIALIZER(0), -- cgit v0.12 From 25fe0f83759649af218ea7eecd849dc0a311afbc Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 14 Apr 2011 10:51:09 +0200 Subject: Fix compilation if D-Bus 1.4 isn't present. --- src/dbus/qdbusintegrator.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index aaf19cf..d6fbe80 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1682,6 +1682,9 @@ static QDBusConnection::ConnectionCapabilities connectionCapabilies(DBusConnecti return result; # endif +#ifndef DBUS_TYPE_UNIX_FD +# define DBUS_TYPE_UNIX_FD int('h') +#endif if (q_dbus_connection_can_send_type(connection, DBUS_TYPE_UNIX_FD)) result |= QDBusConnection::UnixFileDescriptorPassing; #endif -- cgit v0.12 From 0d3044b547614cbd313d90021606af1f81fb10de Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 25 Nov 2010 22:40:34 +0100 Subject: Fix strict-alias breaking warnings with GCC. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GCC doesn't like any kind of reinterpret_cast or C-style cast with pointers. So instead do the work with static_cast<>, which it seems to like. Also took the opportunity to change the generic payload type to void*, so the alignment works as expected. I wonder how we haven't had serious crashes so far on ARM... Reviewed-by: Samuel Rødal --- .../qml/qdeclarativeobjectscriptclass.cpp | 115 +++++++++++++-------- 1 file changed, 72 insertions(+), 43 deletions(-) diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp index dc3ecca..a2411b9 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp @@ -632,7 +632,6 @@ QDeclarativeObjectMethodScriptClass::property(Object *, const Identifier &name) namespace { struct MetaCallArgument { - inline MetaCallArgument(); inline ~MetaCallArgument(); inline void *dataPtr(); @@ -640,15 +639,45 @@ struct MetaCallArgument { void fromScriptValue(int type, QDeclarativeEngine *, const QScriptValue &); inline QScriptDeclarativeClass::Value toValue(QDeclarativeEngine *); +protected: + inline MetaCallArgument(); + private: MetaCallArgument(const MetaCallArgument &); + template T &as(); inline void cleanup(); - char data[4 * sizeof(void *)]; int type; bool isObjectType; + char padding[6]; // ensure sizeof(MetaCallArgument) == 8 +}; + +template struct TypedMetaCallArgument: public MetaCallArgument +{ + T data; +protected: + TypedMetaCallArgument() {} + ~TypedMetaCallArgument() {} +private: + TypedMetaCallArgument(const TypedMetaCallArgument &); }; + +struct GenericPayload { void *data[4]; }; +struct GenericMetaCallArgument: public TypedMetaCallArgument +{ +}; + +template T &MetaCallArgument::as() +{ +#ifdef Q_ALIGNOF + // static assert + char dummy_array[Q_ALIGNOF(T) <= sizeof(*this) ? 1 : -1]; Q_UNUSED(dummy_array); +#endif + TypedMetaCallArgument &typed = static_cast &>(*this); + return typed.data; +} + } MetaCallArgument::MetaCallArgument() @@ -664,22 +693,22 @@ MetaCallArgument::~MetaCallArgument() void MetaCallArgument::cleanup() { if (type == QMetaType::QString) { - ((QString *)&data)->~QString(); + as().~QString(); } else if (type == -1 || type == qMetaTypeId()) { - ((QVariant *)&data)->~QVariant(); + as().~QVariant(); } else if (type == qMetaTypeId()) { - ((QScriptValue *)&data)->~QScriptValue(); + as().~QScriptValue(); } else if (type == qMetaTypeId >()) { - ((QList *)&data)->~QList(); + as >().~QList(); } } void *MetaCallArgument::dataPtr() { if (type == -1) - return ((QVariant *)data)->data(); + return as().data(); else - return (void *)&data; + return &as(); } void MetaCallArgument::initAsType(int callType, QDeclarativeEngine *e) @@ -690,7 +719,7 @@ void MetaCallArgument::initAsType(int callType, QDeclarativeEngine *e) QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(e); if (callType == qMetaTypeId()) { - new (&data) QScriptValue(engine->undefinedValue()); + new (&as()) QScriptValue(engine->undefinedValue()); type = callType; } else if (callType == QMetaType::Int || callType == QMetaType::UInt || @@ -699,20 +728,20 @@ void MetaCallArgument::initAsType(int callType, QDeclarativeEngine *e) callType == QMetaType::Float) { type = callType; } else if (callType == QMetaType::QObjectStar) { - *((QObject **)&data) = 0; + as() = 0; type = callType; } else if (callType == QMetaType::QString) { - new (&data) QString(); + new (&as()) QString(); type = callType; } else if (callType == qMetaTypeId()) { type = callType; - new (&data) QVariant(); + new (&as()) QVariant(); } else if (callType == qMetaTypeId >()) { type = callType; - new (&data) QList(); + new (&as >()) QList(); } else { type = -1; - new (&data) QVariant(callType, (void *)0); + new (&as()) QVariant(callType, (void *)0); } } @@ -721,37 +750,37 @@ void MetaCallArgument::fromScriptValue(int callType, QDeclarativeEngine *engine, if (type != 0) { cleanup(); type = 0; } if (callType == qMetaTypeId()) { - new (&data) QScriptValue(value); + new (&as()) QScriptValue(value); type = qMetaTypeId(); } else if (callType == QMetaType::Int) { - *((int *)&data) = int(value.toInt32()); + as() = int(value.toInt32()); type = callType; } else if (callType == QMetaType::UInt) { - *((uint *)&data) = uint(value.toUInt32()); + as() = uint(value.toUInt32()); type = callType; } else if (callType == QMetaType::Bool) { - *((bool *)&data) = value.toBool(); + as() = value.toBool(); type = callType; } else if (callType == QMetaType::Double) { - *((double *)&data) = double(value.toNumber()); + as() = double(value.toNumber()); type = callType; } else if (callType == QMetaType::Float) { - *((float *)&data) = float(value.toNumber()); + as() = float(value.toNumber()); type = callType; } else if (callType == QMetaType::QString) { if (value.isNull() || value.isUndefined()) - new (&data) QString(); + new (&as()) QString(); else - new (&data) QString(value.toString()); + new (&as()) QString(value.toString()); type = callType; } else if (callType == QMetaType::QObjectStar) { - *((QObject **)&data) = value.toQObject(); + as() = value.toQObject(); type = callType; } else if (callType == qMetaTypeId()) { - new (&data) QVariant(QDeclarativeEnginePrivate::get(engine)->scriptValueToVariant(value)); + new (&as()) QVariant(QDeclarativeEnginePrivate::get(engine)->scriptValueToVariant(value)); type = callType; } else if (callType == qMetaTypeId >()) { - QList *list = new (&data) QList(); + QList *list = new (&as >()) QList(); if (value.isArray()) { int length = value.property(QLatin1String("length")).toInt32(); for (int ii = 0; ii < length; ++ii) { @@ -764,16 +793,16 @@ void MetaCallArgument::fromScriptValue(int callType, QDeclarativeEngine *engine, } type = callType; } else { - new (&data) QVariant(); + new (&as()) QVariant(); type = -1; QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(engine); QVariant v = priv->scriptValueToVariant(value); if (v.userType() == callType) { - *((QVariant *)&data) = v; + as() = v; } else if (v.canConvert((QVariant::Type)callType)) { - *((QVariant *)&data) = v; - ((QVariant *)&data)->convert((QVariant::Type)callType); + as() = v; + as().convert((QVariant::Type)callType); } else if (const QMetaObject *mo = priv->rawMetaObjectForType(callType)) { QObject *obj = priv->toQObject(v); @@ -783,9 +812,9 @@ void MetaCallArgument::fromScriptValue(int callType, QDeclarativeEngine *engine, if (!objMo) obj = 0; } - *((QVariant *)&data) = QVariant(callType, &obj); + as() = QVariant(callType, &obj); } else { - *((QVariant *)&data) = QVariant(callType, (void *)0); + as() = QVariant(callType, (void *)0); } } } @@ -795,27 +824,27 @@ QScriptDeclarativeClass::Value MetaCallArgument::toValue(QDeclarativeEngine *e) QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(e); if (type == qMetaTypeId()) { - return QScriptDeclarativeClass::Value(engine, *((QScriptValue *)&data)); + return QScriptDeclarativeClass::Value(engine, as()); } else if (type == QMetaType::Int) { - return QScriptDeclarativeClass::Value(engine, *((int *)&data)); + return QScriptDeclarativeClass::Value(engine, as()); } else if (type == QMetaType::UInt) { - return QScriptDeclarativeClass::Value(engine, *((uint *)&data)); + return QScriptDeclarativeClass::Value(engine, as()); } else if (type == QMetaType::Bool) { - return QScriptDeclarativeClass::Value(engine, *((bool *)&data)); + return QScriptDeclarativeClass::Value(engine, as()); } else if (type == QMetaType::Double) { - return QScriptDeclarativeClass::Value(engine, *((double *)&data)); + return QScriptDeclarativeClass::Value(engine, as()); } else if (type == QMetaType::Float) { - return QScriptDeclarativeClass::Value(engine, *((float *)&data)); + return QScriptDeclarativeClass::Value(engine, as()); } else if (type == QMetaType::QString) { - return QScriptDeclarativeClass::Value(engine, *((QString *)&data)); + return QScriptDeclarativeClass::Value(engine, as()); } else if (type == QMetaType::QObjectStar) { - QObject *object = *((QObject **)&data); + QObject *object = as(); if (object) QDeclarativeData::get(object, true)->setImplicitDestructible(); QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(e); return QScriptDeclarativeClass::Value(engine, priv->objectClass->newQObject(object)); } else if (type == qMetaTypeId >()) { - QList &list = *(QList*)&data; + QList &list = as >(); QScriptValue rv = engine->newArray(list.count()); QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(e); for (int ii = 0; ii < list.count(); ++ii) { @@ -826,7 +855,7 @@ QScriptDeclarativeClass::Value MetaCallArgument::toValue(QDeclarativeEngine *e) return QScriptDeclarativeClass::Value(engine, rv); } else if (type == -1 || type == qMetaTypeId()) { QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(e); - QScriptValue rv = ep->scriptValueFromVariant(*((QVariant *)&data)); + QScriptValue rv = ep->scriptValueFromVariant(as()); if (rv.isQObject()) { QObject *object = rv.toQObject(); if (object) @@ -906,7 +935,7 @@ QDeclarativeObjectMethodScriptClass::callMethod(QObject *object, int index, { if (argCount > 0) { - QVarLengthArray args(argCount + 1); + QVarLengthArray args(argCount + 1); args[0].initAsType(returnType, engine); for (int ii = 0; ii < argCount; ++ii) @@ -922,7 +951,7 @@ QDeclarativeObjectMethodScriptClass::callMethod(QObject *object, int index, } else if (returnType != 0) { - MetaCallArgument arg; + GenericMetaCallArgument arg; arg.initAsType(returnType, engine); void *args[] = { arg.dataPtr() }; -- cgit v0.12 From 290bc1e55ee3093cadc2addfd2ea29826ee91e87 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 26 Jan 2011 14:57:34 +0100 Subject: Move the constants up, preparing for refactoring --- src/corelib/kernel/qabstracteventdispatcher.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp index b1b1380..06b76c9 100644 --- a/src/corelib/kernel/qabstracteventdispatcher.cpp +++ b/src/corelib/kernel/qabstracteventdispatcher.cpp @@ -49,6 +49,11 @@ QT_BEGIN_NAMESPACE // we allow for 2^24 = 8^8 = 16777216 simultaneously running timers +static const int TimerIdMask = 0x00ffffff; +static const int TimerSerialMask = ~TimerIdMask & ~0x80000000; +static const int TimerSerialCounter = TimerIdMask + 1; +static const int MaxTimerId = TimerSerialCounter - 1; + enum { NumberOfBuckets = 8, FirstBucketSize = 32 }; static const int BucketSize[NumberOfBuckets] = @@ -81,10 +86,6 @@ Q_DESTRUCTOR_FUNCTION(timerIdsDestructorFunction) static QBasicAtomicInt nextFreeTimerId = Q_BASIC_ATOMIC_INITIALIZER(1); -static const int TimerIdMask = 0x00ffffff; -static const int TimerSerialMask = ~TimerIdMask & ~0x80000000; -static const int TimerSerialCounter = TimerIdMask + 1; - // avoid the ABA-problem by using 7 of the top 8 bits of the timerId as a serial number static inline int prepareNewValueWithSerialNumber(int oldId, int newId) { -- cgit v0.12 From 050928ae69c95018718fd77084aa70fa26a033a3 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 26 Jan 2011 15:09:47 +0100 Subject: Replace the handcoded math and change the timer buckets again. Reduce from 8 to 6 buckets and increase the step between each bucket. This way, the second bucket is now of 224 timers, which should be enough for 99.9% of the applications. Also change the hardcoded math to calculations using enum values. This helps in changing the timer buckets again in the future. Also fix the last bucket not to have a timer ID of 16777216, as that is not valid. Reviewed-by: Olivier Goffart --- src/corelib/kernel/qabstracteventdispatcher.cpp | 51 +++++++++++++++++++------ 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp index 06b76c9..2949cd0 100644 --- a/src/corelib/kernel/qabstracteventdispatcher.cpp +++ b/src/corelib/kernel/qabstracteventdispatcher.cpp @@ -52,28 +52,48 @@ QT_BEGIN_NAMESPACE static const int TimerIdMask = 0x00ffffff; static const int TimerSerialMask = ~TimerIdMask & ~0x80000000; static const int TimerSerialCounter = TimerIdMask + 1; -static const int MaxTimerId = TimerSerialCounter - 1; - -enum { NumberOfBuckets = 8, FirstBucketSize = 32 }; - -static const int BucketSize[NumberOfBuckets] = - { 32, 64, 512, 4096, 32768, 262144, 2097152, 16777216 - 2364000 }; -static const int BucketOffset[NumberOfBuckets] = - { 0, 32, 96, 608, 4704, 37448, 266848, 2364000 }; +static const int MaxTimerId = TimerIdMask; static int FirstBucket[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 }; -static QBasicAtomicPointer timerIds[NumberOfBuckets] = +enum { + FirstBucketOffset = 0, + SecondBucketOffset = sizeof(FirstBucket) / sizeof(FirstBucket[0]), + ThirdBucketOffset = 0x100, + FourthBucketOffset = 0x1000, + FifthBucketOffset = 0x10000, + SixthBucketOffset = 0x100000 +}; + +enum { + FirstBucketSize = SecondBucketOffset, + SecondBucketSize = ThirdBucketOffset - SecondBucketOffset, + ThirdBucketSize = FourthBucketOffset - ThirdBucketOffset, + FourthBucketSize = FifthBucketOffset - FourthBucketOffset, + FifthBucketSize = SixthBucketOffset - FifthBucketOffset, + SixthBucketSize = MaxTimerId - SixthBucketOffset +}; + +static const int BucketSize[] = { + FirstBucketSize, SecondBucketSize, ThirdBucketSize, + FourthBucketSize, FifthBucketSize, SixthBucketSize +}; +enum { NumberOfBuckets = sizeof(BucketSize) / sizeof(BucketSize[0]) }; + +static const int BucketOffset[] = { + FirstBucketOffset, SecondBucketOffset, ThirdBucketOffset, + FourthBucketOffset, FifthBucketOffset, SixthBucketOffset +}; + +static QBasicAtomicPointer timerIds[] = { Q_BASIC_ATOMIC_INITIALIZER(FirstBucket), Q_BASIC_ATOMIC_INITIALIZER(0), Q_BASIC_ATOMIC_INITIALIZER(0), Q_BASIC_ATOMIC_INITIALIZER(0), Q_BASIC_ATOMIC_INITIALIZER(0), - Q_BASIC_ATOMIC_INITIALIZER(0), - Q_BASIC_ATOMIC_INITIALIZER(0), Q_BASIC_ATOMIC_INITIALIZER(0) }; static void timerIdsDestructorFunction() @@ -92,8 +112,17 @@ static inline int prepareNewValueWithSerialNumber(int oldId, int newId) return (newId & TimerIdMask) | ((oldId + TimerSerialCounter) & TimerSerialMask); } +namespace { + template struct QStaticAssertType; + template<> struct QStaticAssertType { enum { Value = 1 }; }; +} +#define q_static_assert(expr) (void)QStaticAssertType::Value + static inline int bucketOffset(int timerId) { + q_static_assert(sizeof BucketSize == sizeof BucketOffset); + q_static_assert(sizeof(timerIds) / sizeof(timerIds[0]) == NumberOfBuckets); + for (int i = 0; i < NumberOfBuckets; ++i) { if (timerId < BucketSize[i]) return i; -- cgit v0.12 From 94117641f97d180e0452c508fd4743bf29fb53a7 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 14 Apr 2011 12:48:25 +0200 Subject: Compile with namespace support. --- src/dbus/qdbusunixfiledescriptor.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/dbus/qdbusunixfiledescriptor.cpp b/src/dbus/qdbusunixfiledescriptor.cpp index 4817d95..f45b6cc 100644 --- a/src/dbus/qdbusunixfiledescriptor.cpp +++ b/src/dbus/qdbusunixfiledescriptor.cpp @@ -47,6 +47,8 @@ # include #endif +QT_BEGIN_NAMESPACE + /*! \class QDBusUnixFileDescriptor \inmodule QtDBus @@ -310,3 +312,5 @@ QDBusUnixFileDescriptorPrivate::~QDBusUnixFileDescriptorPrivate() } #endif + +QT_END_NAMESPACE -- cgit v0.12 From 95154796e433b2f38b0a838a77ec1c8ae1d70c43 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 14 Apr 2011 13:45:32 +0200 Subject: L10n: German translations for Qt 4.8 --- translations/assistant_de.ts | 159 +++++++++++++++++++++++++++++++++++++------ translations/designer_de.ts | 103 ++++++++++++++++++++++++++-- translations/qt_de.ts | 22 +++++- 3 files changed, 258 insertions(+), 26 deletions(-) diff --git a/translations/assistant_de.ts b/translations/assistant_de.ts index 42557e6..c8ae518 100644 --- a/translations/assistant_de.ts +++ b/translations/assistant_de.ts @@ -261,6 +261,10 @@ Grund: Adresse + Toolbar Menu + Werkzeugleisten-Menu + + Bookmarks Menu Lesezeichen-Menü @@ -288,11 +292,11 @@ Grund: CentralWidget Add new page - Neue Seite hinzufügen + Neue Seite hinzufügen Close current page - Aktuelle Seite schließen + Aktuelle Seite schließen Print Document @@ -300,27 +304,27 @@ Grund: unknown - unbekannt + unbekannt Add New Page - Neue Seite hinzufügen + Neue Seite hinzufügen Close This Page - Aktuelle Seite schließen + Aktuelle Seite schließen Close Other Pages - Andere Seiten schließen + Andere Seiten schließen Add Bookmark for this Page... - Lesezeichen für diese Seite hinzufügen ... + Lesezeichen für diese Seite hinzufügen ... Search - Suchen + Suchen @@ -640,6 +644,49 @@ Grund: + GlobalActions + + &Back + &Rückwärts + + + &Forward + &Vorwärts + + + &Home + &Startseite + + + ALT+Home + ALT+Home + + + Zoom &in + &Vergrößern + + + Zoom &out + Ver&kleinern + + + &Copy selected Text + Ausgewählten Text &kopieren + + + &Print... + &Drucken ... + + + &Find in Text... + &Textsuche ... + + + &Find + &Suchen + + + HelpEngineWrapper Unfiltered @@ -664,16 +711,32 @@ Grund: <title>Fehler 404 ...</title><div align="center"><br><br><h1>Die Seite kann nicht gefunden werden.</h1><br><h3>'%1'</h3></div> + Open Link + Link öffnen + + Copy &Link Location &Link-Adresse kopieren + Copy + Kopieren + + + Reload + Neu laden + + Open Link in New Tab Ctrl+LMB Link in neuem Reiter öffnen (Strg + linke Maustaste) Open Link in New Tab - Link in neuem Reiter öffnen + Link in neuem Reiter öffnen + + + Open Link in New Page + Link in neuer Seite öffnen @@ -881,7 +944,7 @@ Grund: &Print... - &Drucken ... + &Drucken ... New &Tab @@ -901,15 +964,15 @@ Grund: &Copy selected Text - Ausgewählten Text &kopieren + Ausgewählten Text &kopieren &Find in Text... - &Textsuche ... + &Textsuche ... &Find - &Suchen + &Suchen Find &Next @@ -925,11 +988,11 @@ Grund: Zoom &in - &Vergrößern + &Vergrößern Zoom &out - Ver&kleinern + Ver&kleinern Normal &Size @@ -953,15 +1016,15 @@ Grund: &Home - &Startseite + &Startseite &Back - &Rückwärts + &Rückwärts &Forward - &Vorwärts + &Vorwärts Sync with Table of Contents @@ -1000,6 +1063,22 @@ Grund: Über ... + Open Pages + Offene Seiten + + + Bookmark Toolbar + Lesezeichen-Leiste + + + E&xit + B&eenden + + + ALT+P + ALT+P + + Navigation Toolbar Navigationsleiste @@ -1073,7 +1152,7 @@ Grund: ALT+Home - ALT+Home + ALT+Home &Bookmarks @@ -1089,6 +1168,17 @@ Grund: + OpenPagesWidget + + Close %1 + Schließe %1 + + + Close All Except %1 + Alle außer %1 schließen + + + OutputPage Form @@ -1307,6 +1397,14 @@ Möchten Sie sie löschen? Blank Page Leere Seite + + Appearance + Erscheinungsbild + + + Show tabs for each individual page + Reiter für jede einzelne Seite anzeigen + QCollectionGenerator @@ -1507,6 +1605,29 @@ qhelpgenerator <Hilfe-Projektdatei> [Optionen] + TabBar + + (Untitled) + (Ohne Titel) + + + New &Tab + Neuer &Reiter + + + &Close Tab + Reiter &schließen + + + Close Other Tabs + Andere Reiter schließen + + + Add Bookmark for this Page... + Lesezeichen für diese Seite hinzufügen ... + + + TopicChooser Choose a topic for <b>%1</b>: diff --git a/translations/designer_de.ts b/translations/designer_de.ts index e7aeb51..91da4c0 100644 --- a/translations/designer_de.ts +++ b/translations/designer_de.ts @@ -364,7 +364,7 @@ page - Seite + Seite Insert Page @@ -476,7 +476,7 @@ subwindow - subwindow + subwindow Subwindow @@ -520,6 +520,10 @@ Layout von '%1' von %2 in %3 umwandeln + Change layout alignment + Ausrichtung des Layouts ändern + + Add '%1' to '%2' Command description for adding buttons to a QButtonGroup '%1' zu '%2' hinzufügen @@ -1834,7 +1838,7 @@ Container-Seiten sollten ausschließlich im XML der domXML()-Methode spezifizier Edit - Bearbeiten + Bearbeiten Toolbars @@ -1849,6 +1853,10 @@ Container-Seiten sollten ausschließlich im XML der domXML()-Methode spezifizier &Ansicht + &Edit + &Bearbeiten + + &Settings &Einstellungen @@ -3734,6 +3742,10 @@ Möchten Sie sie überschreiben? Geerbt + [Theme] %1 + [Thema] %1 + + Horizontal Horizontal @@ -3742,6 +3754,10 @@ Möchten Sie sie überschreiben? Vertikal + Theme + Thema + + Normal Off Normal, aus @@ -4328,6 +4344,17 @@ Möchten Sie sie überschreiben? + qdesigner_internal::IconThemeDialog + + Set Icon From Theme + Icon aus Thema setzen + + + Input icon name from the current theme: + Icon-Name vom aktuellen Thema eingeben: + + + qdesigner_internal::ItemListEditor Properties &<< @@ -4470,15 +4497,15 @@ Möchten Sie sie überschreiben? Shortcut: - Tastenkürzel + Tastenkürzel Checkable: - Ankreuzbar: + Ankreuzbar: ToolTip: - ToolTip: + ToolTip: ... @@ -4492,6 +4519,22 @@ Möchten Sie sie überschreiben? Object &name: Objekt&name: + + T&oolTip: + T&oolTip: + + + Icon th&eme: + Icon-Th&ema: + + + &Checkable: + &Ankreuzbar: + + + &Shortcut: + Tastenk&ürzel + qdesigner_internal::NewDynamicPropertyDialog @@ -4748,9 +4791,17 @@ Please select another name. Datei auswählen... + Set Icon From Theme... + Icon aus Thema setzen... + + ... ... + + [Theme] %1 + [Thema] %1 + qdesigner_internal::PlainTextEditorDialog @@ -5132,6 +5183,42 @@ Klasse: %2 Größe + Layout Alignment + Ausrichtung des Layouts + + + No Horizontal Alignment + Keine horizontale Ausrichtung + + + Left + Links + + + Center Horizontally + Horizontal zentrieren + + + Right + Rechts + + + No Vertical Alignment + Keine vertikale Ausrichtung + + + Top + Oben + + + Center Vertically + Vertikal zentrieren + + + Bottom + Unten + + Set Minimum Width Minimalbreite festlegen @@ -5338,6 +5425,10 @@ Klasse: %2 Insert &Image &Bild einfügen + + Simplify Rich Text + Formatierbaren Text vereinfachen + qdesigner_internal::ScriptDialog diff --git a/translations/qt_de.ts b/translations/qt_de.ts index 0e62340..92a9e1d 100644 --- a/translations/qt_de.ts +++ b/translations/qt_de.ts @@ -2514,6 +2514,10 @@ nach Cannot create %1 for output %1 kann nicht erstellt werden + + No file engine available or engine does not support UnMapExtension + Es ist kein Datei-Engine verfügbar oder der gegenwärtig aktive Engine unterstützt die UnMap-Erweiterung nicht + QFileDialog @@ -3483,6 +3487,18 @@ Möchten Sie die Datei trotzdem löschen? Cannot resolve symbol "%1" in %2: %3 Das Symbol "%1" kann in %2 nicht aufgelöst werden: %3 + + '%1' is not an ELF object (%2) + '%1' ist keine ELF-Objektdatei (%2) + + + '%1' is not an ELF object + '%1' ist keine ELF-Objektdatei + + + '%1' is an invalid ELF object (%2) + '%1' ist keine gültige ELF-Objektdatei (%2) + QLineEdit @@ -3580,6 +3596,10 @@ Möchten Sie die Datei trotzdem löschen? %1: Unknown error %2 %1: Unbekannter Fehler %2 + + %1: Access denied + %1: Zugriff verweigert + QMYSQLDriver @@ -3922,7 +3942,7 @@ Möchten Sie die Datei trotzdem löschen? QNetworkAccessDataBackend Operation not supported on %1 - Diese Operation wird von %1 nicht unterstützt + Diese Operation wird von %1 nicht unterstützt Invalid URI: %1 -- cgit v0.12 From 72032a323d2a08e414e2b09ca37b0a514e0021f2 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 17 Apr 2011 15:58:33 +0200 Subject: Do not try to test UnixFDs with the system API because it may be too old --- tests/auto/qdbustype/tst_qdbustype.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/auto/qdbustype/tst_qdbustype.cpp b/tests/auto/qdbustype/tst_qdbustype.cpp index 0469719..676a904 100644 --- a/tests/auto/qdbustype/tst_qdbustype.cpp +++ b/tests/auto/qdbustype/tst_qdbustype.cpp @@ -85,7 +85,9 @@ static void addFixedTypes() QTest::newRow("int64") << DBUS_TYPE_INT64_AS_STRING << true << true; QTest::newRow("uint64") << DBUS_TYPE_UINT64_AS_STRING << true << true; QTest::newRow("double") << DBUS_TYPE_DOUBLE_AS_STRING << true << true; - QTest::newRow("unixfd") << "h" << true << true; +#ifdef DBUS_TYPE_UNIX_FD_AS_STRING + QTest::newRow("unixfd") << DBUS_TYPE_UNIX_FD_AS_STRING << true << true; +#endif } static void addInvalidSingleLetterTypes() -- cgit v0.12 From d4fa1878ff1e7628d3e984d54f8a93810353c71b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 17 Apr 2011 16:34:22 +0200 Subject: Fix warning about vSize not being used in this function --- src/declarative/graphicsitems/qdeclarativeflickable.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp index 1d50baf..3dd194b 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp @@ -266,7 +266,7 @@ void QDeclarativeFlickablePrivate::flickY(qreal velocity) flick(vData, q->minYExtent(), q->maxYExtent(), q->height(), fixupY_callback, velocity); } -void QDeclarativeFlickablePrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize, +void QDeclarativeFlickablePrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal, QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity) { Q_Q(QDeclarativeFlickable); -- cgit v0.12 From 9b97e319fc2a8e48a454725a5eb54edeb305a27c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 18 Apr 2011 13:02:36 +0200 Subject: Revert "Fix strict-alias breaking warnings with GCC." This reverts commit 0d3044b547614cbd313d90021606af1f81fb10de. I'm not sure if this is good for anything. I can't reproduce the failures that happen on Mac and Windows, so let's try reverting the only patch that touches QtDeclarative. If this works, then we'll have found out that the code is broken and my patch only revealed the errors. --- .../qml/qdeclarativeobjectscriptclass.cpp | 115 ++++++++------------- 1 file changed, 43 insertions(+), 72 deletions(-) diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp index a2411b9..dc3ecca 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp @@ -632,6 +632,7 @@ QDeclarativeObjectMethodScriptClass::property(Object *, const Identifier &name) namespace { struct MetaCallArgument { + inline MetaCallArgument(); inline ~MetaCallArgument(); inline void *dataPtr(); @@ -639,45 +640,15 @@ struct MetaCallArgument { void fromScriptValue(int type, QDeclarativeEngine *, const QScriptValue &); inline QScriptDeclarativeClass::Value toValue(QDeclarativeEngine *); -protected: - inline MetaCallArgument(); - private: MetaCallArgument(const MetaCallArgument &); - template T &as(); inline void cleanup(); + char data[4 * sizeof(void *)]; int type; bool isObjectType; - char padding[6]; // ensure sizeof(MetaCallArgument) == 8 -}; - -template struct TypedMetaCallArgument: public MetaCallArgument -{ - T data; -protected: - TypedMetaCallArgument() {} - ~TypedMetaCallArgument() {} -private: - TypedMetaCallArgument(const TypedMetaCallArgument &); }; - -struct GenericPayload { void *data[4]; }; -struct GenericMetaCallArgument: public TypedMetaCallArgument -{ -}; - -template T &MetaCallArgument::as() -{ -#ifdef Q_ALIGNOF - // static assert - char dummy_array[Q_ALIGNOF(T) <= sizeof(*this) ? 1 : -1]; Q_UNUSED(dummy_array); -#endif - TypedMetaCallArgument &typed = static_cast &>(*this); - return typed.data; -} - } MetaCallArgument::MetaCallArgument() @@ -693,22 +664,22 @@ MetaCallArgument::~MetaCallArgument() void MetaCallArgument::cleanup() { if (type == QMetaType::QString) { - as().~QString(); + ((QString *)&data)->~QString(); } else if (type == -1 || type == qMetaTypeId()) { - as().~QVariant(); + ((QVariant *)&data)->~QVariant(); } else if (type == qMetaTypeId()) { - as().~QScriptValue(); + ((QScriptValue *)&data)->~QScriptValue(); } else if (type == qMetaTypeId >()) { - as >().~QList(); + ((QList *)&data)->~QList(); } } void *MetaCallArgument::dataPtr() { if (type == -1) - return as().data(); + return ((QVariant *)data)->data(); else - return &as(); + return (void *)&data; } void MetaCallArgument::initAsType(int callType, QDeclarativeEngine *e) @@ -719,7 +690,7 @@ void MetaCallArgument::initAsType(int callType, QDeclarativeEngine *e) QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(e); if (callType == qMetaTypeId()) { - new (&as()) QScriptValue(engine->undefinedValue()); + new (&data) QScriptValue(engine->undefinedValue()); type = callType; } else if (callType == QMetaType::Int || callType == QMetaType::UInt || @@ -728,20 +699,20 @@ void MetaCallArgument::initAsType(int callType, QDeclarativeEngine *e) callType == QMetaType::Float) { type = callType; } else if (callType == QMetaType::QObjectStar) { - as() = 0; + *((QObject **)&data) = 0; type = callType; } else if (callType == QMetaType::QString) { - new (&as()) QString(); + new (&data) QString(); type = callType; } else if (callType == qMetaTypeId()) { type = callType; - new (&as()) QVariant(); + new (&data) QVariant(); } else if (callType == qMetaTypeId >()) { type = callType; - new (&as >()) QList(); + new (&data) QList(); } else { type = -1; - new (&as()) QVariant(callType, (void *)0); + new (&data) QVariant(callType, (void *)0); } } @@ -750,37 +721,37 @@ void MetaCallArgument::fromScriptValue(int callType, QDeclarativeEngine *engine, if (type != 0) { cleanup(); type = 0; } if (callType == qMetaTypeId()) { - new (&as()) QScriptValue(value); + new (&data) QScriptValue(value); type = qMetaTypeId(); } else if (callType == QMetaType::Int) { - as() = int(value.toInt32()); + *((int *)&data) = int(value.toInt32()); type = callType; } else if (callType == QMetaType::UInt) { - as() = uint(value.toUInt32()); + *((uint *)&data) = uint(value.toUInt32()); type = callType; } else if (callType == QMetaType::Bool) { - as() = value.toBool(); + *((bool *)&data) = value.toBool(); type = callType; } else if (callType == QMetaType::Double) { - as() = double(value.toNumber()); + *((double *)&data) = double(value.toNumber()); type = callType; } else if (callType == QMetaType::Float) { - as() = float(value.toNumber()); + *((float *)&data) = float(value.toNumber()); type = callType; } else if (callType == QMetaType::QString) { if (value.isNull() || value.isUndefined()) - new (&as()) QString(); + new (&data) QString(); else - new (&as()) QString(value.toString()); + new (&data) QString(value.toString()); type = callType; } else if (callType == QMetaType::QObjectStar) { - as() = value.toQObject(); + *((QObject **)&data) = value.toQObject(); type = callType; } else if (callType == qMetaTypeId()) { - new (&as()) QVariant(QDeclarativeEnginePrivate::get(engine)->scriptValueToVariant(value)); + new (&data) QVariant(QDeclarativeEnginePrivate::get(engine)->scriptValueToVariant(value)); type = callType; } else if (callType == qMetaTypeId >()) { - QList *list = new (&as >()) QList(); + QList *list = new (&data) QList(); if (value.isArray()) { int length = value.property(QLatin1String("length")).toInt32(); for (int ii = 0; ii < length; ++ii) { @@ -793,16 +764,16 @@ void MetaCallArgument::fromScriptValue(int callType, QDeclarativeEngine *engine, } type = callType; } else { - new (&as()) QVariant(); + new (&data) QVariant(); type = -1; QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(engine); QVariant v = priv->scriptValueToVariant(value); if (v.userType() == callType) { - as() = v; + *((QVariant *)&data) = v; } else if (v.canConvert((QVariant::Type)callType)) { - as() = v; - as().convert((QVariant::Type)callType); + *((QVariant *)&data) = v; + ((QVariant *)&data)->convert((QVariant::Type)callType); } else if (const QMetaObject *mo = priv->rawMetaObjectForType(callType)) { QObject *obj = priv->toQObject(v); @@ -812,9 +783,9 @@ void MetaCallArgument::fromScriptValue(int callType, QDeclarativeEngine *engine, if (!objMo) obj = 0; } - as() = QVariant(callType, &obj); + *((QVariant *)&data) = QVariant(callType, &obj); } else { - as() = QVariant(callType, (void *)0); + *((QVariant *)&data) = QVariant(callType, (void *)0); } } } @@ -824,27 +795,27 @@ QScriptDeclarativeClass::Value MetaCallArgument::toValue(QDeclarativeEngine *e) QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(e); if (type == qMetaTypeId()) { - return QScriptDeclarativeClass::Value(engine, as()); + return QScriptDeclarativeClass::Value(engine, *((QScriptValue *)&data)); } else if (type == QMetaType::Int) { - return QScriptDeclarativeClass::Value(engine, as()); + return QScriptDeclarativeClass::Value(engine, *((int *)&data)); } else if (type == QMetaType::UInt) { - return QScriptDeclarativeClass::Value(engine, as()); + return QScriptDeclarativeClass::Value(engine, *((uint *)&data)); } else if (type == QMetaType::Bool) { - return QScriptDeclarativeClass::Value(engine, as()); + return QScriptDeclarativeClass::Value(engine, *((bool *)&data)); } else if (type == QMetaType::Double) { - return QScriptDeclarativeClass::Value(engine, as()); + return QScriptDeclarativeClass::Value(engine, *((double *)&data)); } else if (type == QMetaType::Float) { - return QScriptDeclarativeClass::Value(engine, as()); + return QScriptDeclarativeClass::Value(engine, *((float *)&data)); } else if (type == QMetaType::QString) { - return QScriptDeclarativeClass::Value(engine, as()); + return QScriptDeclarativeClass::Value(engine, *((QString *)&data)); } else if (type == QMetaType::QObjectStar) { - QObject *object = as(); + QObject *object = *((QObject **)&data); if (object) QDeclarativeData::get(object, true)->setImplicitDestructible(); QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(e); return QScriptDeclarativeClass::Value(engine, priv->objectClass->newQObject(object)); } else if (type == qMetaTypeId >()) { - QList &list = as >(); + QList &list = *(QList*)&data; QScriptValue rv = engine->newArray(list.count()); QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(e); for (int ii = 0; ii < list.count(); ++ii) { @@ -855,7 +826,7 @@ QScriptDeclarativeClass::Value MetaCallArgument::toValue(QDeclarativeEngine *e) return QScriptDeclarativeClass::Value(engine, rv); } else if (type == -1 || type == qMetaTypeId()) { QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(e); - QScriptValue rv = ep->scriptValueFromVariant(as()); + QScriptValue rv = ep->scriptValueFromVariant(*((QVariant *)&data)); if (rv.isQObject()) { QObject *object = rv.toQObject(); if (object) @@ -935,7 +906,7 @@ QDeclarativeObjectMethodScriptClass::callMethod(QObject *object, int index, { if (argCount > 0) { - QVarLengthArray args(argCount + 1); + QVarLengthArray args(argCount + 1); args[0].initAsType(returnType, engine); for (int ii = 0; ii < argCount; ++ii) @@ -951,7 +922,7 @@ QDeclarativeObjectMethodScriptClass::callMethod(QObject *object, int index, } else if (returnType != 0) { - GenericMetaCallArgument arg; + MetaCallArgument arg; arg.initAsType(returnType, engine); void *args[] = { arg.dataPtr() }; -- cgit v0.12 From 8856e2412fc2756443288644465d9edce5798fea Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 18 Apr 2011 13:15:36 +0200 Subject: Alternative fix to the strict-aliasing violation warnings The code doesn't actually violate aliasing by doing type-punned dereferencing. The objects are always accessed as the right type. So disable the warning and pray that GCC doesn't optimise code out of existence. Reviewed-by: Trust Me --- src/declarative/qml/qdeclarativeobjectscriptclass.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp index dc3ecca..9eecc65 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp @@ -54,7 +54,15 @@ #include #include -Q_DECLARE_METATYPE(QScriptValue); +Q_DECLARE_METATYPE(QScriptValue) + +#if defined(__GNUC__) +# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405 +// The code in this file does not violate strict aliasing, but GCC thinks it does +// so turn off the warnings for us to have a clean build +# pragma GCC diagnostic ignored "-Wstrict-aliasing" +# endif +#endif QT_BEGIN_NAMESPACE -- cgit v0.12 From d0245f57d1b617a61bb7472c232be5b974892369 Mon Sep 17 00:00:00 2001 From: Robert Griebl Date: Mon, 18 Apr 2011 14:26:46 +0200 Subject: Use s/static/Q_GLOBAL_STATIC/g in QScroller Reviewed-by: Harald Fernengel --- src/gui/util/qscroller.cpp | 24 +++++++++++++----------- src/gui/util/qscroller_p.h | 4 ---- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/gui/util/qscroller.cpp b/src/gui/util/qscroller.cpp index 9c2d24d..db128c1 100644 --- a/src/gui/util/qscroller.cpp +++ b/src/gui/util/qscroller.cpp @@ -279,9 +279,11 @@ private: \sa QScrollEvent, QScrollPrepareEvent, QScrollerProperties */ +typedef QMap ScrollerHash; +typedef QSet ScrollerSet; -QMap QScrollerPrivate::allScrollers; -QSet QScrollerPrivate::activeScrollers; +Q_GLOBAL_STATIC(ScrollerHash, qt_allScrollers) +Q_GLOBAL_STATIC(ScrollerSet, qt_activeScrollers) /*! Returns \c true if a QScroller object was already created for \a target; \c false otherwise. @@ -290,7 +292,7 @@ QSet QScrollerPrivate::activeScrollers; */ bool QScroller::hasScroller(QObject *target) { - return (QScrollerPrivate::allScrollers.value(target)); + return (qt_allScrollers()->value(target)); } /*! @@ -308,11 +310,11 @@ QScroller *QScroller::scroller(QObject *target) return 0; } - if (QScrollerPrivate::allScrollers.contains(target)) - return QScrollerPrivate::allScrollers.value(target); + if (qt_allScrollers()->contains(target)) + return qt_allScrollers()->value(target); QScroller *s = new QScroller(target); - QScrollerPrivate::allScrollers.insert(target, s); + qt_allScrollers()->insert(target, s); return s; } @@ -332,7 +334,7 @@ const QScroller *QScroller::scroller(const QObject *target) */ QList QScroller::activeScrollers() { - return QScrollerPrivate::activeScrollers.toList(); + return qt_activeScrollers()->toList(); } /*! @@ -508,8 +510,8 @@ QScroller::~QScroller() // do not delete the recognizer. The QGestureManager is doing this. d->recognizer = 0; #endif - QScrollerPrivate::allScrollers.remove(d->target); - QScrollerPrivate::activeScrollers.remove(this); + qt_allScrollers()->remove(d->target); + qt_activeScrollers()->remove(this); delete d_ptr; } @@ -1754,9 +1756,9 @@ void QScrollerPrivate::setState(QScroller::State newstate) firstScroll = true; } if (state == QScroller::Dragging || state == QScroller::Scrolling) - activeScrollers.insert(q); + qt_activeScrollers()->insert(q); else - activeScrollers.remove(q); + qt_activeScrollers()->remove(q); emit q->stateChanged(state); } diff --git a/src/gui/util/qscroller_p.h b/src/gui/util/qscroller_p.h index 8c5f2e7..c119615 100644 --- a/src/gui/util/qscroller_p.h +++ b/src/gui/util/qscroller_p.h @@ -148,10 +148,6 @@ public slots: void targetDestroyed(); public: - // static - static QMap allScrollers; - static QSet activeScrollers; - // non static QObject *target; QScrollerProperties properties; -- cgit v0.12