d5cd6758cd485fc892e20bddb85806c9c5f56d4f
[platform/upstream/dbus.git] / qt / qdbuserror.cpp
1 /* qdbuserror.h QDBusError object
2  *
3  * Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org>
4  * Copyright (C) 2006 Trolltech AS. All rights reserved.
5  *    Author: Thiago Macieira <thiago.macieira@trolltech.com>
6  *
7  * Licensed under the Academic Free License version 2.1
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation
21  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22  *
23  */
24
25 #include "qdbuserror.h"
26
27 #include <qdebug.h>
28 #include <qvarlengtharray.h>
29
30 #include <dbus/dbus.h>
31 #include "qdbusmessage.h"
32
33 struct ErrorMessageMapping
34 {
35     ErrorMessageMapping();
36     QVarLengthArray<const char*, QDBusError::qKnownErrorsMax> messages;
37
38     inline const char *get(QDBusError::KnownErrors code) const
39     {
40         if (code <= QDBusError::Other || code > QDBusError::qKnownErrorsMax)
41             return messages[int(QDBusError::Other) - 1];
42         return messages[int(code) - 1];
43     }
44
45     inline QDBusError::KnownErrors get(const char *name) const
46     {
47         if (!name || !*name)
48             return QDBusError::NoError;
49         for (int i = QDBusError::Other; i <= QDBusError::qKnownErrorsMax; ++i)
50             if (strcmp(name, messages[i - 1]) == 0)
51                 return QDBusError::KnownErrors(i);
52         return QDBusError::Other;
53     }
54 };
55
56 static const char errorMessages_string[] =
57     // in the same order as KnownErrors!
58     "other\0"                           // Other -- shouldn't happen
59     DBUS_ERROR_FAILED "\0"              // Failed
60     DBUS_ERROR_NO_MEMORY "\0"           // NoMemory
61     DBUS_ERROR_SERVICE_UNKNOWN "\0"     // ServiceUnknown
62     DBUS_ERROR_NO_REPLY "\0"            // NoReply
63     DBUS_ERROR_BAD_ADDRESS "\0"         // BadAddress
64     DBUS_ERROR_NOT_SUPPORTED "\0"       // NotSupported
65     DBUS_ERROR_LIMITS_EXCEEDED "\0"     // LimitsExceeded
66     DBUS_ERROR_ACCESS_DENIED  "\0"      // AccessDenied
67     DBUS_ERROR_NO_SERVER "\0"           // NoServer
68     DBUS_ERROR_TIMEOUT "\0"             // Timeout
69     DBUS_ERROR_NO_NETWORK "\0"          // NoNetwork
70     DBUS_ERROR_ADDRESS_IN_USE "\0"      // AddressInUse
71     DBUS_ERROR_DISCONNECTED "\0"        // Disconnected
72     DBUS_ERROR_INVALID_ARGS "\0"        // InvalidArgs
73     DBUS_ERROR_UNKNOWN_METHOD "\0"      // UnknownMethod
74     DBUS_ERROR_TIMED_OUT "\0"           // TimedOut
75     DBUS_ERROR_INVALID_SIGNATURE "\0"   // InvalidSignature
76     "com.trolltech.QtDBus.Error.UnknownInterface\0" // UnknownInterface
77     "com.trolltech.QtDBus.Error.InternalError\0" // InternalError
78     "\0";
79
80 ErrorMessageMapping::ErrorMessageMapping()
81     : messages(int(QDBusError::qKnownErrorsMax))
82 {
83     // create the list:
84     const char *p = errorMessages_string;
85     int i = 0;
86     while (*p) {
87         messages[i] = p;
88         p += strlen(p) + 1;
89         ++i;
90     }
91 }
92
93 Q_GLOBAL_STATIC(ErrorMessageMapping, errorMessages)    
94
95 /*!
96     \class QDBusError
97     \brief Represents an error received from the D-Bus bus or from remote applications found in the bus.
98
99     When dealing with the D-Bus bus service or with remote applications over D-Bus, a number of
100     error conditions can happen. This error conditions are sometimes signalled by a returned error
101     value or by a QDBusError.
102
103     C++ and Java exceptions are a valid analogy for D-Bus errors: instead of returning normally with
104     a return value, remote applications and the bus may decide to throw an error condition. However,
105     the QtDBus implementation does not use the C++ exception-throwing mechanism, so you will receive
106     QDBusErrors in the return reply (see QDBusReply::error()).
107
108     QDBusError objects are used to inspect the error name and message as received from the bus and
109     remote applications. You should not create such objects yourself to signal error conditions when
110     called from D-Bus: instead, use QDBusMessage::error and QDBusConnection::send.
111
112     \sa QDBusConnection::send(), QDBusMessage, QDBusReply
113 */
114
115 /*!
116     \enum QDBusError::KnownErrors
117
118     In order to facilitate verification of the most common D-Bus errors generated by the D-Bus
119     implementation and by the bus daemon itself, QDBusError can be compared to a set of pre-defined
120     values:
121
122     \value NoError              QDBusError is invalid (i.e., the call succeeded)
123     \value Other                QDBusError contains an error that is one of the well-known ones
124     \value Failed               The call failed (\c org.freedesktop.DBus.Error.Failed)
125     \value NoMemory             Out of memory (\c org.freedesktop.DBus.Error.NoMemory)
126     \value ServiceUnknown       The called service is not known
127                                 (\c org.freedesktop.DBus.Error.ServiceUnknown)
128     \value NoReply              The called method did not reply within the specified timeout
129                                 (\c org.freedesktop.DBus.Error.NoReply)
130     \value BadAddress           The address given is not valid
131                                 (\c org.freedesktop.DBus.Error.BadAddress)
132     \value NotSupported         The call/operation is not supported
133                                 (\c org.freedesktop.DBus.Error.NotSupported)
134     \value LimitsExceeded       The limits allocated to this process/call/connection exceeded the
135                                 pre-defined values (\c org.freedesktop.DBus.Error.LimitsExceeded)
136     \value AccessDenied         The call/operation tried to access a resource it isn't allowed to
137                                 (\c org.freedesktop.DBus.Error.AccessDenied)
138     \value NoServer             \i{Documentation doesn't say what this is for}
139                                 (\c org.freedesktop.DBus.Error.NoServer)
140     \value Timeout              \i{Documentation doesn't say what this is for or how it's used}
141                                 (\c org.freedesktop.DBus.Error.Timeout)
142     \value NoNetwork            \i{Documentation doesn't say what this is for}
143                                 (\c org.freedesktop.DBus.Error.NoNetwork)
144     \value AddressInUse         QDBusServer tried to bind to an address that is already in use
145                                 (\c org.freedesktop.DBus.Error.AddressInUse)
146     \value Disconnected         The call/process/message was sent after QDBusConnection disconnected
147                                 (\c org.freedesktop.DBus.Error.Disconnected)
148     \value InvalidArgs          The arguments passed to this call/operation are not valid
149                                 (\c org.freedesktop.DBus.Error.InvalidArgs)
150     \value UnknownMethod        The method called was not found in this object/interface with the
151                                 given parameters (\c org.freedesktop.DBus.Error.UnknownMethod)
152     \value TimedOut             \i{Documentation doesn't say...}
153                                 (\c org.freedesktop.DBus.Error.TimedOut)
154     \value InvalidSignature     The type signature is not valid or compatible
155                                 (\c org.freedesktop.DBus.Error.InvalidSignature)
156     \value UnknownInterface     The interface is not known
157     \value InternalError        An internal error occurred
158                                 (\c com.trolltech.QtDBus.Error.InternalError)
159
160 */
161
162 /*!
163     \internal
164     Constructs a QDBusError from a DBusError structure.
165 */
166 QDBusError::QDBusError(const DBusError *error)
167     : code(NoError)
168 {
169     if (!error || !dbus_error_is_set(error))
170         return;
171
172     code = errorMessages()->get(error->name);
173     nm = QString::fromUtf8(error->name);
174     msg = QString::fromUtf8(error->message);
175 }
176
177 /*!
178     \internal
179     Constructs a QDBusError from a QDBusMessage.
180 */
181 QDBusError::QDBusError(const QDBusMessage &qdmsg)
182     : code(Other)
183 {
184     if (qdmsg.type() != QDBusMessage::ErrorMessage)
185         return;
186
187     nm = qdmsg.name();
188     if (qdmsg.count())
189         msg = qdmsg[0].toString();
190     code = errorMessages()->get(nm.toUtf8().constData());
191 }
192
193 /*!
194     \internal
195     Constructs a QDBusError from a well-known error code
196 */
197 QDBusError::QDBusError(KnownErrors error, const QString &message)
198     : code(error)
199 {
200     nm = errorMessages()->get(error);
201     msg = message;
202 }
203
204 /*!
205     \fn QDBusError::name() const
206     Returns this error's name. Error names are similar to D-Bus Interface names, like
207     "org.freedesktop.DBus.InvalidArgs".
208 */
209
210 /*!
211     \fn QDBusError::message() const
212     Returns the message that the callee associated with this error. Error messages are
213     implementation defined and usually contain a human-readable error code, though this does not
214     mean it is suitable for your end-users.
215 */
216
217 /*!
218     \fn QDBusError::isValid() const
219     Returns true if this is a valid error condition (i.e., if there was an error), false otherwise.
220 */
221
222 /*!
223     \fn QDBusError::operator==(KnownErrors error) const
224     Compares this QDBusError against the well-known error code \a error and returns true if they
225     match.
226 */
227
228 /*!
229     \fn operator==(QDBusError::KnownErrors p1, const QDBusError &p2)
230     \relates QDBusError
231
232     Compares the QDBusError \a p2 against the well-known error code \a p1 and returns true if they
233     match.
234 */
235
236 #ifndef QT_NO_DEBUG
237 QDebug operator<<(QDebug dbg, const QDBusError &msg)
238 {
239     dbg.nospace() << "QDBusError(" << msg.name() << ", " << msg.message() << ")";
240     return dbg.space();
241 }
242 #endif
243
244