update compat
[lttv.git] / tags / LinuxTraceToolkitViewer-0.10.0-pre-115102007 / 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{
145 unsigned i;
f32847a1 146
dc877563 147 Attribute a, *pa;
f32847a1 148
ffd54a90 149 i = (unsigned)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{
168 unsigned i;
169
170 Attribute a, *pa;
171
172 i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name));
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{
218 unsigned i;
f32847a1 219
ffd54a90 220 i = (unsigned)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{
dc877563 234 unsigned i;
f32847a1 235
dc877563 236 Attribute a;
f32847a1 237
dc877563 238 LttvAttribute *new;
a43d67ba 239
ffd54a90 240 i = (unsigned)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{
256 unsigned i;
257
258 Attribute a;
259
260 LttvAttribute *new;
261
262 i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name));
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{
dc877563 280 unsigned i;
f32847a1 281
dc877563 282 Attribute *a;
f32847a1 283
ffd54a90 284 i = (unsigned)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
304 i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name));
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;
342
343 nb = src->attributes->len;
344
345 for(i = 0 ; i < nb ; i++) {
346 a = &g_array_index(src->attributes, Attribute, i);
347 if(a->type == LTTV_GOBJECT && LTTV_IS_ATTRIBUTE(a->value.dv_gobject)) {
c0cb4d12 348 if(a->is_named)
349 lttv_attribute_recursive_add(
350 /*CHECK*/(LttvAttribute *)lttv_attribute_find_subdir(dest, a->name),
351 (LttvAttribute *)(a->value.dv_gobject));
352 else
353 lttv_attribute_recursive_add(
354 /*CHECK*/(LttvAttribute *)lttv_attribute_find_subdir_unnamed(
355 dest, a->name), (LttvAttribute *)(a->value.dv_gobject));
b445142a 356 }
357 else {
c0cb4d12 358 if(a->is_named)
359 g_assert(lttv_attribute_find(dest, a->name, a->type, &value));
360 else
361 g_assert(lttv_attribute_find_unnamed(dest, a->name, a->type, &value));
b445142a 362 switch(a->type) {
c47a6dc6 363 case LTTV_INT:
b445142a 364 *value.v_int += a->value.dv_int;
365 break;
366 case LTTV_UINT:
367 *value.v_uint += a->value.dv_uint;
368 break;
369 case LTTV_LONG:
370 *value.v_long += a->value.dv_long;
371 break;
372 case LTTV_ULONG:
373 *value.v_ulong += a->value.dv_ulong;
374 break;
375 case LTTV_FLOAT:
376 *value.v_float += a->value.dv_float;
377 break;
378 case LTTV_DOUBLE:
379 *value.v_double += a->value.dv_double;
380 break;
381 case LTTV_TIME:
308711e5 382 *value.v_time = ltt_time_add(*value.v_time, a->value.dv_time);
b445142a 383 break;
384 case LTTV_POINTER:
385 break;
386 case LTTV_STRING:
387 break;
388 case LTTV_GOBJECT:
389 break;
390 case LTTV_NONE:
391 break;
392 }
393 }
394 }
395}
396
397
f95bc830 398static void
399print_indent(FILE *fp, int pos)
400{
401 int i;
402
403 for(i = 0 ; i < pos ; i++) putc(' ', fp);
404}
405
406
407void
408lttv_attribute_write_xml(LttvAttribute *self, FILE *fp, int pos, int indent)
409{
410 int i, nb;
411
412 Attribute *a;
413
414 nb = self->attributes->len;
415
416 fprintf(fp,"<ATTRS>\n");
417 for(i = 0 ; i < nb ; i++) {
418 a = &g_array_index(self->attributes, Attribute, i);
419 print_indent(fp, pos);
5bf80c50 420 fprintf(fp, "<ATTR NAME=\"%s\" ", g_quark_to_string(a->name));
f95bc830 421 if(a->type == LTTV_GOBJECT && LTTV_IS_ATTRIBUTE(a->value.dv_gobject)) {
422 fprintf(fp, "TYPE=ATTRS>");
423 lttv_attribute_write_xml((LttvAttribute *)(a->value.dv_gobject), fp,
424 pos + indent, indent);
425 }
426 else {
427 switch(a->type) {
428 case LTTV_INT:
429 fprintf(fp, "TYPE=INT VALUE=%d/>\n", a->value.dv_int);
430 break;
431 case LTTV_UINT:
432 fprintf(fp, "TYPE=UINT VALUE=%u/>\n", a->value.dv_uint);
433 break;
434 case LTTV_LONG:
435 fprintf(fp, "TYPE=LONG VALUE=%ld/>\n", a->value.dv_long);
436 break;
437 case LTTV_ULONG:
438 fprintf(fp, "TYPE=ULONG VALUE=%lu/>\n", a->value.dv_ulong);
439 break;
440 case LTTV_FLOAT:
441 fprintf(fp, "TYPE=FLOAT VALUE=%f/>\n", a->value.dv_float);
442 break;
443 case LTTV_DOUBLE:
444 fprintf(fp, "TYPE=DOUBLE VALUE=%f/>\n", a->value.dv_double);
445 break;
446 case LTTV_TIME:
00e74b69 447 fprintf(fp, "TYPE=TIME SEC=%lu NSEC=%lu/>\n", a->value.dv_time.tv_sec,
f95bc830 448 a->value.dv_time.tv_nsec);
449 break;
450 case LTTV_POINTER:
451 fprintf(fp, "TYPE=POINTER VALUE=%p/>\n", a->value.dv_pointer);
452 break;
453 case LTTV_STRING:
454 fprintf(fp, "TYPE=STRING VALUE=\"%s\"/>\n", a->value.dv_string);
455 break;
456 case LTTV_GOBJECT:
457 fprintf(fp, "TYPE=GOBJECT VALUE=%p/>\n", a->value.dv_gobject);
458 break;
459 case LTTV_NONE:
460 fprintf(fp, "TYPE=NONE/>\n");
461 break;
462 }
463 }
464 }
465 print_indent(fp, pos);
466 fprintf(fp,"</ATTRS>\n");
467}
468
469
470void
471lttv_attribute_read_xml(LttvAttribute *self, FILE *fp)
472{
00e74b69 473 int res;
f95bc830 474
475 char buffer[256], type[10];
476
477 LttvAttributeName name;
478
479 LttvAttributeValue value;
480
481 LttvAttribute *subtree;
482
483 fscanf(fp,"<ATTRS>");
484 while(1) {
485 res = fscanf(fp, "<ATTR NAME=\"%256[^\"]\" TYPE=%10[^ >]", buffer, type);
486 g_assert(res == 2);
487 name = g_quark_from_string(buffer);
488 if(strcmp(type, "ATTRS") == 0) {
489 fscanf(fp, ">");
490 subtree = lttv_attribute_find_subdir(self, name);
491 lttv_attribute_read_xml(subtree, fp);
492 }
493 else if(strcmp(type, "INT") == 0) {
494 value = lttv_attribute_add(self, name, LTTV_INT);
495 res = fscanf(fp, " VALUE=%d/>", value.v_int);
496 g_assert(res == 1);
497 }
498 else if(strcmp(type, "UINT") == 0) {
499 value = lttv_attribute_add(self, name, LTTV_UINT);
500 res = fscanf(fp, " VALUE=%u/>", value.v_uint);
501 g_assert(res == 1);
502 }
503 else if(strcmp(type, "LONG") == 0) {
504 value = lttv_attribute_add(self, name, LTTV_LONG);
505 res = fscanf(fp, " VALUE=%ld/>", value.v_long);
506 g_assert(res == 1);
507 }
508 else if(strcmp(type, "ULONG") == 0) {
509 value = lttv_attribute_add(self, name, LTTV_ULONG);
510 res = fscanf(fp, " VALUE=%lu/>", value.v_ulong);
511 g_assert(res == 1);
512 }
513 else if(strcmp(type, "FLOAT") == 0) {
514 float d;
515 value = lttv_attribute_add(self, name, LTTV_FLOAT);
516 res = fscanf(fp, " VALUE=%f/>", &d);
517 *(value.v_float) = d;
518 g_assert(res == 1);
519 }
520 else if(strcmp(type, "DOUBLE") == 0) {
521 value = lttv_attribute_add(self, name, LTTV_DOUBLE);
00e74b69 522 res = fscanf(fp, " VALUE=%lf/>", value.v_double);
f95bc830 523 g_assert(res == 1);
524 }
525 else if(strcmp(type, "TIME") == 0) {
526 value = lttv_attribute_add(self, name, LTTV_TIME);
00e74b69 527 res = fscanf(fp, " SEC=%lu NSEC=%lu/>", &(value.v_time->tv_sec),
f95bc830 528 &(value.v_time->tv_nsec));
529 g_assert(res == 2);
530 }
531 else if(strcmp(type, "POINTER") == 0) {
532 value = lttv_attribute_add(self, name, LTTV_POINTER);
533 res = fscanf(fp, " VALUE=%p/>", value.v_pointer);
534 g_error("Cannot read a pointer");
535 }
536 else if(strcmp(type, "STRING") == 0) {
537 value = lttv_attribute_add(self, name, LTTV_STRING);
538 res = fscanf(fp, " VALUE=\"%256[^\"]\"/>", buffer);
539 *(value.v_string) = g_strdup(buffer);
540 g_assert(res == 1);
541 }
542 else if(strcmp(type, "GOBJECT") == 0) {
543 value = lttv_attribute_add(self, name, LTTV_GOBJECT);
544 res = fscanf(fp, " VALUE=%p/>", value.v_gobject);
545 g_error("Cannot read a pointer");
546 }
547 else if(strcmp(type, "NONE") == 0) {
548 value = lttv_attribute_add(self, name, LTTV_NONE);
549 fscanf(fp, "/>");
550 }
551 else g_error("Unknown type to read");
552 }
553 fscanf(fp,"</ATTRS>");
554}
555
3e67c985 556static LttvAttribute *
557new_attribute (LttvAttribute *self)
558{
559 return g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
560}
561
f95bc830 562
dc877563 563static void
564attribute_interface_init (gpointer g_iface, gpointer iface_data)
f32847a1 565{
dc877563 566 LttvIAttributeClass *klass = (LttvIAttributeClass *)g_iface;
f32847a1 567
3e67c985 568 klass->new_attribute = (LttvIAttribute* (*) (LttvIAttribute *self))
569 new_attribute;
570
dc877563 571 klass->get_number = (unsigned int (*) (LttvIAttribute *self))
572 lttv_attribute_get_number;
f32847a1 573
dc877563 574 klass->named = (gboolean (*) (LttvIAttribute *self, gboolean *homogeneous))
575 lttv_attribute_named;
f32847a1 576
dc877563 577 klass->get = (LttvAttributeType (*) (LttvIAttribute *self, unsigned i,
c0cb4d12 578 LttvAttributeName *name, LttvAttributeValue *v, gboolean *is_named))
579 lttv_attribute_get;
f32847a1 580
dc877563 581 klass->get_by_name = (LttvAttributeType (*) (LttvIAttribute *self,
582 LttvAttributeName name, LttvAttributeValue *v))
583 lttv_attribute_get_by_name;
f32847a1 584
dc877563 585 klass->add = (LttvAttributeValue (*) (LttvIAttribute *self,
586 LttvAttributeName name, LttvAttributeType t)) lttv_attribute_add;
f32847a1 587
c0cb4d12 588 klass->add_unnamed = (LttvAttributeValue (*) (LttvIAttribute *self,
589 LttvAttributeName name, LttvAttributeType t)) lttv_attribute_add_unnamed;
590
dc877563 591 klass->remove = (void (*) (LttvIAttribute *self, unsigned i))
592 lttv_attribute_remove;
f32847a1 593
dc877563 594 klass->remove_by_name = (void (*) (LttvIAttribute *self,
595 LttvAttributeName name)) lttv_attribute_remove_by_name;
f32847a1 596
b445142a 597 klass->find_subdir = (LttvIAttribute* (*) (LttvIAttribute *self,
598 LttvAttributeName name)) lttv_attribute_find_subdir;
5e2c04a2 599
c0cb4d12 600 klass->find_subdir = (LttvIAttribute* (*) (LttvIAttribute *self,
601 LttvAttributeName name)) lttv_attribute_find_subdir_unnamed;
f32847a1 602}
603
dc877563 604static void
605attribute_instance_init (GTypeInstance *instance, gpointer g_class)
f32847a1 606{
dc877563 607 LttvAttribute *self = (LttvAttribute *)instance;
6843100a 608 self->names = g_hash_table_new(g_direct_hash,
609 g_direct_equal);
ffd54a90 610 self->attributes = g_array_new(FALSE, FALSE, sizeof(Attribute));
f32847a1 611}
612
f32847a1 613
dc877563 614static void
615attribute_finalize (LttvAttribute *self)
f32847a1 616{
4d39be09 617 guint i;
2a2fa4f0 618 g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "attribute_finalize()");
4d39be09 619
620 for(i=0;i<self->attributes->len;i++) {
621 lttv_attribute_remove(self, i);
622 }
623
624 g_hash_table_destroy(self->names);
dc877563 625 g_array_free(self->attributes, TRUE);
f32847a1 626}
627
f32847a1 628
dc877563 629static void
630attribute_class_init (LttvAttributeClass *klass)
f32847a1 631{
dc877563 632 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
3e67c985 633
ffd54a90 634 gobject_class->finalize = (void (*)(GObject *self))attribute_finalize;
f32847a1 635}
636
ffd54a90 637GType
638lttv_attribute_get_type (void)
639{
640 static GType type = 0;
641 if (type == 0) {
642 static const GTypeInfo info = {
643 sizeof (LttvAttributeClass),
644 NULL, /* base_init */
645 NULL, /* base_finalize */
646 (GClassInitFunc) attribute_class_init, /* class_init */
647 NULL, /* class_finalize */
648 NULL, /* class_data */
649 sizeof (LttvAttribute),
650 0, /* n_preallocs */
00e74b69 651 (GInstanceInitFunc) attribute_instance_init, /* instance_init */
652 NULL /* value handling */
ffd54a90 653 };
654
655 static const GInterfaceInfo iattribute_info = {
656 (GInterfaceInitFunc) attribute_interface_init, /* interface_init */
657 NULL, /* interface_finalize */
658 NULL /* interface_data */
659 };
660
661 type = g_type_register_static (G_TYPE_OBJECT, "LttvAttributeType", &info,
662 0);
663 g_type_add_interface_static (type, LTTV_IATTRIBUTE_TYPE, &iattribute_info);
664 }
665 return type;
666}
667
668
This page took 0.085093 seconds and 4 git commands to generate.