On Tue, Nov 15, 2011 at 11:53 AM, Enlightenment SVN <no-re...@enlightenment.org> wrote: > Log: > Eina_xml based dbus introspection support. Thanks to Gustavo for the parser. ... > +static void cb_introspect(void *data, DBusMessage *msg, DBusError *error) > +{ > + DBusError e; > + DBus *dbus = ((struct dbus_cache *)(data))->dbus; > + const char *xml_str; > + > + if ((error) && (dbus_error_is_set(error))) > + { > + fprintf(stderr, "Error: DBus replied with error %s: %s\n", > + error->name, error->message);
convert it to eina log, create one domain for elv8 and other for submodules such as elv8-dbus > + > + struct DBus_Introspection_Parse_Ctxt *ctxt; > + ctxt = (struct DBus_Introspection_Parse_Ctxt *)calloc(1, sizeof(struct > DBus_Introspection_Parse_Ctxt)); > + if (!eina_simple_xml_parse(xml_str, strlen(xml_str), EINA_TRUE, cb_parse, > ctxt)) > + { > + fprintf(stderr, "Error: could not parse XML:\n%s\n", xml_str); leak of ctxt! > + return; > + } > + > + std::pair<std::map<const char *,DBus_Introspection_Parse_Ctxt > *>::iterator,bool> ret; I'd not allocate ctxt, and would not make it into cache. As I've explained at IRC, the correct structure for this is: path => {interfaces, children} children => [path1, path2, ...] interfaces = [interface1, interface2, ...] interface = {methods, signals, properties} methods = [method1, method2, method3...] method = {name, [argument1, argument2, ...]} signals = [signal1, signal2, signal3...] signal = {name, [argument1, argument2, ...]} properties = [property1, property2, property3...] property = {name, type} Usage is one of: 1 - explicit: var obj = bus.get_object(name, path); var iface = obj.get_interface(iface_name); iface.Method(p1, p2, p3); 2 - implicit: var obj = bus.get_object(name, path); obj.Method(p1, p2, p3); The first case is simple: iface = find_interface(iface_name) # mapping string => interface structure method = find_method(iface, signature) # mapping string => method structure signature you need to compute for instance: ai Method(o,s,i) ai Method(o,s,name=value) # named values will be supported in elev8? parameters in a hash/map? Must define a policy, like sort alphabetically and put at the end. Likely will have to have multiple signatures per method! The second case is bit more complex: ifaces = get_all_interfaces(obj) # mapping path => list of iface structures methods = [] for i in ifaces: m = find_method(i, signature) # mapping string => method structure if not m: continue methods.append(m) if len(methods) > 1: raise "Error: conflicting interfaces for " + signature + ": " + ", ".join(ifaces) else if len(methods) == 0: raise "Error: unknown method" method = methods[0] Cache: method lookup is likely expensive, then cache it as LRU per object, with a limit of dozens so you don't leak memory. Test case must not go the slow path after the first iteration: for (i = 0; i < 1000; i++) obj.Method(i); Assuming that services are implemented correctly the interfaces are unique globally, then you can have: global map interfaces: "interface name" string => interface interface map methods: "method signature" string => method object list interfaces: pair ("interface name" string, "interface instance" interface) object lru methods: pair ("method signature" string, "method instance" method) =================================================================== > --- trunk/PROTO/elev8/src/bin/dbus_library.h 2011-11-15 13:34:28 UTC (rev > 65263) > +++ trunk/PROTO/elev8/src/bin/dbus_library.h 2011-11-15 13:53:27 UTC (rev > 65264) > @@ -4,21 +4,100 @@ > #include <v8.h> > #include <dbus/dbus.h> > #include <E_DBus.h> > -#include "dbus_introspect.h" > +#include <Eina.h> > + > #include <exception> > -#include <sstream> > +#include <map> > #include <iostream> > #include <fstream> > > +/* memory efficient structures to hold introspection information. > + * maybe Eina_Inlist could be replaced with single array of structures > + * (not to be confused with Eina_Array!!!!) > + */ > + > +struct DBus_Method_Argument > +{ > + EINA_INLIST; > + const char *type; > + const char *name; > + Eina_Bool is_output:1; > +}; if you're using structs with malloc/free (C-like) then declare as extern "C" {}, will avoid name marshling by C++ compiler, etc. -- Gustavo Sverzut Barbieri http://profusion.mobi embedded systems -------------------------------------- MSN: barbi...@gmail.com Skype: gsbarbieri Mobile: +55 (19) 9225-2202 ------------------------------------------------------------------------------ RSA(R) Conference 2012 Save $700 by Nov 18 Register now http://p.sf.net/sfu/rsa-sfdev2dev1 _______________________________________________ enlightenment-devel mailing list enlightenment-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-devel