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