Merge remote-tracking branch 'origin/api_changes'
[profile/ivi/qtbase.git] / src / dbus / qdbuserror.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtDBus module of the Qt Toolkit.
7 **
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.
16 **
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.
20 **
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.
28 **
29 ** Other Usage
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.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qdbuserror.h"
43
44 #include <qdebug.h>
45 #include <qvarlengtharray.h>
46
47 #ifndef QT_BOOTSTRAPPED
48 #include "qdbus_symbols_p.h"
49 #include "qdbusmessage.h"
50 #include "qdbusmessage_p.h"
51 #endif
52
53 #ifndef QT_NO_DBUS
54
55 QT_BEGIN_NAMESPACE
56
57 /*
58  * Use the following Perl script to generate the error string index list:
59 ===== PERL SCRIPT ====
60 print "static const char errorMessages_string[] =\n";
61 $counter = 0;
62 $i = 0;
63 while (<STDIN>) {
64     chomp;
65     print "    \"$_\\0\"\n";
66     $sizes[$i++] = $counter;
67     $counter += 1 + length $_;
68 }
69 print "    \"\\0\";\n\nstatic const int errorMessages_indices[] = {\n    ";
70 for ($j = 0; $j < $i; ++$j) {
71     printf "$sizes[$j], ";
72 }
73 print "0\n};\n";
74 ===== PERL SCRIPT ====
75  
76  * The input data is as follows:
77 other
78 org.freedesktop.DBus.Error.Failed
79 org.freedesktop.DBus.Error.NoMemory
80 org.freedesktop.DBus.Error.ServiceUnknown
81 org.freedesktop.DBus.Error.NoReply
82 org.freedesktop.DBus.Error.BadAddress
83 org.freedesktop.DBus.Error.NotSupported
84 org.freedesktop.DBus.Error.LimitsExceeded
85 org.freedesktop.DBus.Error.AccessDenied
86 org.freedesktop.DBus.Error.NoServer
87 org.freedesktop.DBus.Error.Timeout
88 org.freedesktop.DBus.Error.NoNetwork
89 org.freedesktop.DBus.Error.AddressInUse
90 org.freedesktop.DBus.Error.Disconnected
91 org.freedesktop.DBus.Error.InvalidArgs
92 org.freedesktop.DBus.Error.UnknownMethod
93 org.freedesktop.DBus.Error.TimedOut
94 org.freedesktop.DBus.Error.InvalidSignature
95 org.freedesktop.DBus.Error.UnknownInterface
96 org.freedesktop.DBus.Error.UnknownObject
97 org.freedesktop.DBus.Error.UnknownProperty
98 org.freedesktop.DBus.Error.PropertyReadOnly
99 org.qtproject.QtDBus.Error.InternalError
100 org.qtproject.QtDBus.Error.InvalidService
101 org.qtproject.QtDBus.Error.InvalidObjectPath
102 org.qtproject.QtDBus.Error.InvalidInterface
103 org.qtproject.QtDBus.Error.InvalidMember
104 */
105
106 // in the same order as KnownErrors!
107 static const char errorMessages_string[] =
108     "other\0"
109     "org.freedesktop.DBus.Error.Failed\0"
110     "org.freedesktop.DBus.Error.NoMemory\0"
111     "org.freedesktop.DBus.Error.ServiceUnknown\0"
112     "org.freedesktop.DBus.Error.NoReply\0"
113     "org.freedesktop.DBus.Error.BadAddress\0"
114     "org.freedesktop.DBus.Error.NotSupported\0"
115     "org.freedesktop.DBus.Error.LimitsExceeded\0"
116     "org.freedesktop.DBus.Error.AccessDenied\0"
117     "org.freedesktop.DBus.Error.NoServer\0"
118     "org.freedesktop.DBus.Error.Timeout\0"
119     "org.freedesktop.DBus.Error.NoNetwork\0"
120     "org.freedesktop.DBus.Error.AddressInUse\0"
121     "org.freedesktop.DBus.Error.Disconnected\0"
122     "org.freedesktop.DBus.Error.InvalidArgs\0"
123     "org.freedesktop.DBus.Error.UnknownMethod\0"
124     "org.freedesktop.DBus.Error.TimedOut\0"
125     "org.freedesktop.DBus.Error.InvalidSignature\0"
126     "org.freedesktop.DBus.Error.UnknownInterface\0"
127     "org.freedesktop.DBus.Error.UnknownObject\0"
128     "org.freedesktop.DBus.Error.UnknownProperty\0"
129     "org.freedesktop.DBus.Error.PropertyReadOnly\0"
130     "org.qtproject.QtDBus.Error.InternalError\0"
131     "org.qtproject.QtDBus.Error.InvalidService\0"
132     "org.qtproject.QtDBus.Error.InvalidObjectPath\0"
133     "org.qtproject.QtDBus.Error.InvalidInterface\0"
134     "org.qtproject.QtDBus.Error.InvalidMember\0"
135     "\0";
136
137 static const int errorMessages_indices[] = {
138     0,    6,   40,   76,  118,  153,  191,  231,
139     273,  313,  349,  384,  421,  461,  501,  540,
140     581,  617,  661,  705,  746,  789,  833,  874,
141     916,  961, 1005,   -1
142 };
143
144 static const int errorMessages_count = sizeof errorMessages_indices /
145                                        sizeof errorMessages_indices[0];
146
147 static inline const char *get(QDBusError::ErrorType code)
148 {
149     int intcode = qBound(0, int(code) - int(QDBusError::Other), errorMessages_count);
150     return errorMessages_string + errorMessages_indices[intcode];
151 }
152
153 static inline QDBusError::ErrorType get(const char *name)
154 {
155     if (!name || !*name)
156         return QDBusError::NoError;
157     for (int i = 0; i < errorMessages_count; ++i)
158         if (strcmp(name, errorMessages_string + errorMessages_indices[i]) == 0)
159             return QDBusError::ErrorType(i + int(QDBusError::Other));
160     return QDBusError::Other;
161 }
162
163 /*!
164     \class QDBusError
165     \inmodule QtDBus
166     \since 4.2
167
168     \brief The QDBusError class represents an error received from the
169     D-Bus bus or from remote applications found in the bus.
170
171     When dealing with the D-Bus bus service or with remote
172     applications over D-Bus, a number of error conditions can
173     happen. This error conditions are sometimes signalled by a
174     returned error value or by a QDBusError.
175
176     C++ and Java exceptions are a valid analogy for D-Bus errors:
177     instead of returning normally with a return value, remote
178     applications and the bus may decide to throw an error
179     condition. However, the QtDBus implementation does not use the C++
180     exception-throwing mechanism, so you will receive QDBusErrors in
181     the return reply (see QDBusReply::error()).
182
183     QDBusError objects are used to inspect the error name and message
184     as received from the bus and remote applications. You should not
185     create such objects yourself to signal error conditions when
186     called from D-Bus: instead, use QDBusMessage::createError() and
187     QDBusConnection::send().
188
189     \sa QDBusConnection::send(), QDBusMessage, QDBusReply
190 */
191
192 /*!
193     \enum QDBusError::ErrorType
194
195     In order to facilitate verification of the most common D-Bus errors generated by the D-Bus
196     implementation and by the bus daemon itself, QDBusError can be compared to a set of pre-defined
197     values:
198
199     \value NoError              QDBusError is invalid (i.e., the call succeeded)
200     \value Other                QDBusError contains an error that is one of the well-known ones
201     \value Failed               The call failed (\c org.freedesktop.DBus.Error.Failed)
202     \value NoMemory             Out of memory (\c org.freedesktop.DBus.Error.NoMemory)
203     \value ServiceUnknown       The called service is not known
204                                 (\c org.freedesktop.DBus.Error.ServiceUnknown)
205     \value NoReply              The called method did not reply within the specified timeout
206                                 (\c org.freedesktop.DBus.Error.NoReply)
207     \value BadAddress           The address given is not valid
208                                 (\c org.freedesktop.DBus.Error.BadAddress)
209     \value NotSupported         The call/operation is not supported
210                                 (\c org.freedesktop.DBus.Error.NotSupported)
211     \value LimitsExceeded       The limits allocated to this process/call/connection exceeded the
212                                 pre-defined values (\c org.freedesktop.DBus.Error.LimitsExceeded)
213     \value AccessDenied         The call/operation tried to access a resource it isn't allowed to
214                                 (\c org.freedesktop.DBus.Error.AccessDenied)
215     \value NoServer             \e {Documentation doesn't say what this is for}
216                                 (\c org.freedesktop.DBus.Error.NoServer)
217     \value Timeout              \e {Documentation doesn't say what this is for or how it's used}
218                                 (\c org.freedesktop.DBus.Error.Timeout)
219     \value NoNetwork            \e {Documentation doesn't say what this is for}
220                                 (\c org.freedesktop.DBus.Error.NoNetwork)
221     \value AddressInUse         QDBusServer tried to bind to an address that is already in use
222                                 (\c org.freedesktop.DBus.Error.AddressInUse)
223     \value Disconnected         The call/process/message was sent after QDBusConnection disconnected
224                                 (\c org.freedesktop.DBus.Error.Disconnected)
225     \value InvalidArgs          The arguments passed to this call/operation are not valid
226                                 (\c org.freedesktop.DBus.Error.InvalidArgs)
227     \value UnknownMethod        The method called was not found in this object/interface with the
228                                 given parameters (\c org.freedesktop.DBus.Error.UnknownMethod)
229     \value TimedOut             \e {Documentation doesn't say...}
230                                 (\c org.freedesktop.DBus.Error.TimedOut)
231     \value InvalidSignature     The type signature is not valid or compatible
232                                 (\c org.freedesktop.DBus.Error.InvalidSignature)
233     \value UnknownInterface     The interface is not known in this object
234                                 (\c org.freedesktop.DBus.Error.UnknownInterface)
235     \value UnknownObject        The object path points to an object that does not exist
236                                 (\c org.freedesktop.DBus.Error.UnknownObject)
237     \value UnknownProperty      The property does not exist in this interface
238                                 (\c org.freedesktop.DBus.Error.UnknownProperty)
239     \value PropertyReadOnly     The property set failed because the property is read-only
240                                 (\c org.freedesktop.DBus.Error.PropertyReadOnly)
241
242     \value InternalError        An internal error occurred
243
244     \value InvalidObjectPath    The object path provided is invalid.
245
246     \value InvalidService       The service requested is invalid.
247
248     \value InvalidMember        The member is invalid.
249
250     \value InvalidInterface     The interface is invalid.
251 */
252
253 #ifndef QT_BOOTSTRAPPED
254 /*!
255     \internal
256     Constructs a QDBusError from a DBusError structure.
257 */
258 QDBusError::QDBusError(const DBusError *error)
259     : code(NoError)
260 {
261     if (!error || !q_dbus_error_is_set(error))
262         return;
263
264     code = ::get(error->name);
265     msg = QString::fromUtf8(error->message);
266     nm = QString::fromUtf8(error->name);
267 }
268
269 /*!
270     \internal
271     Constructs a QDBusError from a QDBusMessage.
272 */
273 QDBusError::QDBusError(const QDBusMessage &qdmsg)
274     : code(NoError)
275 {
276     if (qdmsg.type() != QDBusMessage::ErrorMessage)
277         return;
278
279     code = ::get(qdmsg.errorName().toUtf8().constData());
280     nm = qdmsg.errorName();
281     msg = qdmsg.errorMessage();
282 }
283 #endif
284
285 /*!
286     \internal
287     Constructs a QDBusError from a well-known error code
288 */
289 QDBusError::QDBusError(ErrorType error, const QString &mess)
290     : code(error)
291 {
292     nm = QLatin1String(::get(error));
293     msg = mess;
294 }
295
296 /*!
297     \internal
298     Constructs a QDBusError from another QDBusError object
299 */
300 QDBusError::QDBusError(const QDBusError &other)
301         : code(other.code), msg(other.msg), nm(other.nm)
302 {
303 }
304
305 /*!
306   \internal
307   Assignment operator
308 */
309
310 QDBusError &QDBusError::operator=(const QDBusError &other)
311 {
312     code = other.code;
313     msg = other.msg;
314     nm = other.nm;
315     return *this;
316 }
317
318 #ifndef QT_BOOTSTRAPPED
319 /*!
320   \internal
321   Assignment operator from a QDBusMessage
322 */
323 QDBusError &QDBusError::operator=(const QDBusMessage &qdmsg)
324 {
325     if (qdmsg.type() == QDBusMessage::ErrorMessage) {
326         code = ::get(qdmsg.errorName().toUtf8().constData());
327         nm = qdmsg.errorName();
328         msg = qdmsg.errorMessage();
329     } else {
330         code =NoError;
331         nm.clear();
332         msg.clear();
333     }
334     return *this;
335 }
336 #endif
337
338 /*!
339     Returns this error's ErrorType.
340
341     \sa ErrorType
342 */
343
344 QDBusError::ErrorType QDBusError::type() const
345 {
346     return code;
347 }
348
349 /*!
350     Returns this error's name. Error names are similar to D-Bus Interface names, like
351     \c org.freedesktop.DBus.InvalidArgs.
352
353     \sa type()
354 */
355
356 QString QDBusError::name() const
357 {
358     return nm;
359 }
360
361 /*!
362     Returns the message that the callee associated with this error. Error messages are
363     implementation defined and usually contain a human-readable error code, though this does not
364     mean it is suitable for your end-users.
365 */
366
367 QString QDBusError::message() const
368 {
369     return msg;
370 }
371
372 /*!
373     Returns true if this is a valid error condition (i.e., if there was an error),
374     otherwise false.
375 */
376
377 bool QDBusError::isValid() const
378 {
379     return (code != NoError);
380 }
381
382 /*!
383     \since 4.3
384     Returns the error name associated with error condition \a error.
385 */
386 QString QDBusError::errorString(ErrorType error)
387 {
388     return QLatin1String(::get(error));
389 }
390
391 #ifndef QT_NO_DEBUG_STREAM
392 QDebug operator<<(QDebug dbg, const QDBusError &msg)
393 {
394     dbg.nospace() << "QDBusError(" << msg.name() << ", " << msg.message() << ')';
395     return dbg.space();
396 }
397 #endif
398
399 QT_END_NAMESPACE
400
401 #endif // QT_NO_DBUS