pendingcall.cpp
Go to the documentation of this file.
00001 /* 00002 * 00003 * D-Bus++ - C++ bindings for D-Bus 00004 * 00005 * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> 00006 * 00007 * 00008 * This library is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * This library is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with this library; if not, write to the Free Software 00020 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00021 * 00022 */ 00023 00024 #ifdef HAVE_CONFIG_H 00025 #include <config.h> 00026 #endif 00027 00028 #include <dbus-c++/pendingcall.h> 00029 00030 #include <dbus/dbus.h> 00031 00032 #include "internalerror.h" 00033 #include "pendingcall_p.h" 00034 #include "message_p.h" 00035 00036 using namespace DBus; 00037 00038 PendingCall::Private::Private(DBusPendingCall *dpc) 00039 : call(dpc), dataslot(-1) 00040 { 00041 if (!dbus_pending_call_allocate_data_slot(&dataslot)) 00042 { 00043 throw ErrorNoMemory("Unable to allocate data slot"); 00044 } 00045 } 00046 00047 PendingCall::Private::~Private() 00048 { 00049 if (dataslot != -1) 00050 { 00051 dbus_pending_call_allocate_data_slot(&dataslot); 00052 } 00053 } 00054 00055 void PendingCall::Private::notify_stub(DBusPendingCall *dpc, void *data) 00056 { 00057 PendingCall::Private *pvt = static_cast<PendingCall::Private *>(data); 00058 00059 PendingCall pc(pvt); 00060 pvt->slot(pc); 00061 } 00062 00063 PendingCall::PendingCall(PendingCall::Private *p) 00064 : _pvt(p) 00065 { 00066 if (!dbus_pending_call_set_notify(_pvt->call, Private::notify_stub, p, NULL)) 00067 { 00068 throw ErrorNoMemory("Unable to initialize pending call"); 00069 } 00070 } 00071 00072 PendingCall::PendingCall(const PendingCall &c) 00073 : _pvt(c._pvt) 00074 { 00075 dbus_pending_call_ref(_pvt->call); 00076 } 00077 00078 PendingCall::~PendingCall() 00079 { 00080 dbus_pending_call_unref(_pvt->call); 00081 } 00082 00083 PendingCall &PendingCall::operator = (const PendingCall &c) 00084 { 00085 if (&c != this) 00086 { 00087 dbus_pending_call_unref(_pvt->call); 00088 _pvt = c._pvt; 00089 dbus_pending_call_ref(_pvt->call); 00090 } 00091 return *this; 00092 } 00093 00094 bool PendingCall::completed() 00095 { 00096 return dbus_pending_call_get_completed(_pvt->call); 00097 } 00098 00099 void PendingCall::cancel() 00100 { 00101 dbus_pending_call_cancel(_pvt->call); 00102 } 00103 00104 void PendingCall::block() 00105 { 00106 dbus_pending_call_block(_pvt->call); 00107 } 00108 00109 void PendingCall::data(void *p) 00110 { 00111 if (!dbus_pending_call_set_data(_pvt->call, _pvt->dataslot, p, NULL)) 00112 { 00113 throw ErrorNoMemory("Unable to initialize data slot"); 00114 } 00115 } 00116 00117 void *PendingCall::data() 00118 { 00119 return dbus_pending_call_get_data(_pvt->call, _pvt->dataslot); 00120 } 00121 00122 Slot<void, PendingCall &>& PendingCall::slot() 00123 { 00124 return _pvt->slot; 00125 } 00126 00127 Message PendingCall::steal_reply() 00128 { 00129 DBusMessage *dmsg = dbus_pending_call_steal_reply(_pvt->call); 00130 if (!dmsg) 00131 { 00132 dbus_bool_t callComplete = dbus_pending_call_get_completed(_pvt->call); 00133 00134 if (callComplete) 00135 throw ErrorNoReply("No reply available"); 00136 else 00137 throw ErrorNoReply("Call not complete"); 00138 } 00139 00140 return Message(new Message::Private(dmsg)); 00141 } 00142