introspection.cpp
Go to the documentation of this file.
1 /*
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++/introspection.h>
29 #include <dbus-c++/object.h>
30 #include <dbus-c++/message.h>
31 
32 #include <dbus/dbus.h>
33 
34 #include <sstream>
35 
36 using namespace DBus;
37 
38 static const char *introspectable_name = "org.freedesktop.DBus.Introspectable";
39 
42 {
44 }
45 
47 {
48  debug_log("requested introspection data");
49 
50  std::ostringstream xml;
51 
52  xml << DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE;
53 
54  const std::string path = object()->path();
55 
56  xml << "<node name=\"" << path << "\">";
57 
58  InterfaceAdaptorTable::const_iterator iti;
59 
60  for (iti = _interfaces.begin(); iti != _interfaces.end(); ++iti)
61  {
62  debug_log("introspecting interface %s", iti->first.c_str());
63 
64  IntrospectedInterface *const intro = iti->second->introspect();
65  if (intro)
66  {
67  xml << "\n\t<interface name=\"" << intro->name << "\">";
68 
69  for (const IntrospectedProperty *p = intro->properties; p->name; ++p)
70  {
71  std::string access;
72 
73  if (p->read) access += "read";
74  if (p->write) access += "write";
75 
76  xml << "\n\t\t<property name=\"" << p->name << "\""
77  << " type=\"" << p->type << "\""
78  << " access=\"" << access << "\"/>";
79  }
80 
81  for (const IntrospectedMethod *m = intro->methods; m->args; ++m)
82  {
83  xml << "\n\t\t<method name=\"" << m->name << "\">";
84 
85  for (const IntrospectedArgument *a = m->args; a->type; ++a)
86  {
87  xml << "\n\t\t\t<arg direction=\"" << (a->in ? "in" : "out") << "\""
88  << " type=\"" << a->type << "\"";
89 
90  if (a->name) xml << " name=\"" << a->name << "\"";
91 
92  xml << "/>";
93  }
94 
95  xml << "\n\t\t</method>";
96  }
97 
98  for (const IntrospectedMethod *m = intro->signals; m->args; ++m)
99  {
100  xml << "\n\t\t<signal name=\"" << m->name << "\">";
101 
102  for (const IntrospectedArgument *a = m->args; a->type; ++a)
103  {
104  xml << "<arg type=\"" << a->type << "\"";
105 
106  if (a->name) xml << " name=\"" << a->name << "\"";
107 
108  xml << "/>";
109  }
110  xml << "\n\t\t</signal>";
111  }
112 
113  xml << "\n\t</interface>";
114  }
115  }
116 
117  const ObjectPathList nodes = ObjectAdaptor::child_nodes_from_prefix(path + '/');
118  ObjectPathList::const_iterator oni;
119 
120  for (oni = nodes.begin(); oni != nodes.end(); ++oni)
121  {
122  xml << "\n\t<node name=\"" << (*oni) << "\"/>";
123  }
124 
125  /* broken
126  const ObjectAdaptorPList children = ObjectAdaptor::from_path_prefix(path + '/');
127 
128  ObjectAdaptorPList::const_iterator oci;
129 
130  for (oci = children.begin(); oci != children.end(); ++oci)
131  {
132  std::string name = (*oci)->path().substr(path.length()+1);
133  name.substr(name.find('/'));
134 
135  xml << "<node name=\"" << name << "\"/>";
136  }
137  */
138 
139  xml << "\n</node>";
140 
141  ReturnMessage reply(call);
142  MessageIter wi = reply.writer();
143  wi.append_string(xml.str().c_str());
144  return reply;
145 }
146 
148 {
149  static IntrospectedArgument Introspect_args[] =
150  {
151  { "data", "s", false },
152  { 0, 0, 0 }
153  };
154  static IntrospectedMethod Introspectable_methods[] =
155  {
156  { "Introspect", Introspect_args },
157  { 0, 0 }
158  };
159  static IntrospectedMethod Introspectable_signals[] =
160  {
161  { 0, 0 }
162  };
163  static IntrospectedProperty Introspectable_properties[] =
164  {
165  { 0, 0, 0, 0 }
166  };
167  static IntrospectedInterface Introspectable_interface =
168  {
170  Introspectable_methods,
171  Introspectable_signals,
172  Introspectable_properties
173  };
174  return &Introspectable_interface;
175 }
176 
179 {}
180 
182 {
183  DBus::CallMessage call;
184 
185  call.member("Introspect");
186 
187  DBus::Message ret = invoke_method(call);
188 
189  DBus::MessageIter ri = ret.reader();
190  const char *str = ri.get_string();
191 
192  return str;
193 }
const char * get_string()
Definition: message.cpp:196
IntrospectedInterface * introspect() const
bool append_string(const char *chars)
Definition: message.cpp:191
const IntrospectedArgument * args
Definition: introspection.h:44
const IntrospectedProperty * properties
Definition: introspection.h:60
const IntrospectedMethod * signals
Definition: introspection.h:59
virtual const ObjectAdaptor * object() const =0
static const char * introspectable_name
static ObjectPathList child_nodes_from_prefix(const std::string &prefix)
Definition: object.cpp:134
Message invoke_method(const CallMessage &)
Definition: interface.cpp:151
const IntrospectedMethod * methods
Definition: introspection.h:58
MessageIter reader() const
Definition: message.cpp:479
const char * member() const
Definition: message.cpp:598
Message Introspect(const CallMessage &)
DXXAPI LogFunction debug_log
Definition: debug.cpp:55
#define register_method(interface, method, callback)
Definition: interface.h:180
InterfaceAdaptorTable _interfaces
Definition: interface.h:73
MessageIter writer()
Definition: message.cpp:472
std::list< std::string > ObjectPathList
Definition: object.h:114
const DBus::Path & path() const
Definition: object.h:82