aboutsummaryrefslogtreecommitdiff
path: root/src/lib/common/gnunet_dbus_lib_object_path.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/common/gnunet_dbus_lib_object_path.c')
-rw-r--r--src/lib/common/gnunet_dbus_lib_object_path.c162
1 files changed, 162 insertions, 0 deletions
diff --git a/src/lib/common/gnunet_dbus_lib_object_path.c b/src/lib/common/gnunet_dbus_lib_object_path.c
new file mode 100644
index 0000000..72a155f
--- /dev/null
+++ b/src/lib/common/gnunet_dbus_lib_object_path.c
@@ -0,0 +1,162 @@
1#include "config.h"
2
3#include <gnunet/platform.h>
4#include <gnunet/gnunet_common.h>
5#include <gnunet/gnunet_container_lib.h>
6
7#include "gnunet_dbus_lib.h"
8
9#define LOG(kind, ...) GNUNET_log_from (kind, "dbus-object-path", __VA_ARGS__)
10
11struct GNUNET_DBUS_ObjectPath
12{
13 size_t objects_len;
14 struct GNUNET_DBUS_Object **objects;
15 size_t ref_count;
16};
17
18struct GNUNET_DBUS_ObjectPath *
19GNUNET_DBUS_object_path_create (
20 struct GNUNET_DBUS_Service *service,
21 ...)
22{
23 struct GNUNET_DBUS_ObjectPath *path = GNUNET_new (struct GNUNET_DBUS_ObjectPath);
24 path->objects_len = 1;
25 path->ref_count = 1;
26
27 va_list vl;
28 va_start (vl, service);
29 while (va_arg (vl, struct GNUNET_DBUS_Object *))
30 {
31 path->objects_len++;
32 }
33 va_end (vl);
34
35 path->objects = GNUNET_malloc (sizeof (struct GNUNET_DBUS_Object *) * (path->objects_len + 1));
36 va_start (vl, service);
37 size_t i;
38 struct GNUNET_DBUS_Object *elem = GNUNET_DBUS_service_get_root_object (service);
39 path->objects[0] = elem;
40 GNUNET_DBUS_object_ref (elem);
41 for (i = 1; i < path->objects_len; i++)
42 {
43 elem = va_arg (vl, struct GNUNET_DBUS_Object *);
44 path->objects[i] = elem;
45 GNUNET_DBUS_object_ref (elem);
46 }
47 path->objects[path->objects_len] = NULL;
48 va_end (vl);
49
50 return path;
51}
52
53void
54GNUNET_DBUS_object_path_unref (
55 struct GNUNET_DBUS_ObjectPath *path)
56{
57 if (path->ref_count == 0)
58 {
59 LOG (GNUNET_ERROR_TYPE_ERROR, "Tried to unreference object path with ref count 0\n");
60
61 /* This will probably segfault, but oh well */
62 char *path_as_str = GNUNET_DBUS_object_path_to_string (path);
63 LOG (GNUNET_ERROR_TYPE_ERROR, " path == %s\n", path_as_str);
64 GNUNET_abort_ ();
65 };
66 if (0 == --(path->ref_count))
67 {
68 size_t i;
69 for (i = 0; i < path->objects_len; i++)
70 {
71 GNUNET_DBUS_object_unref (path->objects[i]);
72 }
73
74 GNUNET_free (path->objects);
75 GNUNET_free (path);
76 }
77}
78
79char *
80GNUNET_DBUS_object_path_to_string (
81 const struct GNUNET_DBUS_ObjectPath *path)
82{
83 char *data;
84 char *new_data;
85
86 struct GNUNET_DBUS_Object **obj = path->objects;
87
88 obj++;
89 if (NULL == *obj)
90 {
91 GNUNET_asprintf (&data, "/");
92 return data;
93 }
94
95 GNUNET_asprintf (&data, "%s", "");
96 while (*obj)
97 {
98 GNUNET_asprintf (&new_data, "%s/%s", data, GNUNET_DBUS_object_get_name (*obj));
99 GNUNET_free (data); data = new_data;
100 obj++;
101 }
102
103 return data;
104}
105
106#if 0
107struct GNUNET_DBUS_ObjectPath *
108GNUNET_DBUS_object_path_create_from_string (
109 const struct GNUNET_DBUS_Service *service,
110 const char *path_str)
111{
112 char **path_decomposed = NULL;
113 dbus_bool_t succ = dbus_message_get_path_decomposed (dbus_message, &path_decomposed);
114 if (! succ)
115 {
116 LOG (GNUNET_ERROR_TYPE_ERROR, "dbus_message_get_path_decomposed failed.\n");
117 GNUNET_abort_ ();
118 };
119
120 struct GNUNET_DBUS_ObjectPath *object_path = GNUNET_new (struct GNUNET_DBUS_ObjectPath);
121 object_path->objects_len = 0;
122 const char **path_element = path_decomposed;
123 while (*path_element)
124 {
125 object_path->objects_len++;
126 path_element++;
127 }
128
129 object_path->objects = GNUNET_malloc (sizeof (struct GNUNET_DBUS_Object *) * object_path->objects_len);
130
131 const struct GNUNET_DBUS_Object *object = GNUNET_DBUS_service_get_root_object (service);
132 struct GNUNET_DBUS_Object **pos = object_path->objects;
133 *pos++ = object;
134 path_element = path_decomposed;
135 while (*path_element)
136 {
137 const struct GNUNET_DBUS_ObjectIterator *start = GNUNET_DBUS_object_iterate_subobjects (object);
138 const struct GNUNET_DBUS_ObjectIterator *found = GNUNET_DBUS_object_find (start, *path_element);
139 if (! found)
140 {
141 LOG (GNUNET_ERROR_TYPE_DEBUG, "Invalid object path \"%s\"\n", path_str);
142 return NULL;
143 };
144
145 object = found->object;
146 *pos++ = object;
147 path_element++;
148 }
149
150 object_path->ref_count = 1;
151
152 return object_path;
153}
154#endif
155
156struct GNUNET_DBUS_Object *
157GNUNET_DBUS_object_path_get_destination (
158 const struct GNUNET_DBUS_ObjectPath *path)
159{
160 return path->objects[path->objects_len - 1];
161}
162