edbus: Append path of child objects in Introspectable

Patch by: José Roberto de Souza  <zehortigoza@profusion.mobi>



SVN revision: 79175
This commit is contained in:
José Roberto de Souza 2012-11-12 16:06:41 +00:00 committed by Lucas De Marchi
parent 208ad94428
commit fb26be4f1b
2 changed files with 96 additions and 4 deletions

View File

@ -61,6 +61,7 @@ struct _EDBus_Connection
Ecore_Idler *idler;
Eina_Bool running_signal;
EDBus_Connection_Context_Event event_handlers[EDBUS_CONNECTION_EVENT_LAST];
Eina_Inlist *root_objs;//service_object
};
struct _EDBus_Object
@ -132,15 +133,19 @@ struct _EDBus_Message
EDBus_Message_Iter *iterator;
};
typedef struct _EDBus_Service_Object
typedef struct _EDBus_Service_Object EDBus_Service_Object;
struct _EDBus_Service_Object
{
EINA_INLIST;
EDBus_Connection *conn;
const char *path;
Eina_Hash *interfaces;
Eina_Strbuf *introspection_data;
Eina_Bool introspection_dirty;
Eina_Inlist *data;
} EDBus_Service_Object;
EDBus_Service_Object *parent;
Eina_Inlist *children;
};
struct _EDBus_Service_Interface
{

View File

@ -52,6 +52,7 @@ static DBusHandlerResult _object_handler(DBusConnection *conn, DBusMessage *mess
static void _object_free(EDBus_Service_Object *obj);
static void _interface_free(EDBus_Service_Interface *interface);
static void _on_connection_free(void *data, const void *dead_pointer);
static EDBus_Service_Object *_edbus_service_object_parent_find(EDBus_Service_Object *obj);
static DBusObjectPathVTable vtable = {
_object_unregister,
@ -354,6 +355,7 @@ cb_introspect(const EDBus_Service_Interface *_iface, const EDBus_Message *messag
{
Eina_Iterator *iterator;
EDBus_Service_Interface *iface;
EDBus_Service_Object *child;
if (obj->introspection_data)
eina_strbuf_reset(obj->introspection_data);
@ -369,8 +371,18 @@ cb_introspect(const EDBus_Service_Interface *_iface, const EDBus_Message *messag
EINA_ITERATOR_FOREACH(iterator, iface)
_introspect_append_interface(obj->introspection_data, iface);
eina_iterator_free(iterator);
eina_strbuf_append(obj->introspection_data, "</node>");
EINA_INLIST_FOREACH(obj->children, child)
{
const char *subpath;
if (strlen(obj->path) == 1)
subpath = child->path+strlen(obj->path);
else
subpath = child->path+strlen(obj->path)+1;
eina_strbuf_append_printf(obj->introspection_data, "<node name=\"%s\" />", subpath);
}
eina_strbuf_append(obj->introspection_data, "</node>");
obj->introspection_dirty = EINA_FALSE;
}
@ -477,7 +489,8 @@ edbus_service_shutdown(void)
static EDBus_Service_Object *
_edbus_service_object_add(EDBus_Connection *conn, const char *path)
{
EDBus_Service_Object *obj;
EDBus_Service_Object *obj, *aux;
Eina_Inlist *safe;
obj = calloc(1, sizeof(EDBus_Service_Object));
EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
@ -497,6 +510,27 @@ _edbus_service_object_add(EDBus_Connection *conn, const char *path)
eina_hash_add(obj->interfaces, introspectable->name, introspectable);
eina_hash_add(obj->interfaces, properties_iface->name, properties_iface);
obj->parent = _edbus_service_object_parent_find(obj);
if (obj->parent)
{
obj->parent->children = eina_inlist_append(obj->parent->children,
EINA_INLIST_GET(obj));
return obj;
}
EINA_INLIST_FOREACH_SAFE(conn->root_objs, safe, aux)
{
if (!strncmp(obj->path, aux->path, strlen(obj->path)))
{
conn->root_objs = eina_inlist_remove(conn->root_objs,
EINA_INLIST_GET(aux));
obj->children = eina_inlist_append(obj->children,
EINA_INLIST_GET(aux));
aux->parent = obj;
}
}
conn->root_objs = eina_inlist_append(conn->root_objs, EINA_INLIST_GET(obj));
return obj;
}
@ -681,6 +715,31 @@ _object_free(EDBus_Service_Object *obj)
EINA_ITERATOR_FOREACH(iterator, iface)
_interface_free(iface);
while (obj->children)
{
EDBus_Service_Object *child;
child = EINA_INLIST_CONTAINER_GET(obj->children, EDBus_Service_Object);
obj->children = eina_inlist_remove(obj->children, obj->children);
if (obj->parent)
{
obj->parent->children = eina_inlist_append(obj->parent->children,
EINA_INLIST_GET(child));
child->parent = obj->parent;
}
else
{
obj->conn->root_objs = eina_inlist_append(obj->conn->root_objs,
EINA_INLIST_GET(child));
child->parent = NULL;
}
}
if (obj->parent)
obj->parent->children = eina_inlist_remove(obj->parent->children,
EINA_INLIST_GET(obj));
else
obj->conn->root_objs = eina_inlist_remove(obj->conn->root_objs,
EINA_INLIST_GET(obj));
edbus_data_del_all(&obj->data);
eina_hash_free(obj->interfaces);
@ -1032,3 +1091,31 @@ edbus_service_property_invalidate_set(EDBus_Service_Interface *iface, const char
iface->prop_invalidated = eina_array_new(1);
return eina_array_push(iface->prop_invalidated, prop);
}
static EDBus_Service_Object *
_edbus_service_object_parent_find(EDBus_Service_Object *obj)
{
size_t len = strlen(obj->path);
char *path = strdup(obj->path);
char *slash;
for (slash = path[len] != '/' ? &path[len - 1] : &path[len - 2];
slash > path; slash--)
{
EDBus_Service_Object *parent = NULL;
if (*slash != '/')
continue;
*slash = '\0';
if (dbus_connection_get_object_path_data(obj->conn->dbus_conn, path,(void **)&parent) && parent != NULL)
{
free(path);
return parent;
}
}
free(path);
return NULL;
}