713ef75a9308087f34e311b4e76cbe62d377f796
[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 com.trolltech.QtDBus.Error.InternalError
97 org.freedesktop.DBus.Error.UnknownObject
98 com.trolltech.QtDBus.Error.InvalidService
99 com.trolltech.QtDBus.Error.InvalidObjectPath
100 com.trolltech.QtDBus.Error.InvalidInterface
101 com.trolltech.QtDBus.Error.InvalidMember
102 */
103
104 // in the same order as KnownErrors!
105 static const char errorMessages_string[] =
106     "other\0"
107     "org.freedesktop.DBus.Error.Failed\0"
108     "org.freedesktop.DBus.Error.NoMemory\0"
109     "org.freedesktop.DBus.Error.ServiceUnknown\0"
110     "org.freedesktop.DBus.Error.NoReply\0"
111     "org.freedesktop.DBus.Error.BadAddress\0"
112     "org.freedesktop.DBus.Error.NotSupported\0"
113     "org.freedesktop.DBus.Error.LimitsExceeded\0"
114     "org.freedesktop.DBus.Error.AccessDenied\0"
115     "org.freedesktop.DBus.Error.NoServer\0"
116     "org.freedesktop.DBus.Error.Timeout\0"
117     "org.freedesktop.DBus.Error.NoNetwork\0"
118     "org.freedesktop.DBus.Error.AddressInUse\0"
119     "org.freedesktop.DBus.Error.Disconnected\0"
120     "org.freedesktop.DBus.Error.InvalidArgs\0"
121     "org.freedesktop.DBus.Error.UnknownMethod\0"
122     "org.freedesktop.DBus.Error.TimedOut\0"
123     "org.freedesktop.DBus.Error.InvalidSignature\0"
124     "org.freedesktop.DBus.Error.UnknownInterface\0"
125     "com.trolltech.QtDBus.Error.InternalError\0"
126     "org.freedesktop.DBus.Error.UnknownObject\0"
127     "com.trolltech.QtDBus.Error.InvalidService\0"
128     "com.trolltech.QtDBus.Error.InvalidObjectPath\0"
129     "com.trolltech.QtDBus.Error.InvalidInterface\0"
130     "com.trolltech.QtDBus.Error.InvalidMember\0"
131     "\0";
132
133 static const int errorMessages_indices[] = {
134        0,    6,   40,   76,  118,  153,  191,  231,
135      273,  313,  349,  384,  421,  461,  501,  540,
136      581,  617,  661,  705,  746,  787,  829,  874,
137      918,    0
138 };
139
140 static const int errorMessages_count = sizeof errorMessages_indices /
141                                        sizeof errorMessages_indices[0];
142
143 static inline const char *get(QDBusError::ErrorType code)
144 {
145     int intcode = qBound(0, int(code) - int(QDBusError::Other), errorMessages_count);
146     return errorMessages_string + errorMessages_indices[intcode];
147 }
148
149 static inline QDBusError::ErrorType get(const char *name)
150 {
151     if (!name || !*name)
152         return QDBusError::NoError;
153     for (int i = 0; i < errorMessages_count; ++i)
154         if (strcmp(name, errorMessages_string + errorMessages_indices[i]) == 0)
155             return QDBusError::ErrorType(i + int(QDBusError::Other));
156     return QDBusError::Other;
157 }
158
159 /*!
160     \class QDBusError
161     \inmodule QtDBus
162     \since 4.2
163
164     \brief The QDBusError class represents an error received from the
165     D-Bus bus or from remote applications found in the bus.
166
167     When dealing with the D-Bus bus service or with remote
168     applications over D-Bus, a number of error conditions can
169     happen. This error conditions are sometimes signalled by a
170     returned error value or by a QDBusError.
171
172     C++ and Java exceptions are a valid analogy for D-Bus errors:
173     instead of returning normally with a return value, remote
174     applications and the bus may decide to throw an error
175     condition. However, the QtDBus implementation does not use the C++
176     exception-throwing mechanism, so you will receive QDBusErrors in
177     the return reply (see QDBusReply::error()).
178
179     QDBusError objects are used to inspect the error name and message
180     as received from the bus and remote applications. You should not
181     create such objects yourself to signal error conditions when
182     called from D-Bus: instead, use QDBusMessage::createError() and
183     QDBusConnection::send().
184
185     \sa QDBusConnection::send(), QDBusMessage, QDBusReply
186 */
187
188 /*!
189     \enum QDBusError::ErrorType
190
191     In order to facilitate verification of the most common D-Bus errors generated by the D-Bus
192     implementation and by the bus daemon itself, QDBusError can be compared to a set of pre-defined
193     values:
194
195     \value NoError              QDBusError is invalid (i.e., the call succeeded)
196     \value Other                QDBusError contains an error that is one of the well-known ones
197     \value Failed               The call failed (\c org.freedesktop.DBus.Error.Failed)
198     \value NoMemory             Out of memory (\c org.freedesktop.DBus.Error.NoMemory)
199     \value ServiceUnknown       The called service is not known
200                                 (\c org.freedesktop.DBus.Error.ServiceUnknown)
201     \value NoReply              The called method did not reply within the specified timeout
202                                 (\c org.freedesktop.DBus.Error.NoReply)
203     \value BadAddress           The address given is not valid
204                                 (\c org.freedesktop.DBus.Error.BadAddress)
205     \value NotSupported         The call/operation is not supported
206                                 (\c org.freedesktop.DBus.Error.NotSupported)
207     \value LimitsExceeded       The limits allocated to this process/call/connection exceeded the
208                                 pre-defined values (\c org.freedesktop.DBus.Error.LimitsExceeded)
209     \value AccessDenied         The call/operation tried to access a resource it isn't allowed to
210                                 (\c org.freedesktop.DBus.Error.AccessDenied)
211     \value NoServer             \e {Documentation doesn't say what this is for}
212                                 (\c org.freedesktop.DBus.Error.NoServer)
213     \value Timeout              \e {Documentation doesn't say what this is for or how it's used}
214                                 (\c org.freedesktop.DBus.Error.Timeout)
215     \value NoNetwork            \e {Documentation doesn't say what this is for}
216                                 (\c org.freedesktop.DBus.Error.NoNetwork)
217     \value AddressInUse         QDBusServer tried to bind to an address that is already in use
218                                 (\c org.freedesktop.DBus.Error.AddressInUse)
219     \value Disconnected         The call/process/message was sent after QDBusConnection disconnected
220                                 (\c org.freedesktop.DBus.Error.Disconnected)
221     \value InvalidArgs          The arguments passed to this call/operation are not valid
222                                 (\c org.freedesktop.DBus.Error.InvalidArgs)
223     \value UnknownMethod        The method called was not found in this object/interface with the
224                                 given parameters (\c org.freedesktop.DBus.Error.UnknownMethod)
225     \value TimedOut             \e {Documentation doesn't say...}
226                                 (\c org.freedesktop.DBus.Error.TimedOut)
227     \value InvalidSignature     The type signature is not valid or compatible
228                                 (\c org.freedesktop.DBus.Error.InvalidSignature)
229     \value UnknownInterface     The interface is not known
230     \value InternalError        An internal error occurred
231                                 (\c com.trolltech.QtDBus.Error.InternalError)
232
233     \value InvalidObjectPath    The object path provided is invalid.
234
235     \value InvalidService       The service requested is invalid.
236
237     \value InvalidMember        The member is invalid.
238
239     \value InvalidInterface     The interface is invalid.
240
241     \value UnknownObject        The remote object could not be found.
242 */
243
244 #ifndef QT_BOOTSTRAPPED
245 /*!
246     \internal
247     Constructs a QDBusError from a DBusError structure.
248 */
249 QDBusError::QDBusError(const DBusError *error)
250     : code(NoError)
251 {
252     if (!error || !q_dbus_error_is_set(error))
253         return;
254
255     code = ::get(error->name);
256     msg = QString::fromUtf8(error->message);
257     nm = QString::fromUtf8(error->name);
258 }
259
260 /*!
261     \internal
262     Constructs a QDBusError from a QDBusMessage.
263 */
264 QDBusError::QDBusError(const QDBusMessage &qdmsg)
265     : code(NoError)
266 {
267     if (qdmsg.type() != QDBusMessage::ErrorMessage)
268         return;
269
270     code = ::get(qdmsg.errorName().toUtf8().constData());
271     nm = qdmsg.errorName();
272     msg = qdmsg.errorMessage();
273 }
274 #endif
275
276 /*!
277     \internal
278     Constructs a QDBusError from a well-known error code
279 */
280 QDBusError::QDBusError(ErrorType error, const QString &mess)
281     : code(error)
282 {
283     nm = QLatin1String(::get(error));
284     msg = mess;
285 }
286
287 /*!
288     \internal
289     Constructs a QDBusError from another QDBusError object
290 */
291 QDBusError::QDBusError(const QDBusError &other)
292         : code(other.code), msg(other.msg), nm(other.nm)
293 {
294 }
295
296 /*!
297   \internal
298   Assignment operator
299 */
300
301 QDBusError &QDBusError::operator=(const QDBusError &other)
302 {
303     code = other.code;
304     msg = other.msg;
305     nm = other.nm;
306     return *this;
307 }
308
309 #ifndef QT_BOOTSTRAPPED
310 /*!
311   \internal
312   Assignment operator from a QDBusMessage
313 */
314 QDBusError &QDBusError::operator=(const QDBusMessage &qdmsg)
315 {
316     if (qdmsg.type() == QDBusMessage::ErrorMessage) {
317         code = ::get(qdmsg.errorName().toUtf8().constData());
318         nm = qdmsg.errorName();
319         msg = qdmsg.errorMessage();
320     } else {
321         code =NoError;
322         nm.clear();
323         msg.clear();
324     }
325     return *this;
326 }
327 #endif
328
329 /*!
330     Returns this error's ErrorType.
331
332     \sa ErrorType
333 */
334
335 QDBusError::ErrorType QDBusError::type() const
336 {
337     return code;
338 }
339
340 /*!
341     Returns this error's name. Error names are similar to D-Bus Interface names, like
342     \c org.freedesktop.DBus.InvalidArgs.
343
344     \sa type()
345 */
346
347 QString QDBusError::name() const
348 {
349     return nm;
350 }
351
352 /*!
353     Returns the message that the callee associated with this error. Error messages are
354     implementation defined and usually contain a human-readable error code, though this does not
355     mean it is suitable for your end-users.
356 */
357
358 QString QDBusError::message() const
359 {
360     return msg;
361 }
362
363 /*!
364     Returns true if this is a valid error condition (i.e., if there was an error),
365     otherwise false.
366 */
367
368 bool QDBusError::isValid() const
369 {
370     return (code != NoError);
371 }
372
373 /*!
374     \since 4.3
375     Returns the error name associated with error condition \a error.
376 */
377 QString QDBusError::errorString(ErrorType error)
378 {
379     return QLatin1String(::get(error));
380 }
381
382 #ifndef QT_NO_DEBUG_STREAM
383 QDebug operator<<(QDebug dbg, const QDBusError &msg)
384 {
385     dbg.nospace() << "QDBusError(" << msg.name() << ", " << msg.message() << ')';
386     return dbg.space();
387 }
388 #endif
389
390 QT_END_NAMESPACE
391
392 #endif // QT_NO_DBUS