#include "config.h" #include #include #include #include "gnunet_dbus_lib.h" #define LOG(kind, ...) GNUNET_log_from (kind, "dbus-object-path", __VA_ARGS__) struct GNUNET_DBUS_ObjectPath { size_t objects_len; struct GNUNET_DBUS_Object **objects; size_t ref_count; }; struct GNUNET_DBUS_ObjectPath * GNUNET_DBUS_object_path_create ( struct GNUNET_DBUS_Service *service, ...) { struct GNUNET_DBUS_ObjectPath *path = GNUNET_new (struct GNUNET_DBUS_ObjectPath); path->objects_len = 1; path->ref_count = 1; va_list vl; va_start (vl, service); while (va_arg (vl, struct GNUNET_DBUS_Object *)) { path->objects_len++; } va_end (vl); path->objects = GNUNET_malloc (sizeof (struct GNUNET_DBUS_Object *) * (path->objects_len + 1)); va_start (vl, service); size_t i; struct GNUNET_DBUS_Object *elem = GNUNET_DBUS_service_get_root_object (service); path->objects[0] = elem; GNUNET_DBUS_object_ref (elem); for (i = 1; i < path->objects_len; i++) { elem = va_arg (vl, struct GNUNET_DBUS_Object *); path->objects[i] = elem; GNUNET_DBUS_object_ref (elem); } path->objects[path->objects_len] = NULL; va_end (vl); return path; } void GNUNET_DBUS_object_path_unref ( struct GNUNET_DBUS_ObjectPath *path) { if (path->ref_count == 0) { LOG (GNUNET_ERROR_TYPE_ERROR, "Tried to unreference object path with ref count 0\n"); /* This will probably segfault, but oh well */ char *path_as_str = GNUNET_DBUS_object_path_to_string (path); LOG (GNUNET_ERROR_TYPE_ERROR, " path == %s\n", path_as_str); GNUNET_abort_ (); }; if (0 == --(path->ref_count)) { size_t i; for (i = 0; i < path->objects_len; i++) { GNUNET_DBUS_object_unref (path->objects[i]); } GNUNET_free (path->objects); GNUNET_free (path); } } char * GNUNET_DBUS_object_path_to_string ( const struct GNUNET_DBUS_ObjectPath *path) { char *data; char *new_data; struct GNUNET_DBUS_Object **obj = path->objects; obj++; if (NULL == *obj) { GNUNET_asprintf (&data, "/"); return data; } GNUNET_asprintf (&data, "%s", ""); while (*obj) { GNUNET_asprintf (&new_data, "%s/%s", data, GNUNET_DBUS_object_get_name (*obj)); GNUNET_free (data); data = new_data; obj++; } return data; } #if 0 struct GNUNET_DBUS_ObjectPath * GNUNET_DBUS_object_path_create_from_string ( const struct GNUNET_DBUS_Service *service, const char *path_str) { char **path_decomposed = NULL; dbus_bool_t succ = dbus_message_get_path_decomposed (dbus_message, &path_decomposed); if (! succ) { LOG (GNUNET_ERROR_TYPE_ERROR, "dbus_message_get_path_decomposed failed.\n"); GNUNET_abort_ (); }; struct GNUNET_DBUS_ObjectPath *object_path = GNUNET_new (struct GNUNET_DBUS_ObjectPath); object_path->objects_len = 0; const char **path_element = path_decomposed; while (*path_element) { object_path->objects_len++; path_element++; } object_path->objects = GNUNET_malloc (sizeof (struct GNUNET_DBUS_Object *) * object_path->objects_len); const struct GNUNET_DBUS_Object *object = GNUNET_DBUS_service_get_root_object (service); struct GNUNET_DBUS_Object **pos = object_path->objects; *pos++ = object; path_element = path_decomposed; while (*path_element) { const struct GNUNET_DBUS_ObjectIterator *start = GNUNET_DBUS_object_iterate_subobjects (object); const struct GNUNET_DBUS_ObjectIterator *found = GNUNET_DBUS_object_find (start, *path_element); if (! found) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Invalid object path \"%s\"\n", path_str); return NULL; }; object = found->object; *pos++ = object; path_element++; } object_path->ref_count = 1; return object_path; } #endif struct GNUNET_DBUS_Object * GNUNET_DBUS_object_path_get_destination ( const struct GNUNET_DBUS_ObjectPath *path) { return path->objects[path->objects_len - 1]; }