1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtDBus module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qdbusreply.h"
43 #include "qdbusmetatype.h"
44 #include "qdbusmetatype_p.h"
56 \brief The QDBusReply class stores the reply for a method call to a remote object.
58 A QDBusReply object is a subset of the QDBusMessage object that represents a method call's
59 reply. It contains only the first output argument or the error code and is used by
60 QDBusInterface-derived classes to allow returning the error code as the function's return
63 It can be used in the following manner:
64 \snippet doc/src/snippets/code/src_qdbus_qdbusreply.cpp 0
66 If the remote method call cannot fail, you can skip the error checking:
67 \snippet doc/src/snippets/code/src_qdbus_qdbusreply.cpp 1
69 However, if it does fail under those conditions, the value returned by QDBusReply::value() is
70 a default-constructed value. It may be indistinguishable from a valid return value.
72 QDBusReply objects are used for remote calls that have no output
73 arguments or return values (i.e., they have a "void" return
74 type). Use the isValid() function to test if the reply succeeded.
76 \sa QDBusMessage, QDBusInterface
80 \fn QDBusReply::QDBusReply(const QDBusMessage &reply)
81 Automatically construct a QDBusReply object from the reply message \a reply, extracting the
82 first return value from it if it is a success reply.
86 \fn QDBusReply::QDBusReply(const QDBusPendingReply<T> &reply)
87 Constructs a QDBusReply object from the pending reply message, \a reply.
91 \fn QDBusReply::QDBusReply(const QDBusPendingCall &pcall)
92 Automatically construct a QDBusReply object from the asynchronous
93 pending call \a pcall. If the call isn't finished yet, QDBusReply
94 will call QDBusPendingCall::waitForFinished(), which is a blocking
97 If the return types patch, QDBusReply will extract the first
98 return argument from the reply.
102 \fn QDBusReply::QDBusReply(const QDBusError &error)
103 Constructs an error reply from the D-Bus error code given by \a error.
107 \fn QDBusReply::operator=(const QDBusReply &other)
108 Makes this object be a copy of the object \a other.
112 \fn QDBusReply::operator=(const QDBusError &error)
113 Sets this object to contain the error code given by \a error. You
114 can later access it with error().
118 \fn QDBusReply::operator=(const QDBusMessage &message)
120 Makes this object contain the reply specified by message \a
121 message. If \a message is an error message, this function will
122 copy the error code and message into this object
124 If \a message is a standard reply message and contains at least
125 one parameter, it will be copied into this object, as long as it
126 is of the correct type. If it's not of the same type as this
127 QDBusError object, this function will instead set an error code
128 indicating a type mismatch.
132 \fn QDBusReply::operator=(const QDBusPendingCall &pcall)
134 Makes this object contain the reply specified by the pending
135 asynchronous call \a pcall. If the call is not finished yet, this
136 function will call QDBusPendingCall::waitForFinished() to block
137 until the reply arrives.
139 If \a pcall finishes with an error message, this function will
140 copy the error code and message into this object
142 If \a pcall finished with a standard reply message and contains at
143 least one parameter, it will be copied into this object, as long
144 as it is of the correct type. If it's not of the same type as this
145 QDBusError object, this function will instead set an error code
146 indicating a type mismatch.
150 \fn bool QDBusReply::isValid() const
152 Returns true if no error occurred; otherwise, returns false.
158 \fn QDBusReply::error()
160 Returns the error code that was returned from the remote function call. If the remote call did
161 not return an error (i.e., if it succeeded), then the QDBusError object that is returned will
162 not be a valid error code (QDBusError::isValid() will return false).
168 \fn QDBusReply::value() const
169 Returns the remote function's calls return value. If the remote call returned with an error,
170 the return value of this function is undefined and may be undistinguishable from a valid return
173 This function is not available if the remote call returns \c void.
177 \fn QDBusReply::operator Type() const
178 Returns the same as value().
180 This function is not available if the remote call returns \c void.
185 Fills in the QDBusReply data \a error and \a data from the reply message \a reply.
187 void qDBusReplyFill(const QDBusMessage &reply, QDBusError &error, QVariant &data)
189 error = QDBusError(reply);
191 if (error.isValid()) {
192 data = QVariant(); // clear it
196 if (reply.arguments().count() >= 1 && reply.arguments().at(0).userType() == data.userType()) {
197 data = reply.arguments().at(0);
201 const char *expectedSignature = QDBusMetaType::typeToSignature(data.userType());
202 const char *receivedType = 0;
203 QByteArray receivedSignature;
205 if (reply.arguments().count() >= 1) {
206 if (reply.arguments().at(0).userType() == QDBusMetaTypeId::argument) {
207 // compare signatures instead
208 QDBusArgument arg = qvariant_cast<QDBusArgument>(reply.arguments().at(0));
209 receivedSignature = arg.currentSignature().toLatin1();
210 if (receivedSignature == expectedSignature) {
211 // matched. Demarshall it
212 QDBusMetaType::demarshall(arg, data.userType(), data.data());
216 // not an argument and doesn't match?
217 int type = reply.arguments().at(0).userType();
218 receivedType = QVariant::typeToName(QVariant::Type(type));
219 receivedSignature = QDBusMetaType::typeToSignature(type);
224 if (receivedSignature.isEmpty())
225 receivedSignature = "no signature";
228 errorMsg = QString::fromLatin1("Unexpected reply signature: got \"%1\" (%4), "
229 "expected \"%2\" (%3)")
230 .arg(QLatin1String(receivedSignature),
231 QLatin1String(expectedSignature),
232 QLatin1String(data.typeName()),
233 QLatin1String(receivedType));
235 errorMsg = QString::fromLatin1("Unexpected reply signature: got \"%1\", "
236 "expected \"%2\" (%3)")
237 .arg(QLatin1String(receivedSignature),
238 QLatin1String(expectedSignature),
239 QLatin1String(data.typeName()));
242 error = QDBusError(QDBusError::InvalidSignature, errorMsg);
243 data = QVariant(); // clear it