2006-02-13 John (J5) Palmieri <johnp@redhat.com>
[platform/upstream/dbus.git] / qt / qdbusmessage.cpp
1 /* qdbusmessage.cpp
2  *
3  * Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org>
4  *
5  * Licensed under the Academic Free License version 2.1
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  */
22
23 #include "qdbusmessage.h"
24
25 #include <QtCore/qdebug.h>
26 #include <QtCore/qstringlist.h>
27
28 #include <dbus/dbus.h>
29
30 #include "qdbusmarshall.h"
31 #include "qdbusmessage_p.h"
32
33 QDBusMessagePrivate::QDBusMessagePrivate(QDBusMessage *qq)
34     : msg(0), reply(0), q(qq), type(DBUS_MESSAGE_TYPE_INVALID), timeout(-1), ref(1)
35 {
36 }
37
38 QDBusMessagePrivate::~QDBusMessagePrivate()
39 {
40     if (msg)
41         dbus_message_unref(msg);
42     if (reply)
43         dbus_message_unref(reply);
44 }
45
46 ///////////////
47
48
49 QDBusMessage QDBusMessage::signal(const QString &path, const QString &interface,
50                                   const QString &name)
51 {
52     QDBusMessage message;
53     message.d->type = DBUS_MESSAGE_TYPE_SIGNAL;
54     message.d->path = path;
55     message.d->interface = interface;
56     message.d->name = name;
57
58     return message;
59 }
60
61 QDBusMessage QDBusMessage::methodCall(const QString &service, const QString &path,
62                                       const QString &interface, const QString &method)
63 {
64     QDBusMessage message;
65     message.d->type = DBUS_MESSAGE_TYPE_METHOD_CALL;
66     message.d->service = service;
67     message.d->path = path;
68     message.d->interface = interface;
69     message.d->method = method;
70
71     return message;
72 }
73
74 QDBusMessage QDBusMessage::methodReply(const QDBusMessage &other)
75 {
76     Q_ASSERT(other.d->msg);
77
78     QDBusMessage message;
79     message.d->type = DBUS_MESSAGE_TYPE_METHOD_RETURN;
80     message.d->reply = dbus_message_ref(other.d->msg);
81
82     return message;
83 }
84
85 QDBusMessage::QDBusMessage()
86 {
87     d = new QDBusMessagePrivate(this);
88 }
89
90 QDBusMessage::QDBusMessage(const QDBusMessage &other)
91     : QList<QVariant>(other)
92 {
93     d = other.d;
94     d->ref.ref();
95 }
96
97 QDBusMessage::~QDBusMessage()
98 {
99     if (!d->ref.deref())
100         delete d;
101 }
102
103 QDBusMessage &QDBusMessage::operator=(const QDBusMessage &other)
104 {
105     QList<QVariant>::operator=(other);
106     qAtomicAssign(d, other.d);
107     return *this;
108 }
109
110 DBusMessage *QDBusMessage::toDBusMessage() const
111 {
112     DBusMessage *msg = 0;
113     switch (d->type) {
114     case DBUS_MESSAGE_TYPE_METHOD_CALL:
115         msg = dbus_message_new_method_call(d->service.toUtf8().constData(),
116                 d->path.toUtf8().constData(), d->interface.toUtf8().constData(),
117                 d->method.toUtf8().constData());
118         break;
119     case DBUS_MESSAGE_TYPE_SIGNAL:
120         msg = dbus_message_new_signal(d->path.toUtf8().constData(),
121                 d->interface.toUtf8().constData(), d->name.toUtf8().constData());
122         break;
123     case DBUS_MESSAGE_TYPE_METHOD_RETURN:
124         msg = dbus_message_new_method_return(d->reply);
125         break;
126     }
127     if (!msg)
128         return 0;
129
130     QDBusMarshall::listToMessage(*this, msg);
131     return msg;
132 }
133
134 QDBusMessage QDBusMessage::fromDBusMessage(DBusMessage *dmsg)
135 {
136     QDBusMessage message;
137     if (!dmsg)
138         return message;
139
140     message.d->type = dbus_message_get_type(dmsg);
141     message.d->path = QString::fromUtf8(dbus_message_get_path(dmsg));
142     message.d->interface = QString::fromUtf8(dbus_message_get_interface(dmsg));
143     message.d->name = QString::fromUtf8(dbus_message_get_member(dmsg));
144     message.d->sender = QString::fromUtf8(dbus_message_get_sender(dmsg));
145     message.d->msg = dbus_message_ref(dmsg);
146
147     QDBusMarshall::messageToList(message, dmsg);
148
149     return message;
150 }
151
152 QString QDBusMessage::path() const
153 {
154     return d->path;
155 }
156
157 QString QDBusMessage::interface() const
158 {
159     return d->interface;
160 }
161
162 QString QDBusMessage::name() const
163 {
164     return d->name;
165 }
166
167 QString QDBusMessage::sender() const
168 {
169     return d->sender;
170 }
171
172 int QDBusMessage::timeout() const
173 {
174     return d->timeout;
175 }
176
177 void QDBusMessage::setTimeout(int ms)
178 {
179     d->timeout = ms;
180 }
181
182 /*!
183     Returns the unique serial number assigned to this message
184     or 0 if the message was not sent yet.
185  */
186 int QDBusMessage::serialNumber() const
187 {
188     if (!d->msg)
189         return 0;
190     return dbus_message_get_serial(d->msg);
191 }
192
193 /*!
194     Returns the unique serial number assigned to the message
195     that triggered this reply message.
196
197     If this message is not a reply to another message, 0
198     is returned.
199
200  */
201 int QDBusMessage::replySerialNumber() const
202 {
203     if (!d->msg)
204         return 0;
205     return dbus_message_get_reply_serial(d->msg);
206 }
207
208 QDBusMessage::MessageType QDBusMessage::type() const
209 {
210     switch (d->type) {
211     case DBUS_MESSAGE_TYPE_METHOD_CALL:
212         return MethodCallMessage;
213     case DBUS_MESSAGE_TYPE_METHOD_RETURN:
214         return ReplyMessage;
215     case DBUS_MESSAGE_TYPE_ERROR:
216         return ErrorMessage;
217     case DBUS_MESSAGE_TYPE_SIGNAL:
218         return SignalMessage;
219     default:
220         return InvalidMessage;
221     }
222 }
223
224 #ifndef QT_NO_DEBUG
225 QDebug operator<<(QDebug dbg, const QDBusMessage &msg)
226 {
227     dbg.nospace() << "QDBusMessage(" << msg.path() << ", " << msg.interface() << ", "
228                   << msg.name() << ", " << msg.sender() << ", "
229                   << static_cast<QList<QVariant> >(msg) << ")";
230     return dbg.space();
231 }
232 #endif
233