source: trunk/src/dbus/qdbusreply.cpp@ 5

Last change on this file since 5 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 8.8 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtDBus module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qdbusreply.h"
43#include "qdbusmetatype.h"
44#include "qdbusmetatype_p.h"
45#include <QDebug>
46
47QT_BEGIN_NAMESPACE
48
49/*!
50 \class QDBusReply
51 \inmodule QtDBus
52 \since 4.2
53
54 \brief The QDBusReply class stores the reply for a method call to a remote object.
55
56 A QDBusReply object is a subset of the QDBusMessage object that represents a method call's
57 reply. It contains only the first output argument or the error code and is used by
58 QDBusInterface-derived classes to allow returning the error code as the function's return
59 argument.
60
61 It can be used in the following manner:
62 \snippet doc/src/snippets/code/src_qdbus_qdbusreply.cpp 0
63
64 If the remote method call cannot fail, you can skip the error checking:
65 \snippet doc/src/snippets/code/src_qdbus_qdbusreply.cpp 1
66
67 However, if it does fail under those conditions, the value returned by QDBusReply::value() is
68 a default-constructed value. It may be indistinguishable from a valid return value.
69
70 QDBusReply objects are used for remote calls that have no output
71 arguments or return values (i.e., they have a "void" return
72 type). Use the isValid() function to test if the reply succeeded.
73
74 \sa QDBusMessage, QDBusInterface
75*/
76
77/*!
78 \fn QDBusReply::QDBusReply(const QDBusMessage &reply)
79 Automatically construct a QDBusReply object from the reply message \a reply, extracting the
80 first return value from it if it is a success reply.
81*/
82
83/*!
84 \fn QDBusReply::QDBusReply(const QDBusPendingReply<T> &reply)
85 Constructs a QDBusReply object from the pending reply message, \a reply.
86*/
87
88/*!
89 \fn QDBusReply::QDBusReply(const QDBusPendingCall &pcall)
90 Automatically construct a QDBusReply object from the asynchronous
91 pending call \a pcall. If the call isn't finished yet, QDBusReply
92 will call QDBusPendingCall::waitForFinished(), which is a blocking
93 operation.
94
95 If the return types patch, QDBusReply will extract the first
96 return argument from the reply.
97*/
98
99/*!
100 \fn QDBusReply::QDBusReply(const QDBusError &error)
101 Constructs an error reply from the D-Bus error code given by \a error.
102*/
103
104/*!
105 \fn QDBusReply::operator=(const QDBusReply &other)
106 Makes this object be a copy of the object \a other.
107*/
108
109/*!
110 \fn QDBusReply::operator=(const QDBusError &error)
111 Sets this object to contain the error code given by \a error. You
112 can later access it with error().
113*/
114
115/*!
116 \fn QDBusReply::operator=(const QDBusMessage &message)
117
118 Makes this object contain the reply specified by message \a
119 message. If \a message is an error message, this function will
120 copy the error code and message into this object
121
122 If \a message is a standard reply message and contains at least
123 one parameter, it will be copied into this object, as long as it
124 is of the correct type. If it's not of the same type as this
125 QDBusError object, this function will instead set an error code
126 indicating a type mismatch.
127*/
128
129/*!
130 \fn QDBusReply::operator=(const QDBusPendingCall &pcall)
131
132 Makes this object contain the reply specified by the pending
133 asynchronous call \a pcall. If the call is not finished yet, this
134 function will call QDBusPendingCall::waitForFinished() to block
135 until the reply arrives.
136
137 If \a pcall finishes with an error message, this function will
138 copy the error code and message into this object
139
140 If \a pcall finished with a standard reply message and contains at
141 least one parameter, it will be copied into this object, as long
142 as it is of the correct type. If it's not of the same type as this
143 QDBusError object, this function will instead set an error code
144 indicating a type mismatch.
145*/
146
147/*!
148 \fn bool QDBusReply::isValid() const
149
150 Returns true if no error occurred; otherwise, returns false.
151
152 \sa error()
153*/
154
155/*!
156 \fn QDBusReply::error()
157
158 Returns the error code that was returned from the remote function call. If the remote call did
159 not return an error (i.e., if it succeeded), then the QDBusError object that is returned will
160 not be a valid error code (QDBusError::isValid() will return false).
161
162 \sa isValid()
163*/
164
165/*!
166 \fn QDBusReply::value() const
167 Returns the remote function's calls return value. If the remote call returned with an error,
168 the return value of this function is undefined and may be undistinguishable from a valid return
169 value.
170
171 This function is not available if the remote call returns \c void.
172*/
173
174/*!
175 \fn QDBusReply::operator Type() const
176 Returns the same as value().
177
178 This function is not available if the remote call returns \c void.
179*/
180
181/*!
182 \internal
183 Fills in the QDBusReply data \a error and \a data from the reply message \a reply.
184*/
185void qDBusReplyFill(const QDBusMessage &reply, QDBusError &error, QVariant &data)
186{
187 error = reply;
188
189 if (error.isValid()) {
190 data = QVariant(); // clear it
191 return;
192 }
193
194 if (reply.arguments().count() >= 1 && reply.arguments().at(0).userType() == data.userType()) {
195 data = reply.arguments().at(0);
196 return;
197 }
198
199 const char *expectedSignature = QDBusMetaType::typeToSignature(data.userType());
200 const char *receivedType = 0;
201 QByteArray receivedSignature;
202
203 if (reply.arguments().count() >= 1) {
204 if (reply.arguments().at(0).userType() == QDBusMetaTypeId::argument) {
205 // compare signatures instead
206 QDBusArgument arg = qvariant_cast<QDBusArgument>(reply.arguments().at(0));
207 receivedSignature = arg.currentSignature().toLatin1();
208 if (receivedSignature == expectedSignature) {
209 // matched. Demarshall it
210 QDBusMetaType::demarshall(arg, data.userType(), data.data());
211 return;
212 }
213 } else {
214 // not an argument and doesn't match?
215 int type = reply.arguments().at(0).userType();
216 receivedType = QVariant::typeToName(QVariant::Type(type));
217 receivedSignature = QDBusMetaType::typeToSignature(type);
218 }
219 }
220
221 // error
222 if (receivedSignature.isEmpty())
223 receivedSignature = "no signature";
224 QString errorMsg;
225 if (receivedType) {
226 errorMsg = QString::fromLatin1("Unexpected reply signature: got \"%1\" (%4), "
227 "expected \"%2\" (%3)")
228 .arg(QLatin1String(receivedSignature),
229 QLatin1String(expectedSignature),
230 QLatin1String(data.typeName()),
231 QLatin1String(receivedType));
232 } else {
233 errorMsg = QString::fromLatin1("Unexpected reply signature: got \"%1\", "
234 "expected \"%2\" (%3)")
235 .arg(QLatin1String(receivedSignature),
236 QLatin1String(expectedSignature),
237 QLatin1String(data.typeName()));
238 }
239
240 error = QDBusError(QDBusError::InvalidSignature, errorMsg);
241 data = QVariant(); // clear it
242}
243
244QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.