Fix: Return a variant's alignment as 0 (undefined).
[babeltrace.git] / lib / objects.c
CommitLineData
347829f5
PP
1/*
2 * objects.c: basic object system
3 *
4 * Babeltrace Library
5 *
6 * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation
7 * Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com>
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * SOFTWARE.
26 */
27
28#include <stdlib.h>
29#include <string.h>
30#include <assert.h>
31#include <string.h>
32#include <babeltrace/ctf-writer/ref-internal.h>
33#include <babeltrace/compiler.h>
34#include <glib.h>
35#include <babeltrace/objects.h>
36
37#define BT_OBJECT_FROM_CONCRETE(_concrete) ((struct bt_object *) (_concrete))
38#define BT_OBJECT_TO_BOOL(_base) ((struct bt_object_bool *) (_base))
39#define BT_OBJECT_TO_INTEGER(_base) ((struct bt_object_integer *) (_base))
40#define BT_OBJECT_TO_FLOAT(_base) ((struct bt_object_float *) (_base))
41#define BT_OBJECT_TO_STRING(_base) ((struct bt_object_string *) (_base))
42#define BT_OBJECT_TO_ARRAY(_base) ((struct bt_object_array *) (_base))
43#define BT_OBJECT_TO_MAP(_base) ((struct bt_object_map *) (_base))
44
45struct bt_object {
46 enum bt_object_type type;
47 struct bt_ctf_ref ref_count;
a40a567e 48 bool is_frozen;
347829f5
PP
49};
50
51static
52struct bt_object bt_object_null_instance = {
53 .type = BT_OBJECT_TYPE_NULL,
a40a567e 54 .is_frozen = true,
347829f5
PP
55};
56
57struct bt_object *bt_object_null = &bt_object_null_instance;
58
59struct bt_object_bool {
60 struct bt_object base;
61 bool value;
62};
63
64struct bt_object_integer {
65 struct bt_object base;
66 int64_t value;
67};
68
69struct bt_object_float {
70 struct bt_object base;
71 double value;
72};
73
74struct bt_object_string {
75 struct bt_object base;
76 GString *gstr;
77};
78
79struct bt_object_array {
80 struct bt_object base;
a22a5f1b 81 GPtrArray *garray;
347829f5
PP
82};
83
84struct bt_object_map {
85 struct bt_object base;
86 GHashTable *ght;
87};
88
89static
90void bt_object_string_destroy(struct bt_object *object)
91{
e196f486 92 g_string_free(BT_OBJECT_TO_STRING(object)->gstr, TRUE);
347829f5
PP
93}
94
95static
96void bt_object_array_destroy(struct bt_object *object)
97{
a22a5f1b
PP
98 /*
99 * Pointer array's registered value destructor will take care
100 * of putting each contained object.
101 */
102 g_ptr_array_free(BT_OBJECT_TO_ARRAY(object)->garray, TRUE);
347829f5
PP
103}
104
105static
106void bt_object_map_destroy(struct bt_object *object)
107{
347829f5
PP
108 /*
109 * Hash table's registered value destructor will take care of
110 * putting each contained object. Keys are GQuarks and cannot
111 * be destroyed anyway.
112 */
e196f486 113 g_hash_table_destroy(BT_OBJECT_TO_MAP(object)->ght);
347829f5
PP
114}
115
116static
117void (* const destroy_funcs[])(struct bt_object *) = {
118 [BT_OBJECT_TYPE_NULL] = NULL,
119 [BT_OBJECT_TYPE_BOOL] = NULL,
120 [BT_OBJECT_TYPE_INTEGER] = NULL,
121 [BT_OBJECT_TYPE_FLOAT] = NULL,
122 [BT_OBJECT_TYPE_STRING] = bt_object_string_destroy,
123 [BT_OBJECT_TYPE_ARRAY] = bt_object_array_destroy,
124 [BT_OBJECT_TYPE_MAP] = bt_object_map_destroy,
125};
126
127static
128struct bt_object *bt_object_null_copy(const struct bt_object *null_obj)
129{
130 return bt_object_null;
131}
132
133static
134struct bt_object *bt_object_bool_copy(const struct bt_object *bool_obj)
135{
136 return bt_object_bool_create_init(BT_OBJECT_TO_BOOL(bool_obj)->value);
137}
138
139static
140struct bt_object *bt_object_integer_copy(const struct bt_object *integer_obj)
141{
142 return bt_object_integer_create_init(
143 BT_OBJECT_TO_INTEGER(integer_obj)->value);
144}
145
146static
147struct bt_object *bt_object_float_copy(const struct bt_object *float_obj)
148{
149 return bt_object_float_create_init(
150 BT_OBJECT_TO_FLOAT(float_obj)->value);
151}
152
153static
154struct bt_object *bt_object_string_copy(const struct bt_object *string_obj)
155{
156 return bt_object_string_create_init(
157 BT_OBJECT_TO_STRING(string_obj)->gstr->str);
158}
159
160static
161struct bt_object *bt_object_array_copy(const struct bt_object *array_obj)
162{
8da980bd 163 int i;
347829f5
PP
164 int ret;
165 struct bt_object *copy_obj;
166 struct bt_object_array *typed_array_obj;
167
168 typed_array_obj = BT_OBJECT_TO_ARRAY(array_obj);
169 copy_obj = bt_object_array_create();
170
171 if (!copy_obj) {
172 goto end;
173 }
174
8da980bd 175 for (i = 0; i < typed_array_obj->garray->len; ++i) {
347829f5
PP
176 struct bt_object *element_obj_copy;
177 struct bt_object *element_obj =
8da980bd 178 bt_object_array_get(array_obj, i);
347829f5
PP
179
180 if (!element_obj) {
181 BT_OBJECT_PUT(copy_obj);
182 goto end;
183 }
184
185 element_obj_copy = bt_object_copy(element_obj);
186 BT_OBJECT_PUT(element_obj);
187
188 if (!element_obj_copy) {
189 BT_OBJECT_PUT(copy_obj);
190 goto end;
191 }
192
193 ret = bt_object_array_append(copy_obj, element_obj_copy);
194 BT_OBJECT_PUT(element_obj_copy);
195
196 if (ret) {
197 BT_OBJECT_PUT(copy_obj);
198 goto end;
199 }
200 }
201
202end:
203 return copy_obj;
204}
205
206static
207struct bt_object *bt_object_map_copy(const struct bt_object *map_obj)
208{
209 int ret;
210 GHashTableIter iter;
211 gpointer key, element_obj;
212 struct bt_object *copy_obj;
213 struct bt_object *element_obj_copy;
214 struct bt_object_map *typed_map_obj;
215
216 typed_map_obj = BT_OBJECT_TO_MAP(map_obj);
217 copy_obj = bt_object_map_create();
218
219 if (!copy_obj) {
220 goto end;
221 }
222
223 g_hash_table_iter_init(&iter, typed_map_obj->ght);
224
225 while (g_hash_table_iter_next(&iter, &key, &element_obj)) {
226 const char *key_str = g_quark_to_string((unsigned long) key);
227
228 element_obj_copy = bt_object_copy(element_obj);
229
230 if (!element_obj_copy) {
231 BT_OBJECT_PUT(copy_obj);
232 goto end;
233 }
234
235 ret = bt_object_map_insert(copy_obj, key_str, element_obj_copy);
236 BT_OBJECT_PUT(element_obj_copy);
237
238 if (ret) {
239 BT_OBJECT_PUT(copy_obj);
240 goto end;
241 }
242 }
243
244end:
245 return copy_obj;
246}
247
248static
249struct bt_object *(* const copy_funcs[])(const struct bt_object *) = {
250 [BT_OBJECT_TYPE_NULL] = bt_object_null_copy,
251 [BT_OBJECT_TYPE_BOOL] = bt_object_bool_copy,
252 [BT_OBJECT_TYPE_INTEGER] = bt_object_integer_copy,
253 [BT_OBJECT_TYPE_FLOAT] = bt_object_float_copy,
254 [BT_OBJECT_TYPE_STRING] = bt_object_string_copy,
255 [BT_OBJECT_TYPE_ARRAY] = bt_object_array_copy,
256 [BT_OBJECT_TYPE_MAP] = bt_object_map_copy,
257};
258
259static
260bool bt_object_null_compare(const struct bt_object *object_a,
261 const struct bt_object *object_b)
262{
263 /*
264 * Always true since bt_object_compare() already checks if both
265 * object_a and object_b have the same type, and in the case of
266 * null objects, they're always the same if it is so.
267 */
268 return true;
269}
270
271static
272bool bt_object_bool_compare(const struct bt_object *object_a,
273 const struct bt_object *object_b)
274{
275 return BT_OBJECT_TO_BOOL(object_a)->value ==
276 BT_OBJECT_TO_BOOL(object_b)->value;
277}
278
279static
280bool bt_object_integer_compare(const struct bt_object *object_a,
281 const struct bt_object *object_b)
282{
283 return BT_OBJECT_TO_INTEGER(object_a)->value ==
284 BT_OBJECT_TO_INTEGER(object_b)->value;
285}
286
287static
288bool bt_object_float_compare(const struct bt_object *object_a,
289 const struct bt_object *object_b)
290{
291 return BT_OBJECT_TO_FLOAT(object_a)->value ==
292 BT_OBJECT_TO_FLOAT(object_b)->value;
293}
294
295static
296bool bt_object_string_compare(const struct bt_object *object_a,
297 const struct bt_object *object_b)
298{
299 return !strcmp(BT_OBJECT_TO_STRING(object_a)->gstr->str,
300 BT_OBJECT_TO_STRING(object_b)->gstr->str);
301}
302
303static
304bool bt_object_array_compare(const struct bt_object *object_a,
305 const struct bt_object *object_b)
306{
8da980bd 307 int i;
347829f5
PP
308 bool ret = true;
309 const struct bt_object_array *array_obj_a =
310 BT_OBJECT_TO_ARRAY(object_a);
311
312 if (bt_object_array_size(object_a) != bt_object_array_size(object_b)) {
313 ret = false;
314 goto end;
315 }
316
8da980bd 317 for (i = 0; i < array_obj_a->garray->len; ++i) {
347829f5
PP
318 struct bt_object *element_obj_a;
319 struct bt_object *element_obj_b;
320
8da980bd
PP
321 element_obj_a = bt_object_array_get(object_a, i);
322 element_obj_b = bt_object_array_get(object_b, i);
347829f5
PP
323
324 if (!bt_object_compare(element_obj_a, element_obj_b)) {
325 BT_OBJECT_PUT(element_obj_a);
326 BT_OBJECT_PUT(element_obj_b);
327 ret = false;
328 goto end;
329 }
330
331 BT_OBJECT_PUT(element_obj_a);
332 BT_OBJECT_PUT(element_obj_b);
333 }
334
335end:
336 return ret;
337}
338
339static
340bool bt_object_map_compare(const struct bt_object *object_a,
341 const struct bt_object *object_b)
342{
343 bool ret = true;
344 GHashTableIter iter;
345 gpointer key, element_obj_a;
346 const struct bt_object_map *map_obj_a = BT_OBJECT_TO_MAP(object_a);
347
348 if (bt_object_map_size(object_a) != bt_object_map_size(object_b)) {
349 ret = false;
350 goto end;
351 }
352
353 g_hash_table_iter_init(&iter, map_obj_a->ght);
354
355 while (g_hash_table_iter_next(&iter, &key, &element_obj_a)) {
356 struct bt_object *element_obj_b;
357 const char *key_str = g_quark_to_string((unsigned long) key);
358
359 element_obj_b = bt_object_map_get(object_b, key_str);
360
361 if (!bt_object_compare(element_obj_a, element_obj_b)) {
362 BT_OBJECT_PUT(element_obj_b);
363 ret = false;
364 goto end;
365 }
366
367 BT_OBJECT_PUT(element_obj_b);
368 }
369
370end:
371 return ret;
372}
373
374static
375bool (* const compare_funcs[])(const struct bt_object *,
376 const struct bt_object *) = {
377 [BT_OBJECT_TYPE_NULL] = bt_object_null_compare,
378 [BT_OBJECT_TYPE_BOOL] = bt_object_bool_compare,
379 [BT_OBJECT_TYPE_INTEGER] = bt_object_integer_compare,
380 [BT_OBJECT_TYPE_FLOAT] = bt_object_float_compare,
381 [BT_OBJECT_TYPE_STRING] = bt_object_string_compare,
382 [BT_OBJECT_TYPE_ARRAY] = bt_object_array_compare,
383 [BT_OBJECT_TYPE_MAP] = bt_object_map_compare,
384};
385
a40a567e
PP
386void bt_object_null_freeze(struct bt_object *object)
387{
388}
389
390void bt_object_generic_freeze(struct bt_object *object)
391{
392 object->is_frozen = true;
393}
394
395void bt_object_array_freeze(struct bt_object *object)
396{
8da980bd 397 int i;
a40a567e
PP
398 struct bt_object_array *typed_array_obj =
399 BT_OBJECT_TO_ARRAY(object);
400
8da980bd 401 for (i = 0; i < typed_array_obj->garray->len; ++i) {
a40a567e 402 struct bt_object *element_obj =
8da980bd 403 g_ptr_array_index(typed_array_obj->garray, i);
a40a567e
PP
404
405 bt_object_freeze(element_obj);
406 }
407
408 bt_object_generic_freeze(object);
409}
410
411void bt_object_map_freeze(struct bt_object *object)
412{
413 GHashTableIter iter;
414 gpointer key, element_obj;
415 const struct bt_object_map *map_obj = BT_OBJECT_TO_MAP(object);
416
417 g_hash_table_iter_init(&iter, map_obj->ght);
418
419 while (g_hash_table_iter_next(&iter, &key, &element_obj)) {
420 bt_object_freeze(element_obj);
421 }
422
423 bt_object_generic_freeze(object);
424}
425
426static
427void (* const freeze_funcs[])(struct bt_object *) = {
428 [BT_OBJECT_TYPE_NULL] = bt_object_null_freeze,
429 [BT_OBJECT_TYPE_BOOL] = bt_object_generic_freeze,
430 [BT_OBJECT_TYPE_INTEGER] = bt_object_generic_freeze,
431 [BT_OBJECT_TYPE_FLOAT] = bt_object_generic_freeze,
432 [BT_OBJECT_TYPE_STRING] = bt_object_generic_freeze,
433 [BT_OBJECT_TYPE_ARRAY] = bt_object_array_freeze,
434 [BT_OBJECT_TYPE_MAP] = bt_object_map_freeze,
435};
436
347829f5
PP
437static
438void bt_object_destroy(struct bt_ctf_ref *ref_count)
439{
440 struct bt_object *object;
441
442 object = container_of(ref_count, struct bt_object, ref_count);
443 assert(object->type != BT_OBJECT_TYPE_UNKNOWN);
444
445 if (bt_object_is_null(object)) {
446 return;
447 }
448
449 if (destroy_funcs[object->type]) {
450 destroy_funcs[object->type](object);
451 }
452
453 g_free(object);
454}
455
456void bt_object_get(struct bt_object *object)
457{
458 if (!object) {
459 goto skip;
460 }
461
462 bt_ctf_ref_get(&object->ref_count);
463
464skip:
465 return;
466}
467
468void bt_object_put(struct bt_object *object)
469{
470 if (!object) {
471 goto skip;
472 }
473
474 bt_ctf_ref_put(&object->ref_count, bt_object_destroy);
475
476skip:
477 return;
478}
479
a40a567e
PP
480enum bt_object_status bt_object_freeze(struct bt_object *object)
481{
482 enum bt_object_status ret = BT_OBJECT_STATUS_OK;
483
484 if (!object) {
485 ret = BT_OBJECT_STATUS_INVAL;
486 goto end;
487 }
488
489 freeze_funcs[object->type](object);
490
491end:
492 return ret;
493}
494
495bool bt_object_is_frozen(const struct bt_object *object)
496{
497 return object && object->is_frozen;
498}
499
347829f5
PP
500enum bt_object_type bt_object_get_type(const struct bt_object *object)
501{
502 if (!object) {
503 return BT_OBJECT_TYPE_UNKNOWN;
504 }
505
506 return object->type;
507}
508
509static
510struct bt_object bt_object_create_base(enum bt_object_type type)
511{
512 struct bt_object base;
513
514 base.type = type;
a40a567e 515 base.is_frozen = false;
347829f5
PP
516 bt_ctf_ref_init(&base.ref_count);
517
518 return base;
519}
520
521struct bt_object *bt_object_bool_create_init(bool val)
522{
523 struct bt_object_bool *bool_obj;
524
525 bool_obj = g_new0(struct bt_object_bool, 1);
526
527 if (!bool_obj) {
528 goto end;
529 }
530
531 bool_obj->base = bt_object_create_base(BT_OBJECT_TYPE_BOOL);
532 bool_obj->value = val;
533
534end:
535 return BT_OBJECT_FROM_CONCRETE(bool_obj);
536}
537
538struct bt_object *bt_object_bool_create(void)
539{
540 return bt_object_bool_create_init(false);
541}
542
543struct bt_object *bt_object_integer_create_init(int64_t val)
544{
545 struct bt_object_integer *integer_obj;
546
547 integer_obj = g_new0(struct bt_object_integer, 1);
548
549 if (!integer_obj) {
550 goto end;
551 }
552
553 integer_obj->base = bt_object_create_base(BT_OBJECT_TYPE_INTEGER);
554 integer_obj->value = val;
555
556end:
557 return BT_OBJECT_FROM_CONCRETE(integer_obj);
558}
559
560struct bt_object *bt_object_integer_create(void)
561{
562 return bt_object_integer_create_init(0);
563}
564
565struct bt_object *bt_object_float_create_init(double val)
566{
567 struct bt_object_float *float_obj;
568
569 float_obj = g_new0(struct bt_object_float, 1);
570
571 if (!float_obj) {
572 goto end;
573 }
574
575 float_obj->base = bt_object_create_base(BT_OBJECT_TYPE_FLOAT);
576 float_obj->value = val;
577
578end:
579 return BT_OBJECT_FROM_CONCRETE(float_obj);
580}
581
582struct bt_object *bt_object_float_create(void)
583{
584 return bt_object_float_create_init(0.);
585}
586
587struct bt_object *bt_object_string_create_init(const char *val)
588{
589 struct bt_object_string *string_obj = NULL;
590
591 if (!val) {
592 goto end;
593 }
594
595 string_obj = g_new0(struct bt_object_string, 1);
596
597 if (!string_obj) {
598 goto end;
599 }
600
601 string_obj->base = bt_object_create_base(BT_OBJECT_TYPE_STRING);
602 string_obj->gstr = g_string_new(val);
603
604 if (!string_obj->gstr) {
605 g_free(string_obj);
606 string_obj = NULL;
607 goto end;
608 }
609
610end:
611 return BT_OBJECT_FROM_CONCRETE(string_obj);
612}
613
614struct bt_object *bt_object_string_create(void)
615{
616 return bt_object_string_create_init("");
617}
618
619struct bt_object *bt_object_array_create(void)
620{
621 struct bt_object_array *array_obj;
622
623 array_obj = g_new0(struct bt_object_array, 1);
624
625 if (!array_obj) {
626 goto end;
627 }
628
629 array_obj->base = bt_object_create_base(BT_OBJECT_TYPE_ARRAY);
a22a5f1b
PP
630 array_obj->garray = g_ptr_array_new_full(0,
631 (GDestroyNotify) bt_object_put);
347829f5
PP
632
633 if (!array_obj->garray) {
634 g_free(array_obj);
635 array_obj = NULL;
636 goto end;
637 }
638
639end:
640 return BT_OBJECT_FROM_CONCRETE(array_obj);
641}
642
643struct bt_object *bt_object_map_create(void)
644{
645 struct bt_object_map *map_obj;
646
647 map_obj = g_new0(struct bt_object_map, 1);
648
649 if (!map_obj) {
650 goto end;
651 }
652
653 map_obj->base = bt_object_create_base(BT_OBJECT_TYPE_MAP);
654 map_obj->ght = g_hash_table_new_full(g_direct_hash, g_direct_equal,
655 NULL, (GDestroyNotify) bt_object_put);
656
657 if (!map_obj->ght) {
658 g_free(map_obj);
659 map_obj = NULL;
660 goto end;
661 }
662
663end:
664 return BT_OBJECT_FROM_CONCRETE(map_obj);
665}
666
a40a567e
PP
667enum bt_object_status bt_object_bool_get(const struct bt_object *bool_obj,
668 bool *val)
347829f5 669{
a40a567e 670 enum bt_object_status ret = BT_OBJECT_STATUS_OK;
347829f5
PP
671 struct bt_object_bool *typed_bool_obj = BT_OBJECT_TO_BOOL(bool_obj);
672
a40a567e
PP
673 if (!bool_obj || !bt_object_is_bool(bool_obj) || !val) {
674 ret = BT_OBJECT_STATUS_INVAL;
347829f5
PP
675 goto end;
676 }
677
678 *val = typed_bool_obj->value;
679
680end:
681 return ret;
682}
683
a40a567e 684enum bt_object_status bt_object_bool_set(struct bt_object *bool_obj, bool val)
347829f5 685{
a40a567e 686 enum bt_object_status ret = BT_OBJECT_STATUS_OK;
347829f5
PP
687 struct bt_object_bool *typed_bool_obj = BT_OBJECT_TO_BOOL(bool_obj);
688
689 if (!bool_obj || !bt_object_is_bool(bool_obj)) {
a40a567e
PP
690 ret = BT_OBJECT_STATUS_INVAL;
691 goto end;
692 }
693
694 if (bool_obj->is_frozen) {
695 ret = BT_OBJECT_STATUS_FROZEN;
347829f5
PP
696 goto end;
697 }
698
699 typed_bool_obj->value = val;
700
701end:
702 return ret;
703}
704
a40a567e
PP
705enum bt_object_status bt_object_integer_get(const struct bt_object *integer_obj,
706 int64_t *val)
347829f5 707{
a40a567e 708 enum bt_object_status ret = BT_OBJECT_STATUS_OK;
347829f5
PP
709 struct bt_object_integer *typed_integer_obj =
710 BT_OBJECT_TO_INTEGER(integer_obj);
711
a40a567e
PP
712 if (!integer_obj || !bt_object_is_integer(integer_obj) || !val) {
713 ret = BT_OBJECT_STATUS_INVAL;
347829f5
PP
714 goto end;
715 }
716
717 *val = typed_integer_obj->value;
718
719end:
720 return ret;
721}
722
a40a567e
PP
723enum bt_object_status bt_object_integer_set(struct bt_object *integer_obj,
724 int64_t val)
347829f5 725{
a40a567e 726 enum bt_object_status ret = BT_OBJECT_STATUS_OK;
347829f5
PP
727 struct bt_object_integer *typed_integer_obj =
728 BT_OBJECT_TO_INTEGER(integer_obj);
729
730 if (!integer_obj || !bt_object_is_integer(integer_obj)) {
a40a567e
PP
731 ret = BT_OBJECT_STATUS_INVAL;
732 goto end;
733 }
734
735 if (integer_obj->is_frozen) {
736 ret = BT_OBJECT_STATUS_FROZEN;
347829f5
PP
737 goto end;
738 }
739
740 typed_integer_obj->value = val;
741
742end:
743 return ret;
744}
745
a40a567e
PP
746enum bt_object_status bt_object_float_get(const struct bt_object *float_obj,
747 double *val)
347829f5 748{
a40a567e 749 enum bt_object_status ret = BT_OBJECT_STATUS_OK;
347829f5
PP
750 struct bt_object_float *typed_float_obj =
751 BT_OBJECT_TO_FLOAT(float_obj);
752
a40a567e
PP
753 if (!float_obj || !bt_object_is_float(float_obj) || !val) {
754 ret = BT_OBJECT_STATUS_INVAL;
347829f5
PP
755 goto end;
756 }
757
758 *val = typed_float_obj->value;
759
760end:
761 return ret;
762}
763
a40a567e
PP
764enum bt_object_status bt_object_float_set(struct bt_object *float_obj,
765 double val)
347829f5 766{
a40a567e 767 enum bt_object_status ret = BT_OBJECT_STATUS_OK;
347829f5
PP
768 struct bt_object_float *typed_float_obj =
769 BT_OBJECT_TO_FLOAT(float_obj);
770
771 if (!float_obj || !bt_object_is_float(float_obj)) {
a40a567e
PP
772 ret = BT_OBJECT_STATUS_INVAL;
773 goto end;
774 }
775
776 if (float_obj->is_frozen) {
777 ret = BT_OBJECT_STATUS_FROZEN;
347829f5
PP
778 goto end;
779 }
780
781 typed_float_obj->value = val;
782
783end:
784 return ret;
785}
786
a40a567e
PP
787enum bt_object_status bt_object_string_get(const struct bt_object *string_obj,
788 const char **val)
347829f5 789{
a40a567e 790 enum bt_object_status ret = BT_OBJECT_STATUS_OK;
347829f5
PP
791 struct bt_object_string *typed_string_obj =
792 BT_OBJECT_TO_STRING(string_obj);
793
a40a567e
PP
794 if (!string_obj || !bt_object_is_string(string_obj) || !val) {
795 ret = BT_OBJECT_STATUS_INVAL;
347829f5
PP
796 goto end;
797 }
798
a40a567e 799 *val = typed_string_obj->gstr->str;
347829f5
PP
800
801end:
802 return ret;
803}
804
a40a567e
PP
805enum bt_object_status bt_object_string_set(struct bt_object *string_obj,
806 const char *val)
347829f5 807{
a40a567e 808 enum bt_object_status ret = BT_OBJECT_STATUS_OK;
347829f5
PP
809 struct bt_object_string *typed_string_obj =
810 BT_OBJECT_TO_STRING(string_obj);
811
812 if (!string_obj || !bt_object_is_string(string_obj) || !val) {
a40a567e
PP
813 ret = BT_OBJECT_STATUS_INVAL;
814 goto end;
815 }
816
817 if (string_obj->is_frozen) {
818 ret = BT_OBJECT_STATUS_FROZEN;
347829f5
PP
819 goto end;
820 }
821
822 g_string_assign(typed_string_obj->gstr, val);
823
824end:
825 return ret;
826}
827
828int bt_object_array_size(const struct bt_object *array_obj)
829{
a40a567e 830 int ret;
347829f5
PP
831 struct bt_object_array *typed_array_obj =
832 BT_OBJECT_TO_ARRAY(array_obj);
833
834 if (!array_obj || !bt_object_is_array(array_obj)) {
a40a567e 835 ret = BT_OBJECT_STATUS_INVAL;
347829f5
PP
836 goto end;
837 }
838
839 ret = (int) typed_array_obj->garray->len;
840
841end:
842 return ret;
843}
844
845bool bt_object_array_is_empty(const struct bt_object *array_obj)
846{
847 return bt_object_array_size(array_obj) == 0;
848}
849
850struct bt_object *bt_object_array_get(const struct bt_object *array_obj,
851 size_t index)
852{
853 struct bt_object *ret;
854 struct bt_object_array *typed_array_obj =
855 BT_OBJECT_TO_ARRAY(array_obj);
856
857 if (!array_obj || !bt_object_is_array(array_obj) ||
858 index >= typed_array_obj->garray->len) {
859 ret = NULL;
860 goto end;
861 }
862
a22a5f1b 863 ret = g_ptr_array_index(typed_array_obj->garray, index);
347829f5
PP
864 bt_object_get(ret);
865
866end:
867 return ret;
868}
869
a40a567e 870enum bt_object_status bt_object_array_append(struct bt_object *array_obj,
347829f5
PP
871 struct bt_object *element_obj)
872{
a40a567e 873 enum bt_object_status ret = BT_OBJECT_STATUS_OK;
347829f5
PP
874 struct bt_object_array *typed_array_obj =
875 BT_OBJECT_TO_ARRAY(array_obj);
876
877 if (!array_obj || !bt_object_is_array(array_obj) || !element_obj) {
a40a567e
PP
878 ret = BT_OBJECT_STATUS_INVAL;
879 goto end;
880 }
881
882 if (array_obj->is_frozen) {
883 ret = BT_OBJECT_STATUS_FROZEN;
347829f5
PP
884 goto end;
885 }
886
a22a5f1b 887 g_ptr_array_add(typed_array_obj->garray, element_obj);
347829f5
PP
888 bt_object_get(element_obj);
889
890end:
891 return ret;
892}
893
a40a567e
PP
894enum bt_object_status bt_object_array_append_bool(struct bt_object *array_obj,
895 bool val)
347829f5 896{
a40a567e 897 enum bt_object_status ret;
347829f5
PP
898 struct bt_object *bool_obj = NULL;
899
900 bool_obj = bt_object_bool_create_init(val);
901 ret = bt_object_array_append(array_obj, bool_obj);
902 bt_object_put(bool_obj);
903
904 return ret;
905}
906
a40a567e
PP
907enum bt_object_status bt_object_array_append_integer(
908 struct bt_object *array_obj, int64_t val)
347829f5 909{
a40a567e 910 enum bt_object_status ret;
347829f5
PP
911 struct bt_object *integer_obj = NULL;
912
913 integer_obj = bt_object_integer_create_init(val);
914 ret = bt_object_array_append(array_obj, integer_obj);
915 bt_object_put(integer_obj);
916
917 return ret;
918}
919
a40a567e
PP
920enum bt_object_status bt_object_array_append_float(struct bt_object *array_obj,
921 double val)
347829f5 922{
a40a567e 923 enum bt_object_status ret;
347829f5
PP
924 struct bt_object *float_obj = NULL;
925
926 float_obj = bt_object_float_create_init(val);
927 ret = bt_object_array_append(array_obj, float_obj);
928 bt_object_put(float_obj);
929
930 return ret;
931}
932
a40a567e
PP
933enum bt_object_status bt_object_array_append_string(struct bt_object *array_obj,
934 const char *val)
347829f5 935{
a40a567e 936 enum bt_object_status ret;
347829f5
PP
937 struct bt_object *string_obj = NULL;
938
939 string_obj = bt_object_string_create_init(val);
940 ret = bt_object_array_append(array_obj, string_obj);
941 bt_object_put(string_obj);
942
943 return ret;
944}
945
a40a567e 946enum bt_object_status bt_object_array_append_array(struct bt_object *array_obj)
347829f5 947{
a40a567e 948 enum bt_object_status ret;
347829f5
PP
949 struct bt_object *empty_array_obj = NULL;
950
951 empty_array_obj = bt_object_array_create();
952 ret = bt_object_array_append(array_obj, empty_array_obj);
953 bt_object_put(empty_array_obj);
954
955 return ret;
956}
957
a40a567e 958enum bt_object_status bt_object_array_append_map(struct bt_object *array_obj)
347829f5 959{
a40a567e 960 enum bt_object_status ret;
347829f5
PP
961 struct bt_object *map_obj = NULL;
962
963 map_obj = bt_object_map_create();
964 ret = bt_object_array_append(array_obj, map_obj);
965 bt_object_put(map_obj);
966
967 return ret;
968}
969
a40a567e
PP
970enum bt_object_status bt_object_array_set(struct bt_object *array_obj,
971 size_t index, struct bt_object *element_obj)
3695540c 972{
a40a567e 973 enum bt_object_status ret = BT_OBJECT_STATUS_OK;
3695540c
PP
974 struct bt_object_array *typed_array_obj =
975 BT_OBJECT_TO_ARRAY(array_obj);
976
977 if (!array_obj || !bt_object_is_array(array_obj) || !element_obj ||
978 index >= typed_array_obj->garray->len) {
a40a567e
PP
979 ret = BT_OBJECT_STATUS_INVAL;
980 goto end;
981 }
982
983 if (array_obj->is_frozen) {
984 ret = BT_OBJECT_STATUS_FROZEN;
3695540c
PP
985 goto end;
986 }
987
988 bt_object_put(g_ptr_array_index(typed_array_obj->garray, index));
989 g_ptr_array_index(typed_array_obj->garray, index) = element_obj;
990 bt_object_get(element_obj);
991
992end:
993 return ret;
994}
995
347829f5
PP
996int bt_object_map_size(const struct bt_object *map_obj)
997{
998 int ret;
999 struct bt_object_map *typed_map_obj = BT_OBJECT_TO_MAP(map_obj);
1000
1001 if (!map_obj || !bt_object_is_map(map_obj)) {
a40a567e 1002 ret = BT_OBJECT_STATUS_INVAL;
347829f5
PP
1003 goto end;
1004 }
1005
1006 ret = (int) g_hash_table_size(typed_map_obj->ght);
1007
1008end:
1009 return ret;
1010}
1011
1012bool bt_object_map_is_empty(const struct bt_object *map_obj)
1013{
1014 return bt_object_map_size(map_obj) == 0;
1015}
1016
1017struct bt_object *bt_object_map_get(const struct bt_object *map_obj,
1018 const char *key)
1019{
1020 GQuark quark;
1021 struct bt_object *ret;
1022 struct bt_object_map *typed_map_obj = BT_OBJECT_TO_MAP(map_obj);
1023
1024 if (!map_obj || !bt_object_is_map(map_obj) || !key) {
1025 ret = NULL;
1026 goto end;
1027 }
1028
1029 quark = g_quark_from_string(key);
1030 ret = g_hash_table_lookup(typed_map_obj->ght, GUINT_TO_POINTER(quark));
1031
1032 if (ret) {
1033 bt_object_get(ret);
1034 }
1035
1036end:
1037 return ret;
1038}
1039
1040bool bt_object_map_has_key(const struct bt_object *map_obj, const char *key)
1041{
1042 bool ret;
1043 GQuark quark;
1044 struct bt_object_map *typed_map_obj = BT_OBJECT_TO_MAP(map_obj);
1045
1046 if (!map_obj || !bt_object_is_map(map_obj) || !key) {
1047 ret = false;
1048 goto end;
1049 }
1050
1051 quark = g_quark_from_string(key);
1052 ret = g_hash_table_contains(typed_map_obj->ght,
1053 GUINT_TO_POINTER(quark));
1054
1055end:
1056 return ret;
1057}
1058
a40a567e
PP
1059enum bt_object_status bt_object_map_insert(struct bt_object *map_obj,
1060 const char *key, struct bt_object *element_obj)
347829f5 1061{
347829f5 1062 GQuark quark;
a40a567e 1063 enum bt_object_status ret = BT_OBJECT_STATUS_OK;
347829f5
PP
1064 struct bt_object_map *typed_map_obj = BT_OBJECT_TO_MAP(map_obj);
1065
1066 if (!map_obj || !bt_object_is_map(map_obj) || !key || !element_obj) {
a40a567e
PP
1067 ret = BT_OBJECT_STATUS_INVAL;
1068 goto end;
1069 }
1070
1071 if (map_obj->is_frozen) {
1072 ret = BT_OBJECT_STATUS_FROZEN;
347829f5
PP
1073 goto end;
1074 }
1075
1076 quark = g_quark_from_string(key);
1077 g_hash_table_insert(typed_map_obj->ght,
1078 GUINT_TO_POINTER(quark), element_obj);
1079 bt_object_get(element_obj);
1080
1081end:
1082 return ret;
1083}
1084
a40a567e 1085enum bt_object_status bt_object_map_insert_bool(struct bt_object *map_obj,
347829f5
PP
1086 const char *key, bool val)
1087{
a40a567e 1088 enum bt_object_status ret;
347829f5
PP
1089 struct bt_object *bool_obj = NULL;
1090
1091 bool_obj = bt_object_bool_create_init(val);
1092 ret = bt_object_map_insert(map_obj, key, bool_obj);
1093 bt_object_put(bool_obj);
1094
1095 return ret;
1096}
1097
a40a567e 1098enum bt_object_status bt_object_map_insert_integer(struct bt_object *map_obj,
347829f5
PP
1099 const char *key, int64_t val)
1100{
a40a567e 1101 enum bt_object_status ret;
347829f5
PP
1102 struct bt_object *integer_obj = NULL;
1103
1104 integer_obj = bt_object_integer_create_init(val);
1105 ret = bt_object_map_insert(map_obj, key, integer_obj);
1106 bt_object_put(integer_obj);
1107
1108 return ret;
1109}
1110
a40a567e 1111enum bt_object_status bt_object_map_insert_float(struct bt_object *map_obj,
347829f5
PP
1112 const char *key, double val)
1113{
a40a567e 1114 enum bt_object_status ret;
347829f5
PP
1115 struct bt_object *float_obj = NULL;
1116
1117 float_obj = bt_object_float_create_init(val);
1118 ret = bt_object_map_insert(map_obj, key, float_obj);
1119 bt_object_put(float_obj);
1120
1121 return ret;
1122}
1123
a40a567e 1124enum bt_object_status bt_object_map_insert_string(struct bt_object *map_obj,
347829f5
PP
1125 const char *key, const char *val)
1126{
a40a567e 1127 enum bt_object_status ret;
347829f5
PP
1128 struct bt_object *string_obj = NULL;
1129
1130 string_obj = bt_object_string_create_init(val);
1131 ret = bt_object_map_insert(map_obj, key, string_obj);
1132 bt_object_put(string_obj);
1133
1134 return ret;
1135}
1136
a40a567e 1137enum bt_object_status bt_object_map_insert_array(struct bt_object *map_obj,
347829f5
PP
1138 const char *key)
1139{
a40a567e 1140 enum bt_object_status ret;
347829f5
PP
1141 struct bt_object *array_obj = NULL;
1142
1143 array_obj = bt_object_array_create();
1144 ret = bt_object_map_insert(map_obj, key, array_obj);
1145 bt_object_put(array_obj);
1146
1147 return ret;
1148}
1149
a40a567e 1150enum bt_object_status bt_object_map_insert_map(struct bt_object *map_obj,
347829f5
PP
1151 const char *key)
1152{
a40a567e 1153 enum bt_object_status ret;
347829f5
PP
1154 struct bt_object *empty_map_obj = NULL;
1155
1156 empty_map_obj = bt_object_map_create();
1157 ret = bt_object_map_insert(map_obj, key, empty_map_obj);
1158 bt_object_put(empty_map_obj);
1159
1160 return ret;
1161}
1162
a40a567e 1163enum bt_object_status bt_object_map_foreach(const struct bt_object *map_obj,
347829f5
PP
1164 bt_object_map_foreach_cb cb, void *data)
1165{
4a512e75 1166 enum bt_object_status ret = BT_OBJECT_STATUS_OK;
347829f5
PP
1167 gpointer key, element_obj;
1168 GHashTableIter iter;
1169 struct bt_object_map *typed_map_obj = BT_OBJECT_TO_MAP(map_obj);
1170
1171 if (!map_obj || !bt_object_is_map(map_obj) || !cb) {
a40a567e 1172 ret = BT_OBJECT_STATUS_INVAL;
347829f5
PP
1173 goto end;
1174 }
1175
1176 g_hash_table_iter_init(&iter, typed_map_obj->ght);
1177
1178 while (g_hash_table_iter_next(&iter, &key, &element_obj)) {
1179 const char *key_str = g_quark_to_string((unsigned long) key);
1180
1181 if (!cb(key_str, element_obj, data)) {
4a512e75 1182 ret = BT_OBJECT_STATUS_CANCELLED;
347829f5
PP
1183 break;
1184 }
1185 }
1186
1187end:
1188 return ret;
1189}
1190
1191struct bt_object *bt_object_copy(const struct bt_object *object)
1192{
1193 struct bt_object *copy_obj = NULL;
1194
1195 if (!object) {
1196 goto end;
1197 }
1198
1199 copy_obj = copy_funcs[object->type](object);
1200
1201end:
1202 return copy_obj;
1203}
1204
1205bool bt_object_compare(const struct bt_object *object_a,
1206 const struct bt_object *object_b)
1207{
1208 bool ret = false;
1209
1210 if (!object_a || !object_b) {
1211 goto end;
1212 }
1213
1214 if (object_a->type != object_b->type) {
1215 goto end;
1216 }
1217
1218 ret = compare_funcs[object_a->type](object_a, object_b);
1219
1220end:
1221 return ret;
1222}
This page took 0.07167 seconds and 4 git commands to generate.