1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). |
4 | ** Contact: http://www.qt-project.org/legal |
5 | ** |
6 | ** This file is part of the QtDBus module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and Digia. For licensing terms and |
14 | ** conditions see http://qt.digia.com/licensing. For further information |
15 | ** use the contact form at http://qt.digia.com/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 2.1 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 2.1 requirements |
23 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
24 | ** |
25 | ** In addition, as a special exception, Digia gives you certain additional |
26 | ** rights. These rights are described in the Digia Qt LGPL Exception |
27 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
28 | ** |
29 | ** GNU General Public License Usage |
30 | ** Alternatively, this file may be used under the terms of the GNU |
31 | ** General Public License version 3.0 as published by the Free Software |
32 | ** Foundation and appearing in the file LICENSE.GPL included in the |
33 | ** packaging of this file. Please review the following information to |
34 | ** ensure the GNU General Public License version 3.0 requirements will be |
35 | ** met: http://www.gnu.org/copyleft/gpl.html. |
36 | ** |
37 | ** |
38 | ** $QT_END_LICENSE$ |
39 | ** |
40 | ****************************************************************************/ |
41 | |
42 | #include "qdbuspendingreply.h" |
43 | #include "qdbuspendingcall_p.h" |
44 | #include "qdbusmetatype.h" |
45 | |
46 | #ifndef QT_NO_DBUS |
47 | |
48 | /*! |
49 | \class QDBusPendingReply |
50 | \inmodule QtDBus |
51 | \since 4.5 |
52 | |
53 | \brief The QDBusPendingReply class contains the reply to an asynchronous method call |
54 | |
55 | The QDBusPendingReply is a template class with up to 8 template |
56 | parameters. Those parameters are the types that will be used to |
57 | extract the contents of the reply's data. |
58 | |
59 | This class is similar in functionality to QDBusReply, but with two |
60 | important differences: |
61 | |
62 | \list |
63 | \o QDBusReply accepts exactly one return type, whereas |
64 | QDBusPendingReply can have from 1 to 8 types |
65 | \o QDBusReply only works on already completed replies, whereas |
66 | QDBusPendingReply allows one to wait for replies from pending |
67 | calls |
68 | \endlist |
69 | |
70 | Where with QDBusReply you would write: |
71 | |
72 | \snippet doc/src/snippets/code/src_qdbus_qdbusreply.cpp 0 |
73 | |
74 | with QDBusPendingReply, the equivalent code (including the blocking |
75 | wait for the reply) would be: |
76 | |
77 | \snippet doc/src/snippets/code/src.qdbus.qdbuspendingreply.cpp 0 |
78 | |
79 | For method calls that have more than one output argument, with |
80 | QDBusReply, you would write: |
81 | |
82 | \snippet doc/src/snippets/code/src_qdbus_qdbusreply.cpp 1 |
83 | |
84 | whereas with QDBusPendingReply, all of the output arguments should |
85 | be template parameters: |
86 | |
87 | \snippet doc/src/snippets/code/src.qdbus.qdbuspendingreply.cpp 2 |
88 | |
89 | QDBusPendingReply objects can be associated with |
90 | QDBusPendingCallWatcher objects, which emit signals when the reply |
91 | arrives. |
92 | |
93 | \sa QDBusPendingCallWatcher, QDBusReply, |
94 | QDBusAbstractInterface::asyncCall() |
95 | */ |
96 | |
97 | /*! |
98 | \fn QDBusPendingReply::QDBusPendingReply() |
99 | |
100 | Creates an empty QDBusPendingReply object. Without assigning a |
101 | QDBusPendingCall object to this reply, QDBusPendingReply cannot do |
102 | anything. All functions return their failure values. |
103 | */ |
104 | |
105 | /*! |
106 | \fn QDBusPendingReply::QDBusPendingReply(const QDBusPendingReply &other) |
107 | |
108 | Creates a copy of the \a other QDBusPendingReply object. Just like |
109 | QDBusPendingCall and QDBusPendingCallWatcher, this QDBusPendingReply |
110 | object will share the same pending call reference. All copies |
111 | share the same return values. |
112 | */ |
113 | |
114 | /*! |
115 | \fn QDBusPendingReply::QDBusPendingReply(const QDBusPendingCall &call) |
116 | |
117 | Creates a QDBusPendingReply object that will take its contents from |
118 | the \a call pending asynchronous call. This QDBusPendingReply object |
119 | will share the same pending call reference as \a call. |
120 | */ |
121 | |
122 | /*! |
123 | \fn QDBusPendingReply::QDBusPendingReply(const QDBusMessage &message) |
124 | |
125 | Creates a QDBusPendingReply object that will take its contents from |
126 | the message \a message. In this case, this object will be already |
127 | in its finished state and the reply's contents will be accessible. |
128 | |
129 | \sa isFinished() |
130 | */ |
131 | |
132 | /*! |
133 | \fn QDBusPendingReply &QDBusPendingReply::operator=(const QDBusPendingReply &other) |
134 | |
135 | Makes a copy of \a other and drops the reference to the current |
136 | pending call. If the current reference is to an unfinished pending |
137 | call and this is the last reference, the pending call will be |
138 | canceled and there will be no way of retrieving the reply's |
139 | contents, when they arrive. |
140 | */ |
141 | |
142 | /*! |
143 | \fn QDBusPendingReply &QDBusPendingReply::operator=(const QDBusPendingCall &call) |
144 | |
145 | Makes this object take its contents from the \a call pending call |
146 | and drops the reference to the current pending call. If the |
147 | current reference is to an unfinished pending call and this is the |
148 | last reference, the pending call will be canceled and there will |
149 | be no way of retrieving the reply's contents, when they arrive. |
150 | */ |
151 | |
152 | /*! |
153 | \fn QDBusPendingReply &QDBusPendingReply::operator=(const QDBusMessage &message) |
154 | |
155 | Makes this object take its contents from the \a message message |
156 | and drops the reference to the current pending call. If the |
157 | current reference is to an unfinished pending call and this is the |
158 | last reference, the pending call will be canceled and there will |
159 | be no way of retrieving the reply's contents, when they arrive. |
160 | |
161 | After this function is finished, the QDBusPendingReply object will |
162 | be in its "finished" state and the \a message contents will be |
163 | accessible. |
164 | |
165 | \sa isFinished() |
166 | */ |
167 | |
168 | /*! |
169 | \fn int QDBusPendingReply::count() const |
170 | |
171 | Return the number of arguments the reply is supposed to have. This |
172 | number matches the number of non-void template parameters in this |
173 | class. |
174 | |
175 | If the reply arrives with a different number of arguments (or with |
176 | different types), it will be transformed into an error reply |
177 | indicating a bad signature. |
178 | */ |
179 | |
180 | /*! |
181 | \fn QVariant QDBusPendingReply::argumentAt(int index) const |
182 | |
183 | Returns the argument at position \a index in the reply's |
184 | contents. If the reply doesn't have that many elements, this |
185 | function's return value is undefined (will probably cause an |
186 | assertion failure), so it is important to verify that the |
187 | processing is finished and the reply is valid. |
188 | */ |
189 | |
190 | /*! |
191 | \fn Type QDBusPendingReply::argumentAt() const |
192 | |
193 | Returns the argument at position \c Index (which is a template |
194 | parameter) cast to type \c Type. This function uses template code |
195 | to determine the proper \c Type type, according to the type list |
196 | used in the construction of this object. |
197 | |
198 | Note that, if the reply hasn't arrived, this function causes the |
199 | calling thread to block until the reply is processed. |
200 | */ |
201 | |
202 | /*! |
203 | \fn T1 QDBusPendingReply::value() const |
204 | |
205 | Returns the first argument in this reply, cast to type \c T1 (the |
206 | first template parameter of this class). This is equivalent to |
207 | calling argumentAt<0>(). |
208 | |
209 | This function is provided as a convenience, matching the |
210 | QDBusReply::value() function. |
211 | |
212 | Note that, if the reply hasn't arrived, this function causes the |
213 | calling thread to block until the reply is processed. |
214 | */ |
215 | |
216 | /*! |
217 | \fn QDBusPendingReply::operator T1() const |
218 | |
219 | Returns the first argument in this reply, cast to type \c T1 (the |
220 | first template parameter of this class). This is equivalent to |
221 | calling argumentAt<0>(). |
222 | |
223 | This function is provided as a convenience, matching the |
224 | QDBusReply::value() function. |
225 | |
226 | Note that, if the reply hasn't arrived, this function causes the |
227 | calling thread to block until the reply is processed. |
228 | */ |
229 | |
230 | /*! |
231 | \fn void QDBusPendingReply::waitForFinished() |
232 | |
233 | Suspends the execution of the calling thread until the reply is |
234 | received and processed. After this function returns, isFinished() |
235 | should return true, indicating the reply's contents are ready to |
236 | be processed. |
237 | |
238 | \sa QDBusPendingCallWatcher::waitForFinished() |
239 | */ |
240 | |
241 | QDBusPendingReplyData::QDBusPendingReplyData() |
242 | : QDBusPendingCall(0) // initialize base class empty |
243 | { |
244 | } |
245 | |
246 | QDBusPendingReplyData::~QDBusPendingReplyData() |
247 | { |
248 | } |
249 | |
250 | void QDBusPendingReplyData::assign(const QDBusPendingCall &other) |
251 | { |
252 | QDBusPendingCall::operator=(other); |
253 | } |
254 | |
255 | void QDBusPendingReplyData::assign(const QDBusMessage &message) |
256 | { |
257 | d = new QDBusPendingCallPrivate(QDBusMessage(), 0); // drops the reference to the old one |
258 | d->replyMessage = message; |
259 | } |
260 | |
261 | QVariant QDBusPendingReplyData::argumentAt(int index) const |
262 | { |
263 | if (d) |
264 | d->waitForFinished(); // bypasses "const" |
265 | |
266 | Q_ASSERT_X(d && index >= 0 && index < d->replyMessage.arguments().count(), |
267 | "QDBusPendingReply::argumentAt" , |
268 | "Index out of bounds" ); |
269 | |
270 | return d->replyMessage.arguments().at(index); |
271 | } |
272 | |
273 | void QDBusPendingReplyData::setMetaTypes(int count, const int *types) |
274 | { |
275 | Q_ASSERT(d); |
276 | QMutexLocker locker(&d->mutex); |
277 | d->setMetaTypes(count, types); |
278 | d->checkReceivedSignature(); |
279 | } |
280 | |
281 | #endif // QT_NO_DBUS |
282 | |