Move "active" code out of debug statements
[lttv.git] / lttv / lttv / attribute.c
CommitLineData
9c312311 1/* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 Michel Dagenais
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
16 * MA 02111-1307, USA.
17 */
dc877563 18
4e4d11b3 19#ifdef HAVE_CONFIG_H
20#include <config.h>
21#endif
22
00e74b69 23#include <string.h>
fcdf0ec2 24#include <lttv/attribute.h>
b445142a 25#include <ltt/ltt.h>
1d1df11d 26#include <ltt/compiler.h>
f32847a1 27
dc877563 28typedef union _AttributeValue {
29 int dv_int;
30 unsigned dv_uint;
31 long dv_long;
32 unsigned long dv_ulong;
33 float dv_float;
34 double dv_double;
308711e5 35 LttTime dv_time;
dc877563 36 gpointer dv_pointer;
37 char *dv_string;
ffd54a90 38 GObject *dv_gobject;
dc877563 39} AttributeValue;
40
41
42typedef struct _Attribute {
43 LttvAttributeName name;
44 LttvAttributeType type;
45 AttributeValue value;
c0cb4d12 46 gboolean is_named;
dc877563 47} Attribute;
48
49
31b6868d 50static __inline__ LttvAttributeValue address_of_value(LttvAttributeType t,
51 AttributeValue *v)
dc877563 52{
ffd54a90 53 LttvAttributeValue va;
54
55 switch(t) {
56 case LTTV_INT: va.v_int = &v->dv_int; break;
57 case LTTV_UINT: va.v_uint = &v->dv_uint; break;
58 case LTTV_LONG: va.v_long = &v->dv_long; break;
59 case LTTV_ULONG: va.v_ulong = &v->dv_ulong; break;
60 case LTTV_FLOAT: va.v_float = &v->dv_float; break;
61 case LTTV_DOUBLE: va.v_double = &v->dv_double; break;
62 case LTTV_TIME: va.v_time = &v->dv_time; break;
63 case LTTV_POINTER: va.v_pointer = &v->dv_pointer; break;
64 case LTTV_STRING: va.v_string = &v->dv_string; break;
65 case LTTV_GOBJECT: va.v_gobject = &v->dv_gobject; break;
00e74b69 66 case LTTV_NONE: break;
ffd54a90 67 }
68 return va;
69}
dc877563 70
dc877563 71
ffd54a90 72AttributeValue init_value(LttvAttributeType t)
73{
74 AttributeValue v;
75
76 switch(t) {
77 case LTTV_INT: v.dv_int = 0; break;
78 case LTTV_UINT: v.dv_uint = 0; break;
79 case LTTV_LONG: v.dv_long = 0; break;
80 case LTTV_ULONG: v.dv_ulong = 0; break;
81 case LTTV_FLOAT: v.dv_float = 0; break;
82 case LTTV_DOUBLE: v.dv_double = 0; break;
83 case LTTV_TIME: v.dv_time.tv_sec = 0; v.dv_time.tv_nsec = 0; break;
84 case LTTV_POINTER: v.dv_pointer = NULL; break;
85 case LTTV_STRING: v.dv_string = NULL; break;
86 case LTTV_GOBJECT: v.dv_gobject = NULL; break;
00e74b69 87 case LTTV_NONE: break;
dc877563 88 }
ffd54a90 89 return v;
f32847a1 90}
91
92
dc877563 93unsigned int
94lttv_attribute_get_number(LttvAttribute *self)
95{
96 return self->attributes->len;
f32847a1 97}
98
dc877563 99gboolean
100lttv_attribute_named(LttvAttribute *self, gboolean *homogeneous)
101{
102 *homogeneous = FALSE;
103 return TRUE;
f32847a1 104}
105
dc877563 106LttvAttributeType
107lttv_attribute_get(LttvAttribute *self, unsigned i, LttvAttributeName *name,
c0cb4d12 108 LttvAttributeValue *v, gboolean *is_named)
dc877563 109{
110 Attribute *a;
f32847a1 111
dc877563 112 a = &g_array_index(self->attributes, Attribute, i);
113 *name = a->name;
ffd54a90 114 *v = address_of_value(a->type, &(a->value));
c0cb4d12 115 *is_named = a->is_named;
dc877563 116 return a->type;
f32847a1 117}
118
119
dc877563 120LttvAttributeType
121lttv_attribute_get_by_name(LttvAttribute *self, LttvAttributeName name,
122 LttvAttributeValue *v)
123{
124 Attribute *a;
f32847a1 125
dc877563 126 unsigned i;
f32847a1 127
ffd54a90 128 gpointer p;
129
130 p = g_hash_table_lookup(self->names, GUINT_TO_POINTER(name));
131 if(p == NULL) return LTTV_NONE;
f32847a1 132
ba576a78 133 i = GPOINTER_TO_UINT(p);
dc877563 134 i--;
135 a = &g_array_index(self->attributes, Attribute, i);
ffd54a90 136 *v = address_of_value(a->type, &(a->value));
dc877563 137 return a->type;
f32847a1 138}
139
f32847a1 140
dc877563 141LttvAttributeValue
142lttv_attribute_add(LttvAttribute *self, LttvAttributeName name,
143 LttvAttributeType t)
144{
43ed82b5 145 unsigned int i;
f32847a1 146
dc877563 147 Attribute a, *pa;
f32847a1 148
43ed82b5 149 i = GPOINTER_TO_UINT(g_hash_table_lookup(self->names, GUINT_TO_POINTER(name)));
dc877563 150 if(i != 0) g_error("duplicate entry in attribute table");
f32847a1 151
ffd54a90 152 a.name = name;
c0cb4d12 153 a.is_named = 1;
154 a.type = t;
155 a.value = init_value(t);
156 g_array_append_val(self->attributes, a);
157 i = self->attributes->len - 1;
158 pa = &g_array_index(self->attributes, Attribute, i);
159 g_hash_table_insert(self->names, GUINT_TO_POINTER(name),
160 GUINT_TO_POINTER(i + 1));
161 return address_of_value(t, &(pa->value));
162}
163
164LttvAttributeValue
165lttv_attribute_add_unnamed(LttvAttribute *self, LttvAttributeName name,
166 LttvAttributeType t)
167{
43ed82b5 168 unsigned int i;
c0cb4d12 169
170 Attribute a, *pa;
171
43ed82b5 172 i = GPOINTER_TO_UINT(g_hash_table_lookup(self->names, GUINT_TO_POINTER(name)));
c0cb4d12 173 if(i != 0) g_error("duplicate entry in attribute table");
174
175 a.name = name;
176 a.is_named = 0;
ffd54a90 177 a.type = t;
178 a.value = init_value(t);
dc877563 179 g_array_append_val(self->attributes, a);
180 i = self->attributes->len - 1;
ffd54a90 181 pa = &g_array_index(self->attributes, Attribute, i);
182 g_hash_table_insert(self->names, GUINT_TO_POINTER(name),
183 GUINT_TO_POINTER(i + 1));
184 return address_of_value(t, &(pa->value));
f32847a1 185}
186
187
dc877563 188/* Remove an attribute */
f32847a1 189
dc877563 190void
191lttv_attribute_remove(LttvAttribute *self, unsigned i)
f32847a1 192{
dc877563 193 Attribute *a;
f32847a1 194
dc877563 195 a = &g_array_index(self->attributes, Attribute, i);
f32847a1 196
c47a6dc6 197 /* If the element is a gobject, unreference it. */
198 if(a->type == LTTV_GOBJECT && a->value.dv_gobject != NULL)
199 g_object_unref(a->value.dv_gobject);
200
dc877563 201 /* Remove the array element and its entry in the name index */
f32847a1 202
ffd54a90 203 g_hash_table_remove(self->names, GUINT_TO_POINTER(a->name));
dc877563 204 g_array_remove_index_fast(self->attributes, i);
f32847a1 205
dc877563 206 /* The element used to replace the removed element has its index entry
207 all wrong now. Reinsert it with its new position. */
f32847a1 208
1d1df11d 209 if(likely(self->attributes->len != i)){
c6bc9cb9 210 g_hash_table_remove(self->names, GUINT_TO_POINTER(a->name));
211 g_hash_table_insert(self->names, GUINT_TO_POINTER(a->name), GUINT_TO_POINTER(i + 1));
212 }
f32847a1 213}
214
dc877563 215void
216lttv_attribute_remove_by_name(LttvAttribute *self, LttvAttributeName name)
217{
43ed82b5 218 unsigned int i;
f32847a1 219
43ed82b5 220 i = GPOINTER_TO_UINT(g_hash_table_lookup(self->names, GUINT_TO_POINTER(name)));
1d1df11d 221 if(unlikely(i == 0)) g_error("remove by name non existent attribute");
f32847a1 222
dc877563 223 lttv_attribute_remove(self, i - 1);
f32847a1 224}
225
dc877563 226/* Create an empty iattribute object and add it as an attribute under the
227 specified name, or return an existing iattribute attribute. If an
228 attribute of that name already exists but is not a GObject supporting the
229 iattribute interface, return NULL. */
f32847a1 230
b445142a 231/*CHECK*/LttvAttribute*
232lttv_attribute_find_subdir(LttvAttribute *self, LttvAttributeName name)
f32847a1 233{
43ed82b5 234 unsigned int i;
f32847a1 235
dc877563 236 Attribute a;
f32847a1 237
dc877563 238 LttvAttribute *new;
a43d67ba 239
43ed82b5 240 i = GPOINTER_TO_UINT(g_hash_table_lookup(self->names, GUINT_TO_POINTER(name)));
1d1df11d 241 if(likely(i != 0)) {
dc877563 242 a = g_array_index(self->attributes, Attribute, i - 1);
1d1df11d 243 if(likely(a.type == LTTV_GOBJECT && LTTV_IS_IATTRIBUTE(a.value.dv_gobject))) {
b445142a 244 return LTTV_ATTRIBUTE(a.value.dv_gobject);
dc877563 245 }
246 else return NULL;
f32847a1 247 }
ffd54a90 248 new = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
249 *(lttv_attribute_add(self, name, LTTV_GOBJECT).v_gobject) = G_OBJECT(new);
b445142a 250 return (LttvAttribute *)new;
f32847a1 251}
252
c0cb4d12 253/*CHECK*/LttvAttribute*
254lttv_attribute_find_subdir_unnamed(LttvAttribute *self, LttvAttributeName name)
255{
43ed82b5 256 unsigned int i;
c0cb4d12 257
258 Attribute a;
259
260 LttvAttribute *new;
261
43ed82b5 262 i = GPOINTER_TO_UINT(g_hash_table_lookup(self->names, GUINT_TO_POINTER(name)));
c0cb4d12 263 if(likely(i != 0)) {
264 a = g_array_index(self->attributes, Attribute, i - 1);
265 if(likely(a.type == LTTV_GOBJECT && LTTV_IS_IATTRIBUTE(a.value.dv_gobject))) {
266 return LTTV_ATTRIBUTE(a.value.dv_gobject);
267 }
268 else return NULL;
269 }
270 new = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
271 *(lttv_attribute_add_unnamed(self, name, LTTV_GOBJECT).v_gobject)
272 = G_OBJECT(new);
273 return (LttvAttribute *)new;
274}
275
dc877563 276gboolean
277lttv_attribute_find(LttvAttribute *self, LttvAttributeName name,
278 LttvAttributeType t, LttvAttributeValue *v)
f32847a1 279{
43ed82b5 280 unsigned int i;
f32847a1 281
dc877563 282 Attribute *a;
f32847a1 283
43ed82b5 284 i = GPOINTER_TO_UINT(g_hash_table_lookup(self->names, GUINT_TO_POINTER(name)));
1d1df11d 285 if(likely(i != 0)) {
dc877563 286 a = &g_array_index(self->attributes, Attribute, i - 1);
1d1df11d 287 if(unlikely(a->type != t)) return FALSE;
ffd54a90 288 *v = address_of_value(t, &(a->value));
dc877563 289 return TRUE;
290 }
f32847a1 291
dc877563 292 *v = lttv_attribute_add(self, name, t);
293 return TRUE;
f32847a1 294}
295
c0cb4d12 296gboolean
297lttv_attribute_find_unnamed(LttvAttribute *self, LttvAttributeName name,
298 LttvAttributeType t, LttvAttributeValue *v)
299{
300 unsigned i;
301
302 Attribute *a;
303
43ed82b5 304 i = GPOINTER_TO_UINT(g_hash_table_lookup(self->names, GUINT_TO_POINTER(name)));
c0cb4d12 305 if(likely(i != 0)) {
306 a = &g_array_index(self->attributes, Attribute, i - 1);
307 if(unlikely(a->type != t)) return FALSE;
308 *v = address_of_value(t, &(a->value));
309 return TRUE;
310 }
311
312 *v = lttv_attribute_add_unnamed(self, name, t);
313 return TRUE;
314}
315
f32847a1 316
c47a6dc6 317/*void lttv_attribute_recursive_free(LttvAttribute *self)
b445142a 318{
319 int i, nb;
320
321 Attribute *a;
322
323 nb = self->attributes->len;
324
325 for(i = 0 ; i < nb ; i++) {
326 a = &g_array_index(self->attributes, Attribute, i);
327 if(a->type == LTTV_GOBJECT && LTTV_IS_ATTRIBUTE(a->value.dv_gobject)) {
328 lttv_attribute_recursive_free((LttvAttribute *)(a->value.dv_gobject));
329 }
330 }
331 g_object_unref(self);
c47a6dc6 332}*/
b445142a 333
334
335void lttv_attribute_recursive_add(LttvAttribute *dest, LttvAttribute *src)
336{
337 int i, nb;
338
339 Attribute *a;
340
341 LttvAttributeValue value;
8f318283 342 gboolean retval;
b445142a 343
344 nb = src->attributes->len;
345
346 for(i = 0 ; i < nb ; i++) {
347 a = &g_array_index(src->attributes, Attribute, i);
348 if(a->type == LTTV_GOBJECT && LTTV_IS_ATTRIBUTE(a->value.dv_gobject)) {
c0cb4d12 349 if(a->is_named)
350 lttv_attribute_recursive_add(
351 /*CHECK*/(LttvAttribute *)lttv_attribute_find_subdir(dest, a->name),
352 (LttvAttribute *)(a->value.dv_gobject));
353 else
354 lttv_attribute_recursive_add(
355 /*CHECK*/(LttvAttribute *)lttv_attribute_find_subdir_unnamed(
356 dest, a->name), (LttvAttribute *)(a->value.dv_gobject));
b445142a 357 }
358 else {
8f318283
BP
359 if(a->is_named) {
360 retval= lttv_attribute_find(dest, a->name, a->type, &value);
361 g_assert(retval);
362 }
363 else {
364 retval= lttv_attribute_find_unnamed(dest, a->name, a->type, &value);
365 g_assert(retval);
366 }
b445142a 367 switch(a->type) {
c47a6dc6 368 case LTTV_INT:
b445142a 369 *value.v_int += a->value.dv_int;
370 break;
371 case LTTV_UINT:
372 *value.v_uint += a->value.dv_uint;
373 break;
374 case LTTV_LONG:
375 *value.v_long += a->value.dv_long;
376 break;
377 case LTTV_ULONG:
378 *value.v_ulong += a->value.dv_ulong;
379 break;
380 case LTTV_FLOAT:
381 *value.v_float += a->value.dv_float;
382 break;
383 case LTTV_DOUBLE:
384 *value.v_double += a->value.dv_double;
385 break;
386 case LTTV_TIME:
308711e5 387 *value.v_time = ltt_time_add(*value.v_time, a->value.dv_time);
b445142a 388 break;
389 case LTTV_POINTER:
390 break;
391 case LTTV_STRING:
392 break;
393 case LTTV_GOBJECT:
394 break;
395 case LTTV_NONE:
396 break;
397 }
398 }
399 }
400}
401
402
f95bc830 403static void
404print_indent(FILE *fp, int pos)
405{
406 int i;
407
408 for(i = 0 ; i < pos ; i++) putc(' ', fp);
409}
410
411
412void
413lttv_attribute_write_xml(LttvAttribute *self, FILE *fp, int pos, int indent)
414{
415 int i, nb;
416
417 Attribute *a;
418
419 nb = self->attributes->len;
420
421 fprintf(fp,"<ATTRS>\n");
422 for(i = 0 ; i < nb ; i++) {
423 a = &g_array_index(self->attributes, Attribute, i);
424 print_indent(fp, pos);
5bf80c50 425 fprintf(fp, "<ATTR NAME=\"%s\" ", g_quark_to_string(a->name));
f95bc830 426 if(a->type == LTTV_GOBJECT && LTTV_IS_ATTRIBUTE(a->value.dv_gobject)) {
427 fprintf(fp, "TYPE=ATTRS>");
428 lttv_attribute_write_xml((LttvAttribute *)(a->value.dv_gobject), fp,
429 pos + indent, indent);
430 }
431 else {
432 switch(a->type) {
433 case LTTV_INT:
434 fprintf(fp, "TYPE=INT VALUE=%d/>\n", a->value.dv_int);
435 break;
436 case LTTV_UINT:
437 fprintf(fp, "TYPE=UINT VALUE=%u/>\n", a->value.dv_uint);
438 break;
439 case LTTV_LONG:
440 fprintf(fp, "TYPE=LONG VALUE=%ld/>\n", a->value.dv_long);
441 break;
442 case LTTV_ULONG:
443 fprintf(fp, "TYPE=ULONG VALUE=%lu/>\n", a->value.dv_ulong);
444 break;
445 case LTTV_FLOAT:
446 fprintf(fp, "TYPE=FLOAT VALUE=%f/>\n", a->value.dv_float);
447 break;
448 case LTTV_DOUBLE:
449 fprintf(fp, "TYPE=DOUBLE VALUE=%f/>\n", a->value.dv_double);
450 break;
451 case LTTV_TIME:
00e74b69 452 fprintf(fp, "TYPE=TIME SEC=%lu NSEC=%lu/>\n", a->value.dv_time.tv_sec,
f95bc830 453 a->value.dv_time.tv_nsec);
454 break;
455 case LTTV_POINTER:
456 fprintf(fp, "TYPE=POINTER VALUE=%p/>\n", a->value.dv_pointer);
457 break;
458 case LTTV_STRING:
459 fprintf(fp, "TYPE=STRING VALUE=\"%s\"/>\n", a->value.dv_string);
460 break;
461 case LTTV_GOBJECT:
462 fprintf(fp, "TYPE=GOBJECT VALUE=%p/>\n", a->value.dv_gobject);
463 break;
464 case LTTV_NONE:
465 fprintf(fp, "TYPE=NONE/>\n");
466 break;
467 }
468 }
469 }
470 print_indent(fp, pos);
471 fprintf(fp,"</ATTRS>\n");
472}
473
474
475void
476lttv_attribute_read_xml(LttvAttribute *self, FILE *fp)
477{
00e74b69 478 int res;
f95bc830 479
480 char buffer[256], type[10];
481
482 LttvAttributeName name;
483
484 LttvAttributeValue value;
485
486 LttvAttribute *subtree;
487
488 fscanf(fp,"<ATTRS>");
489 while(1) {
490 res = fscanf(fp, "<ATTR NAME=\"%256[^\"]\" TYPE=%10[^ >]", buffer, type);
491 g_assert(res == 2);
492 name = g_quark_from_string(buffer);
493 if(strcmp(type, "ATTRS") == 0) {
494 fscanf(fp, ">");
495 subtree = lttv_attribute_find_subdir(self, name);
496 lttv_attribute_read_xml(subtree, fp);
497 }
498 else if(strcmp(type, "INT") == 0) {
499 value = lttv_attribute_add(self, name, LTTV_INT);
500 res = fscanf(fp, " VALUE=%d/>", value.v_int);
501 g_assert(res == 1);
502 }
503 else if(strcmp(type, "UINT") == 0) {
504 value = lttv_attribute_add(self, name, LTTV_UINT);
505 res = fscanf(fp, " VALUE=%u/>", value.v_uint);
506 g_assert(res == 1);
507 }
508 else if(strcmp(type, "LONG") == 0) {
509 value = lttv_attribute_add(self, name, LTTV_LONG);
510 res = fscanf(fp, " VALUE=%ld/>", value.v_long);
511 g_assert(res == 1);
512 }
513 else if(strcmp(type, "ULONG") == 0) {
514 value = lttv_attribute_add(self, name, LTTV_ULONG);
515 res = fscanf(fp, " VALUE=%lu/>", value.v_ulong);
516 g_assert(res == 1);
517 }
518 else if(strcmp(type, "FLOAT") == 0) {
519 float d;
520 value = lttv_attribute_add(self, name, LTTV_FLOAT);
521 res = fscanf(fp, " VALUE=%f/>", &d);
522 *(value.v_float) = d;
523 g_assert(res == 1);
524 }
525 else if(strcmp(type, "DOUBLE") == 0) {
526 value = lttv_attribute_add(self, name, LTTV_DOUBLE);
00e74b69 527 res = fscanf(fp, " VALUE=%lf/>", value.v_double);
f95bc830 528 g_assert(res == 1);
529 }
530 else if(strcmp(type, "TIME") == 0) {
531 value = lttv_attribute_add(self, name, LTTV_TIME);
00e74b69 532 res = fscanf(fp, " SEC=%lu NSEC=%lu/>", &(value.v_time->tv_sec),
f95bc830 533 &(value.v_time->tv_nsec));
534 g_assert(res == 2);
535 }
536 else if(strcmp(type, "POINTER") == 0) {
537 value = lttv_attribute_add(self, name, LTTV_POINTER);
538 res = fscanf(fp, " VALUE=%p/>", value.v_pointer);
539 g_error("Cannot read a pointer");
540 }
541 else if(strcmp(type, "STRING") == 0) {
542 value = lttv_attribute_add(self, name, LTTV_STRING);
543 res = fscanf(fp, " VALUE=\"%256[^\"]\"/>", buffer);
544 *(value.v_string) = g_strdup(buffer);
545 g_assert(res == 1);
546 }
547 else if(strcmp(type, "GOBJECT") == 0) {
548 value = lttv_attribute_add(self, name, LTTV_GOBJECT);
549 res = fscanf(fp, " VALUE=%p/>", value.v_gobject);
550 g_error("Cannot read a pointer");
551 }
552 else if(strcmp(type, "NONE") == 0) {
553 value = lttv_attribute_add(self, name, LTTV_NONE);
554 fscanf(fp, "/>");
555 }
556 else g_error("Unknown type to read");
557 }
558 fscanf(fp,"</ATTRS>");
559}
560
3e67c985 561static LttvAttribute *
562new_attribute (LttvAttribute *self)
563{
564 return g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
565}
566
f95bc830 567
dc877563 568static void
569attribute_interface_init (gpointer g_iface, gpointer iface_data)
f32847a1 570{
dc877563 571 LttvIAttributeClass *klass = (LttvIAttributeClass *)g_iface;
f32847a1 572
3e67c985 573 klass->new_attribute = (LttvIAttribute* (*) (LttvIAttribute *self))
574 new_attribute;
575
dc877563 576 klass->get_number = (unsigned int (*) (LttvIAttribute *self))
577 lttv_attribute_get_number;
f32847a1 578
dc877563 579 klass->named = (gboolean (*) (LttvIAttribute *self, gboolean *homogeneous))
580 lttv_attribute_named;
f32847a1 581
dc877563 582 klass->get = (LttvAttributeType (*) (LttvIAttribute *self, unsigned i,
c0cb4d12 583 LttvAttributeName *name, LttvAttributeValue *v, gboolean *is_named))
584 lttv_attribute_get;
f32847a1 585
dc877563 586 klass->get_by_name = (LttvAttributeType (*) (LttvIAttribute *self,
587 LttvAttributeName name, LttvAttributeValue *v))
588 lttv_attribute_get_by_name;
f32847a1 589
dc877563 590 klass->add = (LttvAttributeValue (*) (LttvIAttribute *self,
591 LttvAttributeName name, LttvAttributeType t)) lttv_attribute_add;
f32847a1 592
c0cb4d12 593 klass->add_unnamed = (LttvAttributeValue (*) (LttvIAttribute *self,
594 LttvAttributeName name, LttvAttributeType t)) lttv_attribute_add_unnamed;
595
dc877563 596 klass->remove = (void (*) (LttvIAttribute *self, unsigned i))
597 lttv_attribute_remove;
f32847a1 598
dc877563 599 klass->remove_by_name = (void (*) (LttvIAttribute *self,
600 LttvAttributeName name)) lttv_attribute_remove_by_name;
f32847a1 601
b445142a 602 klass->find_subdir = (LttvIAttribute* (*) (LttvIAttribute *self,
603 LttvAttributeName name)) lttv_attribute_find_subdir;
5e2c04a2 604
c0cb4d12 605 klass->find_subdir = (LttvIAttribute* (*) (LttvIAttribute *self,
606 LttvAttributeName name)) lttv_attribute_find_subdir_unnamed;
f32847a1 607}
608
dc877563 609static void
610attribute_instance_init (GTypeInstance *instance, gpointer g_class)
f32847a1 611{
dc877563 612 LttvAttribute *self = (LttvAttribute *)instance;
6843100a 613 self->names = g_hash_table_new(g_direct_hash,
614 g_direct_equal);
ffd54a90 615 self->attributes = g_array_new(FALSE, FALSE, sizeof(Attribute));
f32847a1 616}
617
f32847a1 618
dc877563 619static void
620attribute_finalize (LttvAttribute *self)
f32847a1 621{
4d39be09 622 guint i;
2a2fa4f0 623 g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "attribute_finalize()");
4d39be09 624
625 for(i=0;i<self->attributes->len;i++) {
626 lttv_attribute_remove(self, i);
627 }
628
629 g_hash_table_destroy(self->names);
dc877563 630 g_array_free(self->attributes, TRUE);
f32847a1 631}
632
f32847a1 633
dc877563 634static void
635attribute_class_init (LttvAttributeClass *klass)
f32847a1 636{
dc877563 637 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
3e67c985 638
ffd54a90 639 gobject_class->finalize = (void (*)(GObject *self))attribute_finalize;
f32847a1 640}
641
ffd54a90 642GType
643lttv_attribute_get_type (void)
644{
645 static GType type = 0;
646 if (type == 0) {
647 static const GTypeInfo info = {
648 sizeof (LttvAttributeClass),
649 NULL, /* base_init */
650 NULL, /* base_finalize */
651 (GClassInitFunc) attribute_class_init, /* class_init */
652 NULL, /* class_finalize */
653 NULL, /* class_data */
654 sizeof (LttvAttribute),
655 0, /* n_preallocs */
00e74b69 656 (GInstanceInitFunc) attribute_instance_init, /* instance_init */
657 NULL /* value handling */
ffd54a90 658 };
659
660 static const GInterfaceInfo iattribute_info = {
661 (GInterfaceInitFunc) attribute_interface_init, /* interface_init */
662 NULL, /* interface_finalize */
663 NULL /* interface_data */
664 };
665
666 type = g_type_register_static (G_TYPE_OBJECT, "LttvAttributeType", &info,
667 0);
668 g_type_add_interface_static (type, LTTV_IATTRIBUTE_TYPE, &iattribute_info);
669 }
670 return type;
671}
672
673
This page took 0.095155 seconds and 4 git commands to generate.