Fix format-security warnings when building with trace-sync
[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
bdddf3f5
AM
490 res = fscanf(fp, "<ATTRS>");
491 g_assert(res > 0);
90e19f82
AM
492 while(1) {
493 res = fscanf(fp, "<ATTR NAME=\"%256[^\"]\" TYPE=%10[^ >]", buffer, type);
494 g_assert(res == 2);
495 name = g_quark_from_string(buffer);
496 if(strcmp(type, "ATTRS") == 0) {
bdddf3f5
AM
497 res = fscanf(fp, ">");
498 g_assert(res > 0);
90e19f82
AM
499 subtree = lttv_attribute_find_subdir(self, name);
500 lttv_attribute_read_xml(subtree, fp);
501 }
502 else if(strcmp(type, "INT") == 0) {
503 value = lttv_attribute_add(self, name, LTTV_INT);
504 res = fscanf(fp, " VALUE=%d/>", value.v_int);
505 g_assert(res == 1);
506 }
507 else if(strcmp(type, "UINT") == 0) {
508 value = lttv_attribute_add(self, name, LTTV_UINT);
509 res = fscanf(fp, " VALUE=%u/>", value.v_uint);
510 g_assert(res == 1);
511 }
512 else if(strcmp(type, "LONG") == 0) {
513 value = lttv_attribute_add(self, name, LTTV_LONG);
514 res = fscanf(fp, " VALUE=%ld/>", value.v_long);
515 g_assert(res == 1);
516 }
517 else if(strcmp(type, "ULONG") == 0) {
518 value = lttv_attribute_add(self, name, LTTV_ULONG);
519 res = fscanf(fp, " VALUE=%lu/>", value.v_ulong);
520 g_assert(res == 1);
521 }
522 else if(strcmp(type, "FLOAT") == 0) {
523 float d;
524 value = lttv_attribute_add(self, name, LTTV_FLOAT);
525 res = fscanf(fp, " VALUE=%f/>", &d);
526 *(value.v_float) = d;
527 g_assert(res == 1);
528 }
529 else if(strcmp(type, "DOUBLE") == 0) {
530 value = lttv_attribute_add(self, name, LTTV_DOUBLE);
531 res = fscanf(fp, " VALUE=%lf/>", value.v_double);
532 g_assert(res == 1);
533 }
534 else if(strcmp(type, "TIME") == 0) {
535 value = lttv_attribute_add(self, name, LTTV_TIME);
536 res = fscanf(fp, " SEC=%lu NSEC=%lu/>", &(value.v_time->tv_sec),
537 &(value.v_time->tv_nsec));
538 g_assert(res == 2);
539 }
540 else if(strcmp(type, "POINTER") == 0) {
541 value = lttv_attribute_add(self, name, LTTV_POINTER);
542 res = fscanf(fp, " VALUE=%p/>", value.v_pointer);
543 g_error("Cannot read a pointer");
544 }
545 else if(strcmp(type, "STRING") == 0) {
546 value = lttv_attribute_add(self, name, LTTV_STRING);
547 res = fscanf(fp, " VALUE=\"%256[^\"]\"/>", buffer);
548 *(value.v_string) = g_strdup(buffer);
549 g_assert(res == 1);
550 }
551 else if(strcmp(type, "GOBJECT") == 0) {
552 value = lttv_attribute_add(self, name, LTTV_GOBJECT);
553 res = fscanf(fp, " VALUE=%p/>", value.v_gobject);
554 g_error("Cannot read a pointer");
555 }
556 else if(strcmp(type, "NONE") == 0) {
557 value = lttv_attribute_add(self, name, LTTV_NONE);
bdddf3f5
AM
558 res = fscanf(fp, "/>");
559 g_assert(res > 0);
90e19f82
AM
560 }
561 else g_error("Unknown type to read");
562 }
bdddf3f5
AM
563 res = fscanf(fp, "</ATTRS>");
564 g_assert(res > 0);
f95bc830 565}
566
3e67c985 567static LttvAttribute *
568new_attribute (LttvAttribute *self)
569{
90e19f82 570 return g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
3e67c985 571}
572
f95bc830 573
dc877563 574static void
575attribute_interface_init (gpointer g_iface, gpointer iface_data)
f32847a1 576{
90e19f82 577 LttvIAttributeClass *klass = (LttvIAttributeClass *)g_iface;
f32847a1 578
90e19f82
AM
579 klass->new_attribute = (LttvIAttribute* (*) (LttvIAttribute *self))
580 new_attribute;
3e67c985 581
90e19f82
AM
582 klass->get_number = (unsigned int (*) (LttvIAttribute *self))
583 lttv_attribute_get_number;
f32847a1 584
90e19f82
AM
585 klass->named = (gboolean (*) (LttvIAttribute *self, gboolean *homogeneous))
586 lttv_attribute_named;
f32847a1 587
90e19f82
AM
588 klass->get = (LttvAttributeType (*) (LttvIAttribute *self, unsigned i,
589 LttvAttributeName *name, LttvAttributeValue *v, gboolean *is_named))
c0cb4d12 590 lttv_attribute_get;
f32847a1 591
90e19f82
AM
592 klass->get_by_name = (LttvAttributeType (*) (LttvIAttribute *self,
593 LttvAttributeName name, LttvAttributeValue *v))
594 lttv_attribute_get_by_name;
f32847a1 595
90e19f82
AM
596 klass->add = (LttvAttributeValue (*) (LttvIAttribute *self,
597 LttvAttributeName name, LttvAttributeType t)) lttv_attribute_add;
f32847a1 598
90e19f82
AM
599 klass->add_unnamed = (LttvAttributeValue (*) (LttvIAttribute *self,
600 LttvAttributeName name, LttvAttributeType t)) lttv_attribute_add_unnamed;
c0cb4d12 601
90e19f82
AM
602 klass->remove = (void (*) (LttvIAttribute *self, unsigned i))
603 lttv_attribute_remove;
f32847a1 604
90e19f82
AM
605 klass->remove_by_name = (void (*) (LttvIAttribute *self,
606 LttvAttributeName name)) lttv_attribute_remove_by_name;
f32847a1 607
90e19f82
AM
608 klass->find_subdir = (LttvIAttribute* (*) (LttvIAttribute *self,
609 LttvAttributeName name)) lttv_attribute_find_subdir;
5e2c04a2 610
90e19f82
AM
611 klass->find_subdir = (LttvIAttribute* (*) (LttvIAttribute *self,
612 LttvAttributeName name)) lttv_attribute_find_subdir_unnamed;
f32847a1 613}
614
dc877563 615static void
616attribute_instance_init (GTypeInstance *instance, gpointer g_class)
f32847a1 617{
90e19f82
AM
618 LttvAttribute *self = (LttvAttribute *)instance;
619 self->names = g_hash_table_new(g_direct_hash,
620 g_direct_equal);
621 self->attributes = g_array_new(FALSE, FALSE, sizeof(Attribute));
f32847a1 622}
623
f32847a1 624
dc877563 625static void
626attribute_finalize (LttvAttribute *self)
f32847a1 627{
90e19f82
AM
628 guint i;
629 g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "attribute_finalize()");
630
631 for(i=0;i<self->attributes->len;i++) {
632 lttv_attribute_remove(self, i);
633 }
634
635 g_hash_table_destroy(self->names);
636 g_array_free(self->attributes, TRUE);
f32847a1 637}
638
f32847a1 639
dc877563 640static void
641attribute_class_init (LttvAttributeClass *klass)
f32847a1 642{
90e19f82
AM
643 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
644
645 gobject_class->finalize = (void (*)(GObject *self))attribute_finalize;
f32847a1 646}
647
ffd54a90 648GType
649lttv_attribute_get_type (void)
650{
90e19f82
AM
651 static GType type = 0;
652 if (type == 0) {
653 static const GTypeInfo info = {
654 sizeof (LttvAttributeClass),
655 NULL, /* base_init */
656 NULL, /* base_finalize */
657 (GClassInitFunc) attribute_class_init, /* class_init */
658 NULL, /* class_finalize */
659 NULL, /* class_data */
660 sizeof (LttvAttribute),
661 0, /* n_preallocs */
662 (GInstanceInitFunc) attribute_instance_init, /* instance_init */
663 NULL /* value handling */
664 };
665
666 static const GInterfaceInfo iattribute_info = {
667 (GInterfaceInitFunc) attribute_interface_init, /* interface_init */
668 NULL, /* interface_finalize */
669 NULL /* interface_data */
670 };
671
672 type = g_type_register_static (G_TYPE_OBJECT, "LttvAttributeType", &info,
673 0);
674 g_type_add_interface_static (type, LTTV_IATTRIBUTE_TYPE, &iattribute_info);
675 }
676 return type;
ffd54a90 677}
678
679
This page took 0.244392 seconds and 4 git commands to generate.