On Tue, Nov 15, 2011 at 11:45 PM, Gustavo Sverzut Barbieri <
barbi...@profusion.mobi> wrote:

> 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
>

Ok.


>
>
> > +
> > +   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!
>
Will fix this.


>
>
> > +        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}
>

Don't the existing structures do this already? Except for the addition of
the DBus_Node?


>
> 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);
>
>
I haven't yet decided on the best way to make dbus calls/signals simple for
users. Let's discuss over IRC today.



> 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.
>

Yes, will fix this.


>
> --
> 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
>
------------------------------------------------------------------------------
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

Reply via email to