diff options
Diffstat (limited to 'src/lib/common/gnunet_dbus_lib_object_path.c')
-rw-r--r-- | src/lib/common/gnunet_dbus_lib_object_path.c | 162 |
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 | |||
11 | struct GNUNET_DBUS_ObjectPath | ||
12 | { | ||
13 | size_t objects_len; | ||
14 | struct GNUNET_DBUS_Object **objects; | ||
15 | size_t ref_count; | ||
16 | }; | ||
17 | |||
18 | struct GNUNET_DBUS_ObjectPath * | ||
19 | GNUNET_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 | |||
53 | void | ||
54 | GNUNET_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 | |||
79 | char * | ||
80 | GNUNET_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 | ||
107 | struct GNUNET_DBUS_ObjectPath * | ||
108 | GNUNET_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 | |||
156 | struct GNUNET_DBUS_Object * | ||
157 | GNUNET_DBUS_object_path_get_destination ( | ||
158 | const struct GNUNET_DBUS_ObjectPath *path) | ||
159 | { | ||
160 | return path->objects[path->objects_len - 1]; | ||
161 | } | ||
162 | |||