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