interface.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++/debug.h>
00029 #include <dbus-c++/interface.h>
00030 
00031 #include "internalerror.h"
00032 
00033 using namespace DBus;
00034 
00035 Interface::Interface(const std::string &name)
00036   : _name(name)
00037 {}
00038 
00039 Interface::~Interface()
00040 {}
00041 
00042 InterfaceAdaptor *AdaptorBase::find_interface(const std::string &name)
00043 {
00044   InterfaceAdaptorTable::const_iterator ii = _interfaces.find(name);
00045 
00046   return ii != _interfaces.end() ? ii->second : NULL;
00047 }
00048 
00049 InterfaceAdaptor::InterfaceAdaptor(const std::string &name)
00050   : Interface(name)
00051 {
00052   debug_log("adding interface %s", name.c_str());
00053 
00054   _interfaces[name] = this;
00055 }
00056 
00057 Message InterfaceAdaptor::dispatch_method(const CallMessage &msg)
00058 {
00059   const char *name = msg.member();
00060 
00061   MethodTable::iterator mi = _methods.find(name);
00062   if (mi != _methods.end())
00063   {
00064     return mi->second.call(msg);
00065   }
00066   else
00067   {
00068     return ErrorMessage(msg, DBUS_ERROR_UNKNOWN_METHOD, name);
00069   }
00070 }
00071 
00072 void InterfaceAdaptor::emit_signal(const SignalMessage &sig)
00073 {
00074   SignalMessage &sig2 = const_cast<SignalMessage &>(sig);
00075 
00076   if (sig2.interface() == NULL)
00077     sig2.interface(name().c_str());
00078 
00079   _emit_signal(sig2);
00080 }
00081 
00082 Variant *InterfaceAdaptor::get_property(const std::string &name)
00083 {
00084   PropertyTable::iterator pti = _properties.find(name);
00085 
00086   if (pti != _properties.end())
00087   {
00088     if (!pti->second.read)
00089       throw ErrorAccessDenied("property is not readable");
00090 
00091     return &(pti->second.value);
00092   }
00093   return NULL;
00094 }
00095 
00096 void InterfaceAdaptor::set_property(const std::string &name, Variant &value)
00097 {
00098   PropertyTable::iterator pti = _properties.find(name);
00099 
00100   if (pti != _properties.end())
00101   {
00102     if (!pti->second.write)
00103       throw ErrorAccessDenied("property is not writeable");
00104 
00105     Signature sig = value.signature();
00106 
00107     if (pti->second.sig != sig)
00108       throw ErrorInvalidSignature("property expects a different type");
00109 
00110     pti->second.value = value;
00111     return;
00112   }
00113   throw ErrorFailed("requested property not found");
00114 }
00115 
00116 InterfaceProxy *ProxyBase::find_interface(const std::string &name)
00117 {
00118   InterfaceProxyTable::const_iterator ii = _interfaces.find(name);
00119 
00120   return ii != _interfaces.end() ? ii->second : NULL;
00121 }
00122 
00123 InterfaceProxy::InterfaceProxy(const std::string &name)
00124   : Interface(name)
00125 {
00126   debug_log("adding interface %s", name.c_str());
00127 
00128   _interfaces[name] = this;
00129 }
00130 
00131 bool InterfaceProxy::dispatch_signal(const SignalMessage &msg)
00132 {
00133   const char *name = msg.member();
00134 
00135   SignalTable::iterator si = _signals.find(name);
00136   if (si != _signals.end())
00137   {
00138     si->second.call(msg);
00139     // Here we always return false because there might be
00140     // another InterfaceProxy listening for the same signal.
00141     // This way we instruct libdbus-1 to go on dispatching
00142     // the signal.
00143     return false;
00144   }
00145   else
00146   {
00147     return false;
00148   }
00149 }
00150 
00151 Message InterfaceProxy::invoke_method(const CallMessage &call)
00152 {
00153   CallMessage &call2 = const_cast<CallMessage &>(call);
00154 
00155   if (call.interface() == NULL)
00156     call2.interface(name().c_str());
00157 
00158   return _invoke_method(call2);
00159 }
00160 
00161 bool InterfaceProxy::invoke_method_noreply(const CallMessage &call)
00162 {
00163   CallMessage &call2 = const_cast<CallMessage &>(call);
00164 
00165   if (call.interface() == NULL)
00166     call2.interface(name().c_str());
00167 
00168   return _invoke_method_noreply(call2);
00169 }