Correct syntax, not done but release often they say :-(
[lttv.git] / ltt / branches / poly / lttv / attribute.c
1
2 #include <lttv/attribute.h>
3
4 typedef union _AttributeValue {
5 int dv_int;
6 unsigned dv_uint;
7 long dv_long;
8 unsigned long dv_ulong;
9 float dv_float;
10 double dv_double;
11 LttvTime dv_time;
12 gpointer dv_pointer;
13 char *dv_string;
14 GObject *dv_gobject;
15 } AttributeValue;
16
17
18 typedef struct _Attribute {
19 LttvAttributeName name;
20 LttvAttributeType type;
21 AttributeValue value;
22 } Attribute;
23
24
25 LttvAttributeValue address_of_value(LttvAttributeType t, AttributeValue *v)
26 {
27 LttvAttributeValue va;
28
29 switch(t) {
30 case LTTV_INT: va.v_int = &v->dv_int; break;
31 case LTTV_UINT: va.v_uint = &v->dv_uint; break;
32 case LTTV_LONG: va.v_long = &v->dv_long; break;
33 case LTTV_ULONG: va.v_ulong = &v->dv_ulong; break;
34 case LTTV_FLOAT: va.v_float = &v->dv_float; break;
35 case LTTV_DOUBLE: va.v_double = &v->dv_double; break;
36 case LTTV_TIME: va.v_time = &v->dv_time; break;
37 case LTTV_POINTER: va.v_pointer = &v->dv_pointer; break;
38 case LTTV_STRING: va.v_string = &v->dv_string; break;
39 case LTTV_GOBJECT: va.v_gobject = &v->dv_gobject; break;
40 }
41 return va;
42 }
43
44
45 AttributeValue init_value(LttvAttributeType t)
46 {
47 AttributeValue v;
48
49 switch(t) {
50 case LTTV_INT: v.dv_int = 0; break;
51 case LTTV_UINT: v.dv_uint = 0; break;
52 case LTTV_LONG: v.dv_long = 0; break;
53 case LTTV_ULONG: v.dv_ulong = 0; break;
54 case LTTV_FLOAT: v.dv_float = 0; break;
55 case LTTV_DOUBLE: v.dv_double = 0; break;
56 case LTTV_TIME: v.dv_time.tv_sec = 0; v.dv_time.tv_nsec = 0; break;
57 case LTTV_POINTER: v.dv_pointer = NULL; break;
58 case LTTV_STRING: v.dv_string = NULL; break;
59 case LTTV_GOBJECT: v.dv_gobject = NULL; break;
60 }
61 return v;
62 }
63
64
65 unsigned int
66 lttv_attribute_get_number(LttvAttribute *self)
67 {
68 return self->attributes->len;
69 }
70
71
72 gboolean
73 lttv_attribute_named(LttvAttribute *self, gboolean *homogeneous)
74 {
75 *homogeneous = FALSE;
76 return TRUE;
77 }
78
79
80 LttvAttributeType
81 lttv_attribute_get(LttvAttribute *self, unsigned i, LttvAttributeName *name,
82 LttvAttributeValue *v)
83 {
84 Attribute *a;
85
86 a = &g_array_index(self->attributes, Attribute, i);
87 *name = a->name;
88 *v = address_of_value(a->type, &(a->value));
89 return a->type;
90 }
91
92
93 LttvAttributeType
94 lttv_attribute_get_by_name(LttvAttribute *self, LttvAttributeName name,
95 LttvAttributeValue *v)
96 {
97 Attribute *a;
98
99 unsigned i;
100
101 gpointer p;
102
103 p = g_hash_table_lookup(self->names, GUINT_TO_POINTER(name));
104 if(p == NULL) return LTTV_NONE;
105
106 i = POINTER_TO_GUINT(p);
107 i--;
108 a = &g_array_index(self->attributes, Attribute, i);
109 *v = address_of_value(a->type, &(a->value));
110 return a->type;
111 }
112
113
114 LttvAttributeValue
115 lttv_attribute_add(LttvAttribute *self, LttvAttributeName name,
116 LttvAttributeType t)
117 {
118 unsigned i;
119
120 Attribute a, *pa;
121
122 i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name));
123 if(i != 0) g_error("duplicate entry in attribute table");
124
125 a.name = name;
126 a.type = t;
127 a.value = init_value(t);
128 g_array_append_val(self->attributes, a);
129 i = self->attributes->len - 1;
130 pa = &g_array_index(self->attributes, Attribute, i);
131 g_hash_table_insert(self->names, GUINT_TO_POINTER(name),
132 GUINT_TO_POINTER(i + 1));
133 return address_of_value(t, &(pa->value));
134 }
135
136
137 /* Remove an attribute */
138
139 void
140 lttv_attribute_remove(LttvAttribute *self, unsigned i)
141 {
142 Attribute *a;
143
144 a = &g_array_index(self->attributes, Attribute, i);
145
146 /* Remove the array element and its entry in the name index */
147
148 g_hash_table_remove(self->names, GUINT_TO_POINTER(a->name));
149 g_array_remove_index_fast(self->attributes, i);
150
151 /* The element used to replace the removed element has its index entry
152 all wrong now. Reinsert it with its new position. */
153
154 g_hash_table_remove(self->names, GUINT_TO_POINTER(a->name));
155 g_hash_table_insert(self->names, GUINT_TO_POINTER(a->name), GUINT_TO_POINTER(i + 1));
156 }
157
158 void
159 lttv_attribute_remove_by_name(LttvAttribute *self, LttvAttributeName name)
160 {
161 unsigned i;
162
163 i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name));
164 if(i == 0) g_error("remove by name non existent attribute");
165
166 lttv_attribute_remove(self, i - 1);
167 }
168
169 /* Create an empty iattribute object and add it as an attribute under the
170 specified name, or return an existing iattribute attribute. If an
171 attribute of that name already exists but is not a GObject supporting the
172 iattribute interface, return NULL. */
173
174 LttvIAttribute*
175 lttv_attribute_create_subdir(LttvAttribute *self, LttvAttributeName name)
176 {
177 unsigned i;
178
179 Attribute a;
180
181 LttvAttribute *new;
182
183 i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name));
184 if(i != 0) {
185 a = g_array_index(self->attributes, Attribute, i - 1);
186 if(a.type == LTTV_GOBJECT && LTTV_IS_IATTRIBUTE(a.value.dv_gobject)) {
187 return LTTV_IATTRIBUTE(a.value.dv_gobject);
188 }
189 else return NULL;
190 }
191 new = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
192 *(lttv_attribute_add(self, name, LTTV_GOBJECT).v_gobject) = G_OBJECT(new);
193 return (LttvIAttribute *)new;
194 }
195
196 gboolean
197 lttv_attribute_find(LttvAttribute *self, LttvAttributeName name,
198 LttvAttributeType t, LttvAttributeValue *v)
199 {
200 unsigned i;
201
202 Attribute *a;
203
204 i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name));
205 if(i != 0) {
206 a = &g_array_index(self->attributes, Attribute, i - 1);
207 if(a->type != t) return FALSE;
208 *v = address_of_value(t, &(a->value));
209 return TRUE;
210 }
211
212 *v = lttv_attribute_add(self, name, t);
213 return TRUE;
214 }
215
216
217 static void
218 attribute_interface_init (gpointer g_iface, gpointer iface_data)
219 {
220 LttvIAttributeClass *klass = (LttvIAttributeClass *)g_iface;
221
222 klass->get_number = (unsigned int (*) (LttvIAttribute *self))
223 lttv_attribute_get_number;
224
225 klass->named = (gboolean (*) (LttvIAttribute *self, gboolean *homogeneous))
226 lttv_attribute_named;
227
228 klass->get = (LttvAttributeType (*) (LttvIAttribute *self, unsigned i,
229 LttvAttributeName *name, LttvAttributeValue *v)) lttv_attribute_get;
230
231 klass->get_by_name = (LttvAttributeType (*) (LttvIAttribute *self,
232 LttvAttributeName name, LttvAttributeValue *v))
233 lttv_attribute_get_by_name;
234
235 klass->add = (LttvAttributeValue (*) (LttvIAttribute *self,
236 LttvAttributeName name, LttvAttributeType t)) lttv_attribute_add;
237
238 klass->remove = (void (*) (LttvIAttribute *self, unsigned i))
239 lttv_attribute_remove;
240
241 klass->remove_by_name = (void (*) (LttvIAttribute *self,
242 LttvAttributeName name)) lttv_attribute_remove_by_name;
243
244 klass->create_subdir = (LttvIAttribute* (*) (LttvIAttribute *self,
245 LttvAttributeName name)) lttv_attribute_create_subdir;
246 }
247
248
249 static void
250 attribute_instance_init (GTypeInstance *instance, gpointer g_class)
251 {
252 LttvAttribute *self = (LttvAttribute *)instance;
253 self->names = g_hash_table_new(g_direct_hash, g_direct_equal);
254 self->attributes = g_array_new(FALSE, FALSE, sizeof(Attribute));
255 }
256
257
258 static void
259 attribute_finalize (LttvAttribute *self)
260 {
261 g_hash_table_free(self->names);
262 g_array_free(self->attributes, TRUE);
263 G_OBJECT_CLASS(g_type_class_peek_parent(LTTV_ATTRIBUTE_GET_CLASS(self)))->finalize(G_OBJECT(self));
264 }
265
266
267 static void
268 attribute_class_init (LttvAttributeClass *klass)
269 {
270 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
271
272 gobject_class->finalize = (void (*)(GObject *self))attribute_finalize;
273 }
274
275 GType
276 lttv_attribute_get_type (void)
277 {
278 static GType type = 0;
279 if (type == 0) {
280 static const GTypeInfo info = {
281 sizeof (LttvAttributeClass),
282 NULL, /* base_init */
283 NULL, /* base_finalize */
284 (GClassInitFunc) attribute_class_init, /* class_init */
285 NULL, /* class_finalize */
286 NULL, /* class_data */
287 sizeof (LttvAttribute),
288 0, /* n_preallocs */
289 (GInstanceInitFunc) attribute_instance_init /* instance_init */
290 };
291
292 static const GInterfaceInfo iattribute_info = {
293 (GInterfaceInitFunc) attribute_interface_init, /* interface_init */
294 NULL, /* interface_finalize */
295 NULL /* interface_data */
296 };
297
298 type = g_type_register_static (G_TYPE_OBJECT, "LttvAttributeType", &info,
299 0);
300 g_type_add_interface_static (type, LTTV_IATTRIBUTE_TYPE, &iattribute_info);
301 }
302 return type;
303 }
304
305
This page took 0.036379 seconds and 4 git commands to generate.