On Tue, Nov 15, 2011 at 11:53 AM, Enlightenment SVN
<[email protected]> 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: [email protected]
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel