/**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/ ** ** This file is part of the QtDBus module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** GNU Lesser General Public License Usage ** 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. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU General ** Public License version 3.0 as published by the Free Software Foundation ** and appearing in the file LICENSE.GPL included in the packaging of this ** file. Please review the following information to ensure the GNU General ** Public License version 3.0 requirements will be met: ** http://www.gnu.org/copyleft/gpl.html. ** ** Other Usage ** Alternatively, this file may be used in accordance with the terms and ** conditions contained in a signed written agreement between you and Nokia. ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef QDBUSPENDINGREPLY_H #define QDBUSPENDINGREPLY_H #include #include #include #include #ifndef QT_NO_DBUS QT_BEGIN_HEADER QT_BEGIN_NAMESPACE class Q_DBUS_EXPORT QDBusPendingReplyData: public QDBusPendingCall { protected: QDBusPendingReplyData(); ~QDBusPendingReplyData(); void assign(const QDBusPendingCall &call); void assign(const QDBusMessage &message); QVariant argumentAt(int index) const; void setMetaTypes(int count, const int *metaTypes); }; namespace QDBusPendingReplyTypes { template struct Select { typedef Select Next; typedef typename Next::Type Type; }; template struct Select<0, T1, T2, T3, T4, T5, T6, T7, T8> { typedef T1 Type; }; template inline int metaTypeFor(T1 * = 0) { return qMetaTypeId(); } // specialize for QVariant, allowing it to be used in place of QDBusVariant template<> inline int metaTypeFor(QVariant *) { return qMetaTypeId(); } template struct ForEach { typedef ForEach Next; enum { Total = Next::Total + 1 }; static inline void fillMetaTypes(int *p) { *p = metaTypeFor(0); Next::fillMetaTypes(++p); } }; template<> struct ForEach { enum { Total = 0 }; static inline void fillMetaTypes(int *) { } }; } // namespace QDBusPendingReplyTypes template class QDBusPendingReply: #ifdef Q_QDOC public QDBusPendingCall #else public QDBusPendingReplyData #endif { typedef QDBusPendingReplyTypes::ForEach ForEach; template struct Select : QDBusPendingReplyTypes::Select { }; public: enum { Count = ForEach::Total }; inline QDBusPendingReply() { } inline QDBusPendingReply(const QDBusPendingReply &other) : QDBusPendingReplyData(other) { } inline QDBusPendingReply(const QDBusPendingCall &call) { *this = call; } inline QDBusPendingReply(const QDBusMessage &message) { *this = message; } inline QDBusPendingReply &operator=(const QDBusPendingReply &other) { assign(other); return *this; } inline QDBusPendingReply &operator=(const QDBusPendingCall &call) { assign(call); return *this; } inline QDBusPendingReply &operator=(const QDBusMessage &message) { assign(message); return *this; } inline int count() const { return Count; } #if defined(Q_QDOC) || defined(Q_NO_USING_KEYWORD) inline QVariant argumentAt(int index) const { return QDBusPendingReplyData::argumentAt(index); } #else using QDBusPendingReplyData::argumentAt; #endif #if defined(Q_QDOC) bool isFinished() const; void waitForFinished(); bool isValid() const; bool isError() const; QDBusError error() const; QDBusMessage reply() const; template inline Type argumentAt() const; inline T1 value() const; inline operator T1() const; #else template inline const typename Select::Type argumentAt() const { // static assert? Q_ASSERT_X(Index < count() && Index >= 0, "QDBusPendingReply::argumentAt", "Index out of bounds"); typedef typename Select::Type ResultType; return qdbus_cast(argumentAt(Index), 0); } inline typename Select<0>::Type value() const { return argumentAt<0>(); } inline operator typename Select<0>::Type() const { return argumentAt<0>(); } #endif private: inline void calculateMetaTypes() { if (!d) return; int typeIds[Count > 0 ? Count : 1]; // use at least one since zero-sized arrays aren't valid ForEach::fillMetaTypes(typeIds); setMetaTypes(Count, typeIds); } inline void assign(const QDBusPendingCall &call) { QDBusPendingReplyData::assign(call); calculateMetaTypes(); } inline void assign(const QDBusMessage &message) { QDBusPendingReplyData::assign(message); calculateMetaTypes(); } }; QT_END_NAMESPACE QT_END_HEADER #endif // QT_NO_DBUS #endif