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