blob: d67f4863b5d5d31f83646af6776e9cf6021468ee [file] [log] [blame]
Emeric Vigier2f625822012-08-06 11:09:52 -04001/*
2 *
3 * D-Bus++ - C++ bindings for D-Bus
4 *
5 * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com>
6 *
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#ifdef HAVE_CONFIG_H
25#include <config.h>
26#endif
27
28#include <dbus-c++/pendingcall.h>
29
30#include <dbus/dbus.h>
31
32#include "internalerror.h"
33#include "pendingcall_p.h"
34#include "message_p.h"
35
36using namespace DBus;
37
38PendingCall::Private::Private(DBusPendingCall *dpc)
39 : call(dpc), dataslot(-1)
40{
41 if (!dbus_pending_call_allocate_data_slot(&dataslot))
42 {
43 throw ErrorNoMemory("Unable to allocate data slot");
44 }
45}
46
47PendingCall::Private::~Private()
48{
49 if (dataslot != -1)
50 {
51 dbus_pending_call_allocate_data_slot(&dataslot);
52 }
53}
54
55void PendingCall::Private::notify_stub(DBusPendingCall *dpc, void *data)
56{
57 PendingCall::Private *pvt = static_cast<PendingCall::Private *>(data);
58
59 PendingCall pc(pvt);
60 pvt->slot(pc);
61}
62
63PendingCall::PendingCall(PendingCall::Private *p)
64 : _pvt(p)
65{
66 if (!dbus_pending_call_set_notify(_pvt->call, Private::notify_stub, p, NULL))
67 {
68 throw ErrorNoMemory("Unable to initialize pending call");
69 }
70}
71
72PendingCall::PendingCall(const PendingCall &c)
73 : _pvt(c._pvt)
74{
75 dbus_pending_call_ref(_pvt->call);
76}
77
78PendingCall::~PendingCall()
79{
80 dbus_pending_call_unref(_pvt->call);
81}
82
83PendingCall &PendingCall::operator = (const PendingCall &c)
84{
85 if (&c != this)
86 {
87 dbus_pending_call_unref(_pvt->call);
88 _pvt = c._pvt;
89 dbus_pending_call_ref(_pvt->call);
90 }
91 return *this;
92}
93
94bool PendingCall::completed()
95{
96 return dbus_pending_call_get_completed(_pvt->call);
97}
98
99void PendingCall::cancel()
100{
101 dbus_pending_call_cancel(_pvt->call);
102}
103
104void PendingCall::block()
105{
106 dbus_pending_call_block(_pvt->call);
107}
108
109void PendingCall::data(void *p)
110{
111 if (!dbus_pending_call_set_data(_pvt->call, _pvt->dataslot, p, NULL))
112 {
113 throw ErrorNoMemory("Unable to initialize data slot");
114 }
115}
116
117void *PendingCall::data()
118{
119 return dbus_pending_call_get_data(_pvt->call, _pvt->dataslot);
120}
121
122Slot<void, PendingCall &>& PendingCall::slot()
123{
124 return _pvt->slot;
125}
126
127Message PendingCall::steal_reply()
128{
129 DBusMessage *dmsg = dbus_pending_call_steal_reply(_pvt->call);
130 if (!dmsg)
131 {
132 dbus_bool_t callComplete = dbus_pending_call_get_completed(_pvt->call);
133
134 if (callComplete)
135 throw ErrorNoReply("No reply available");
136 else
137 throw ErrorNoReply("Call not complete");
138 }
139
140 return Message(new Message::Private(dmsg));
141}
142