introspection.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++/introspection.h> 00029 #include <dbus-c++/object.h> 00030 #include <dbus-c++/message.h> 00031 00032 #include <dbus/dbus.h> 00033 00034 #include <sstream> 00035 00036 using namespace DBus; 00037 00038 static const char *introspectable_name = "org.freedesktop.DBus.Introspectable"; 00039 00040 IntrospectableAdaptor::IntrospectableAdaptor() 00041 : InterfaceAdaptor(introspectable_name) 00042 { 00043 register_method(IntrospectableAdaptor, Introspect, Introspect); 00044 } 00045 00046 Message IntrospectableAdaptor::Introspect(const CallMessage &call) 00047 { 00048 debug_log("requested introspection data"); 00049 00050 std::ostringstream xml; 00051 00052 xml << DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE; 00053 00054 const std::string path = object()->path(); 00055 00056 xml << "<node name=\"" << path << "\">"; 00057 00058 InterfaceAdaptorTable::const_iterator iti; 00059 00060 for (iti = _interfaces.begin(); iti != _interfaces.end(); ++iti) 00061 { 00062 debug_log("introspecting interface %s", iti->first.c_str()); 00063 00064 IntrospectedInterface *const intro = iti->second->introspect(); 00065 if (intro) 00066 { 00067 xml << "\n\t<interface name=\"" << intro->name << "\">"; 00068 00069 for (const IntrospectedProperty *p = intro->properties; p->name; ++p) 00070 { 00071 std::string access; 00072 00073 if (p->read) access += "read"; 00074 if (p->write) access += "write"; 00075 00076 xml << "\n\t\t<property name=\"" << p->name << "\"" 00077 << " type=\"" << p->type << "\"" 00078 << " access=\"" << access << "\"/>"; 00079 } 00080 00081 for (const IntrospectedMethod *m = intro->methods; m->args; ++m) 00082 { 00083 xml << "\n\t\t<method name=\"" << m->name << "\">"; 00084 00085 for (const IntrospectedArgument *a = m->args; a->type; ++a) 00086 { 00087 xml << "\n\t\t\t<arg direction=\"" << (a->in ? "in" : "out") << "\"" 00088 << " type=\"" << a->type << "\""; 00089 00090 if (a->name) xml << " name=\"" << a->name << "\""; 00091 00092 xml << "/>"; 00093 } 00094 00095 xml << "\n\t\t</method>"; 00096 } 00097 00098 for (const IntrospectedMethod *m = intro->signals; m->args; ++m) 00099 { 00100 xml << "\n\t\t<signal name=\"" << m->name << "\">"; 00101 00102 for (const IntrospectedArgument *a = m->args; a->type; ++a) 00103 { 00104 xml << "<arg type=\"" << a->type << "\""; 00105 00106 if (a->name) xml << " name=\"" << a->name << "\""; 00107 00108 xml << "/>"; 00109 } 00110 xml << "\n\t\t</signal>"; 00111 } 00112 00113 xml << "\n\t</interface>"; 00114 } 00115 } 00116 00117 const ObjectPathList nodes = ObjectAdaptor::child_nodes_from_prefix(path + '/'); 00118 ObjectPathList::const_iterator oni; 00119 00120 for (oni = nodes.begin(); oni != nodes.end(); ++oni) 00121 { 00122 xml << "\n\t<node name=\"" << (*oni) << "\"/>"; 00123 } 00124 00125 /* broken 00126 const ObjectAdaptorPList children = ObjectAdaptor::from_path_prefix(path + '/'); 00127 00128 ObjectAdaptorPList::const_iterator oci; 00129 00130 for (oci = children.begin(); oci != children.end(); ++oci) 00131 { 00132 std::string name = (*oci)->path().substr(path.length()+1); 00133 name.substr(name.find('/')); 00134 00135 xml << "<node name=\"" << name << "\"/>"; 00136 } 00137 */ 00138 00139 xml << "\n</node>"; 00140 00141 ReturnMessage reply(call); 00142 MessageIter wi = reply.writer(); 00143 wi.append_string(xml.str().c_str()); 00144 return reply; 00145 } 00146 00147 IntrospectedInterface *IntrospectableAdaptor::introspect() const 00148 { 00149 static IntrospectedArgument Introspect_args[] = 00150 { 00151 { "data", "s", false }, 00152 { 0, 0, 0 } 00153 }; 00154 static IntrospectedMethod Introspectable_methods[] = 00155 { 00156 { "Introspect", Introspect_args }, 00157 { 0, 0 } 00158 }; 00159 static IntrospectedMethod Introspectable_signals[] = 00160 { 00161 { 0, 0 } 00162 }; 00163 static IntrospectedProperty Introspectable_properties[] = 00164 { 00165 { 0, 0, 0, 0 } 00166 }; 00167 static IntrospectedInterface Introspectable_interface = 00168 { 00169 introspectable_name, 00170 Introspectable_methods, 00171 Introspectable_signals, 00172 Introspectable_properties 00173 }; 00174 return &Introspectable_interface; 00175 } 00176 00177 IntrospectableProxy::IntrospectableProxy() 00178 : InterfaceProxy(introspectable_name) 00179 {} 00180 00181 std::string IntrospectableProxy::Introspect() 00182 { 00183 DBus::CallMessage call; 00184 00185 call.member("Introspect"); 00186 00187 DBus::Message ret = invoke_method(call); 00188 00189 DBus::MessageIter ri = ret.reader(); 00190 const char *str = ri.get_string(); 00191 00192 return str; 00193 }