aboutsummaryrefslogtreecommitdiff
path: root/src/lib/common/gnunet_dbus_lib_object.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/common/gnunet_dbus_lib_object.c')
-rw-r--r--src/lib/common/gnunet_dbus_lib_object.c192
1 files changed, 192 insertions, 0 deletions
diff --git a/src/lib/common/gnunet_dbus_lib_object.c b/src/lib/common/gnunet_dbus_lib_object.c
new file mode 100644
index 0000000..816f587
--- /dev/null
+++ b/src/lib/common/gnunet_dbus_lib_object.c
@@ -0,0 +1,192 @@
1#include "config.h"
2
3#include <inttypes.h>
4
5#include <gnunet/platform.h>
6#include <gnunet/gnunet_common.h>
7#include <gnunet/gnunet_container_lib.h>
8
9#include "gnunet_dbus_lib.h"
10
11#define LOG(kind, ...) GNUNET_log_from (kind, "dbus-object", __VA_ARGS__)
12
13struct GNUNET_DBUS_Object
14{
15 struct GNUNET_DBUS_InterfaceIterator *interfaces_front;
16 struct GNUNET_DBUS_InterfaceIterator *interfaces_back;
17
18 struct GNUNET_DBUS_ObjectIterator *subobjects_front;
19 struct GNUNET_DBUS_ObjectIterator *subobjects_back;
20
21 char *name;
22 void *data;
23 unsigned ref_count;
24};
25
26struct GNUNET_DBUS_Object *
27GNUNET_DBUS_object_create (
28 const char *name,
29 void *data)
30{
31 struct GNUNET_DBUS_Object *object = GNUNET_new (struct GNUNET_DBUS_Object);
32 object->name = GNUNET_strdup (name);
33 object->data = data;
34 object->interfaces_front = NULL;
35 object->interfaces_back = NULL;
36 object->subobjects_front = NULL;
37 object->subobjects_back = NULL;
38 object->ref_count = 1;
39
40 return object;
41};
42
43void
44GNUNET_DBUS_object_ref (
45 struct GNUNET_DBUS_Object *object)
46{
47 object->ref_count++;
48};
49
50void
51GNUNET_DBUS_object_unref (
52 struct GNUNET_DBUS_Object *object)
53{
54 if (object->ref_count == 0)
55 {
56 LOG (GNUNET_ERROR_TYPE_ERROR, "Tried to unreference object with ref count 0\n");
57 GNUNET_abort_ ();
58 };
59 if (0 == --(object->ref_count))
60 {
61 struct GNUNET_DBUS_InterfaceIterator *int_it = object->interfaces_front;
62 while (int_it)
63 {
64 struct GNUNET_DBUS_InterfaceIterator *next = int_it->next;
65 GNUNET_DBUS_interface_unref (int_it->interface);
66 GNUNET_free (int_it);
67 int_it = next;
68 };
69
70 struct GNUNET_DBUS_ObjectIterator *obj_it = object->subobjects_front;
71 while (obj_it)
72 {
73 struct GNUNET_DBUS_ObjectIterator *next = obj_it->next;
74 GNUNET_DBUS_object_unref (obj_it->object);
75 GNUNET_free (obj_it);
76 obj_it = next;
77 };
78
79 GNUNET_free (object->name);
80 GNUNET_free (object);
81 }
82};
83
84const char *
85GNUNET_DBUS_object_get_name (
86 const struct GNUNET_DBUS_Object *object)
87{
88 return object->name;
89};
90
91void
92GNUNET_DBUS_object_add_interface (
93 struct GNUNET_DBUS_Object *object,
94 struct GNUNET_DBUS_Interface *interface)
95{
96 struct GNUNET_DBUS_InterfaceIterator *int_it = GNUNET_new (struct GNUNET_DBUS_InterfaceIterator);
97 int_it->interface = interface;
98 GNUNET_DBUS_interface_ref (interface);
99
100 GNUNET_CONTAINER_DLL_insert (object->interfaces_front,
101 object->interfaces_back,
102 int_it);
103};
104
105const struct GNUNET_DBUS_InterfaceIterator *
106GNUNET_DBUS_object_iterate_interfaces (
107 struct GNUNET_DBUS_Object *object)
108{
109 return object->interfaces_front;
110};
111
112void *
113GNUNET_DBUS_object_get_data (
114 struct GNUNET_DBUS_Object *object)
115{
116 return object->data;
117};
118
119struct GNUNET_DBUS_Object *
120GNUNET_DBUS_object_create_uniquely_named_subobject (
121 struct GNUNET_DBUS_Object *object,
122 void *data)
123{
124 while(true)
125 {
126 char name[9];
127 uint32_t id = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 0xffffffff);
128 GNUNET_snprintf (name, sizeof(name), "%08" PRIx32, id);
129 const struct GNUNET_DBUS_ObjectIterator *obj_it = GNUNET_DBUS_object_iterate_subobjects (object);
130 while (true)
131 {
132 if (! obj_it)
133 {
134 struct GNUNET_DBUS_Object *subobject = GNUNET_DBUS_object_create (name, data);
135 GNUNET_DBUS_object_add_subobject (object, subobject);
136 return subobject;
137 }
138
139 const struct GNUNET_DBUS_Object *test_object = obj_it->object;
140 if (0 == strcmp (name, GNUNET_DBUS_object_get_name (test_object)))
141 break;
142
143 obj_it = obj_it->next;
144 }
145 }
146}
147
148void
149GNUNET_DBUS_object_add_subobject (
150 struct GNUNET_DBUS_Object *object,
151 struct GNUNET_DBUS_Object *subobject)
152{
153 struct GNUNET_DBUS_ObjectIterator *obj_it = GNUNET_new (struct GNUNET_DBUS_ObjectIterator);
154 obj_it->object = subobject;
155 GNUNET_DBUS_object_ref (subobject);
156
157 GNUNET_CONTAINER_DLL_insert (object->subobjects_front,
158 object->subobjects_back,
159 obj_it);
160};
161
162void
163GNUNET_DBUS_object_remove_subobject (
164 struct GNUNET_DBUS_Object *object,
165 struct GNUNET_DBUS_ObjectIterator *subobject_it)
166{
167 GNUNET_DBUS_object_unref (subobject_it->object);
168 GNUNET_CONTAINER_DLL_remove (object->subobjects_front,
169 object->subobjects_back,
170 subobject_it);
171 GNUNET_free (subobject_it);
172};
173
174struct GNUNET_DBUS_ObjectIterator *
175GNUNET_DBUS_object_iterate_subobjects (
176 const struct GNUNET_DBUS_Object *object)
177{
178 return object->subobjects_front;
179}
180
181const struct GNUNET_DBUS_ObjectIterator *
182GNUNET_DBUS_object_find (
183 const struct GNUNET_DBUS_ObjectIterator *object_it,
184 const char *name)
185{
186 while (object_it && strcmp (name, object_it->object->name))
187 object_it = object_it->next;
188
189 return object_it;
190}
191
192