blob: 15d859659cf3e0beed51c97949b2c2f3367ae44a [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++/debug.h>
29#include <dbus-c++/interface.h>
30
31#include "internalerror.h"
32
33using namespace DBus;
34
35Interface::Interface(const std::string &name)
36 : _name(name)
37{}
38
39Interface::~Interface()
40{}
41
42InterfaceAdaptor *AdaptorBase::find_interface(const std::string &name)
43{
44 InterfaceAdaptorTable::const_iterator ii = _interfaces.find(name);
45
46 return ii != _interfaces.end() ? ii->second : NULL;
47}
48
49InterfaceAdaptor::InterfaceAdaptor(const std::string &name)
50 : Interface(name)
51{
52 debug_log("adding interface %s", name.c_str());
53
54 _interfaces[name] = this;
55}
56
57Message InterfaceAdaptor::dispatch_method(const CallMessage &msg)
58{
59 const char *name = msg.member();
60
61 MethodTable::iterator mi = _methods.find(name);
62 if (mi != _methods.end())
63 {
64 return mi->second.call(msg);
65 }
66 else
67 {
68 return ErrorMessage(msg, DBUS_ERROR_UNKNOWN_METHOD, name);
69 }
70}
71
72void InterfaceAdaptor::emit_signal(const SignalMessage &sig)
73{
74 SignalMessage &sig2 = const_cast<SignalMessage &>(sig);
75
76 if (sig2.interface() == NULL)
77 sig2.interface(name().c_str());
78
79 _emit_signal(sig2);
80}
81
82Variant *InterfaceAdaptor::get_property(const std::string &name)
83{
84 PropertyTable::iterator pti = _properties.find(name);
85
86 if (pti != _properties.end())
87 {
88 if (!pti->second.read)
89 throw ErrorAccessDenied("property is not readable");
90
91 return &(pti->second.value);
92 }
93 return NULL;
94}
95
96void InterfaceAdaptor::set_property(const std::string &name, Variant &value)
97{
98 PropertyTable::iterator pti = _properties.find(name);
99
100 if (pti != _properties.end())
101 {
102 if (!pti->second.write)
103 throw ErrorAccessDenied("property is not writeable");
104
105 Signature sig = value.signature();
106
107 if (pti->second.sig != sig)
108 throw ErrorInvalidSignature("property expects a different type");
109
110 pti->second.value = value;
111 return;
112 }
113 throw ErrorFailed("requested property not found");
114}
115
116InterfaceProxy *ProxyBase::find_interface(const std::string &name)
117{
118 InterfaceProxyTable::const_iterator ii = _interfaces.find(name);
119
120 return ii != _interfaces.end() ? ii->second : NULL;
121}
122
123InterfaceProxy::InterfaceProxy(const std::string &name)
124 : Interface(name)
125{
126 debug_log("adding interface %s", name.c_str());
127
128 _interfaces[name] = this;
129}
130
131bool InterfaceProxy::dispatch_signal(const SignalMessage &msg)
132{
133 const char *name = msg.member();
134
135 SignalTable::iterator si = _signals.find(name);
136 if (si != _signals.end())
137 {
138 si->second.call(msg);
139 // Here we always return false because there might be
140 // another InterfaceProxy listening for the same signal.
141 // This way we instruct libdbus-1 to go on dispatching
142 // the signal.
143 return false;
144 }
145 else
146 {
147 return false;
148 }
149}
150
151Message InterfaceProxy::invoke_method(const CallMessage &call)
152{
153 CallMessage &call2 = const_cast<CallMessage &>(call);
154
155 if (call.interface() == NULL)
156 call2.interface(name().c_str());
157
158 return _invoke_method(call2);
159}
160
161bool InterfaceProxy::invoke_method_noreply(const CallMessage &call)
162{
163 CallMessage &call2 = const_cast<CallMessage &>(call);
164
165 if (call.interface() == NULL)
166 call2.interface(name().c_str());
167
168 return _invoke_method_noreply(call2);
169}