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