2 * Values.c: value objects
6 * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation
7 * Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com>
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:
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
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
32 #include <babeltrace/compiler.h>
33 #include <babeltrace/object-internal.h>
34 #include <babeltrace/ref.h>
35 #include <babeltrace/values.h>
36 #include <babeltrace/compat/glib.h>
38 #define BT_VALUE_FROM_CONCRETE(_concrete) ((struct bt_value *) (_concrete))
39 #define BT_VALUE_TO_BOOL(_base) ((struct bt_value_bool *) (_base))
40 #define BT_VALUE_TO_INTEGER(_base) ((struct bt_value_integer *) (_base))
41 #define BT_VALUE_TO_FLOAT(_base) ((struct bt_value_float *) (_base))
42 #define BT_VALUE_TO_STRING(_base) ((struct bt_value_string *) (_base))
43 #define BT_VALUE_TO_ARRAY(_base) ((struct bt_value_array *) (_base))
44 #define BT_VALUE_TO_MAP(_base) ((struct bt_value_map *) (_base))
47 struct bt_object base
;
48 enum bt_value_type type
;
53 struct bt_value bt_value_null_instance
= {
54 .type
= BT_VALUE_TYPE_NULL
,
58 struct bt_value
*bt_value_null
= &bt_value_null_instance
;
60 struct bt_value_bool
{
65 struct bt_value_integer
{
70 struct bt_value_float
{
75 struct bt_value_string
{
80 struct bt_value_array
{
91 void bt_value_destroy(struct bt_object
*obj
);
94 void bt_value_string_destroy(struct bt_value
*object
)
96 g_string_free(BT_VALUE_TO_STRING(object
)->gstr
, TRUE
);
100 void bt_value_array_destroy(struct bt_value
*object
)
103 * Pointer array's registered value destructor will take care
104 * of putting each contained object.
106 g_ptr_array_free(BT_VALUE_TO_ARRAY(object
)->garray
, TRUE
);
110 void bt_value_map_destroy(struct bt_value
*object
)
113 * Hash table's registered value destructor will take care of
114 * putting each contained object. Keys are GQuarks and cannot
115 * be destroyed anyway.
117 g_hash_table_destroy(BT_VALUE_TO_MAP(object
)->ght
);
121 void (* const destroy_funcs
[])(struct bt_value
*) = {
122 [BT_VALUE_TYPE_NULL
] = NULL
,
123 [BT_VALUE_TYPE_BOOL
] = NULL
,
124 [BT_VALUE_TYPE_INTEGER
] = NULL
,
125 [BT_VALUE_TYPE_FLOAT
] = NULL
,
126 [BT_VALUE_TYPE_STRING
] = bt_value_string_destroy
,
127 [BT_VALUE_TYPE_ARRAY
] = bt_value_array_destroy
,
128 [BT_VALUE_TYPE_MAP
] = bt_value_map_destroy
,
132 struct bt_value
*bt_value_null_copy(const struct bt_value
*null_obj
)
134 return bt_value_null
;
138 struct bt_value
*bt_value_bool_copy(const struct bt_value
*bool_obj
)
140 return bt_value_bool_create_init(BT_VALUE_TO_BOOL(bool_obj
)->value
);
144 struct bt_value
*bt_value_integer_copy(const struct bt_value
*integer_obj
)
146 return bt_value_integer_create_init(
147 BT_VALUE_TO_INTEGER(integer_obj
)->value
);
151 struct bt_value
*bt_value_float_copy(const struct bt_value
*float_obj
)
153 return bt_value_float_create_init(
154 BT_VALUE_TO_FLOAT(float_obj
)->value
);
158 struct bt_value
*bt_value_string_copy(const struct bt_value
*string_obj
)
160 return bt_value_string_create_init(
161 BT_VALUE_TO_STRING(string_obj
)->gstr
->str
);
165 struct bt_value
*bt_value_array_copy(const struct bt_value
*array_obj
)
169 struct bt_value
*copy_obj
;
170 struct bt_value_array
*typed_array_obj
;
172 typed_array_obj
= BT_VALUE_TO_ARRAY(array_obj
);
173 copy_obj
= bt_value_array_create();
179 for (i
= 0; i
< typed_array_obj
->garray
->len
; ++i
) {
180 struct bt_value
*element_obj_copy
;
181 struct bt_value
*element_obj
= bt_value_array_get(array_obj
, i
);
188 element_obj_copy
= bt_value_copy(element_obj
);
191 if (!element_obj_copy
) {
196 ret
= bt_value_array_append(copy_obj
, element_obj_copy
);
197 BT_PUT(element_obj_copy
);
210 struct bt_value
*bt_value_map_copy(const struct bt_value
*map_obj
)
214 gpointer key
, element_obj
;
215 struct bt_value
*copy_obj
;
216 struct bt_value
*element_obj_copy
;
217 struct bt_value_map
*typed_map_obj
;
219 typed_map_obj
= BT_VALUE_TO_MAP(map_obj
);
220 copy_obj
= bt_value_map_create();
226 g_hash_table_iter_init(&iter
, typed_map_obj
->ght
);
228 while (g_hash_table_iter_next(&iter
, &key
, &element_obj
)) {
229 const char *key_str
= g_quark_to_string((unsigned long) key
);
231 element_obj_copy
= bt_value_copy(element_obj
);
233 if (!element_obj_copy
) {
238 ret
= bt_value_map_insert(copy_obj
, key_str
, element_obj_copy
);
239 BT_PUT(element_obj_copy
);
252 struct bt_value
*(* const copy_funcs
[])(const struct bt_value
*) = {
253 [BT_VALUE_TYPE_NULL
] = bt_value_null_copy
,
254 [BT_VALUE_TYPE_BOOL
] = bt_value_bool_copy
,
255 [BT_VALUE_TYPE_INTEGER
] = bt_value_integer_copy
,
256 [BT_VALUE_TYPE_FLOAT
] = bt_value_float_copy
,
257 [BT_VALUE_TYPE_STRING
] = bt_value_string_copy
,
258 [BT_VALUE_TYPE_ARRAY
] = bt_value_array_copy
,
259 [BT_VALUE_TYPE_MAP
] = bt_value_map_copy
,
263 bool bt_value_null_compare(const struct bt_value
*object_a
,
264 const struct bt_value
*object_b
)
267 * Always true since bt_value_compare() already checks if both
268 * object_a and object_b have the same type, and in the case of
269 * null value objects, they're always the same if it is so.
275 bool bt_value_bool_compare(const struct bt_value
*object_a
,
276 const struct bt_value
*object_b
)
278 return BT_VALUE_TO_BOOL(object_a
)->value
==
279 BT_VALUE_TO_BOOL(object_b
)->value
;
283 bool bt_value_integer_compare(const struct bt_value
*object_a
,
284 const struct bt_value
*object_b
)
286 return BT_VALUE_TO_INTEGER(object_a
)->value
==
287 BT_VALUE_TO_INTEGER(object_b
)->value
;
291 bool bt_value_float_compare(const struct bt_value
*object_a
,
292 const struct bt_value
*object_b
)
294 return BT_VALUE_TO_FLOAT(object_a
)->value
==
295 BT_VALUE_TO_FLOAT(object_b
)->value
;
299 bool bt_value_string_compare(const struct bt_value
*object_a
,
300 const struct bt_value
*object_b
)
302 return !strcmp(BT_VALUE_TO_STRING(object_a
)->gstr
->str
,
303 BT_VALUE_TO_STRING(object_b
)->gstr
->str
);
307 bool bt_value_array_compare(const struct bt_value
*object_a
,
308 const struct bt_value
*object_b
)
312 const struct bt_value_array
*array_obj_a
=
313 BT_VALUE_TO_ARRAY(object_a
);
315 if (bt_value_array_size(object_a
) != bt_value_array_size(object_b
)) {
320 for (i
= 0; i
< array_obj_a
->garray
->len
; ++i
) {
321 struct bt_value
*element_obj_a
;
322 struct bt_value
*element_obj_b
;
324 element_obj_a
= bt_value_array_get(object_a
, i
);
325 element_obj_b
= bt_value_array_get(object_b
, i
);
327 if (!bt_value_compare(element_obj_a
, element_obj_b
)) {
328 BT_PUT(element_obj_a
);
329 BT_PUT(element_obj_b
);
334 BT_PUT(element_obj_a
);
335 BT_PUT(element_obj_b
);
343 bool bt_value_map_compare(const struct bt_value
*object_a
,
344 const struct bt_value
*object_b
)
348 gpointer key
, element_obj_a
;
349 const struct bt_value_map
*map_obj_a
= BT_VALUE_TO_MAP(object_a
);
351 if (bt_value_map_size(object_a
) != bt_value_map_size(object_b
)) {
356 g_hash_table_iter_init(&iter
, map_obj_a
->ght
);
358 while (g_hash_table_iter_next(&iter
, &key
, &element_obj_a
)) {
359 struct bt_value
*element_obj_b
;
360 const char *key_str
= g_quark_to_string((unsigned long) key
);
362 element_obj_b
= bt_value_map_get(object_b
, key_str
);
364 if (!bt_value_compare(element_obj_a
, element_obj_b
)) {
365 BT_PUT(element_obj_b
);
370 BT_PUT(element_obj_b
);
378 bool (* const compare_funcs
[])(const struct bt_value
*,
379 const struct bt_value
*) = {
380 [BT_VALUE_TYPE_NULL
] = bt_value_null_compare
,
381 [BT_VALUE_TYPE_BOOL
] = bt_value_bool_compare
,
382 [BT_VALUE_TYPE_INTEGER
] = bt_value_integer_compare
,
383 [BT_VALUE_TYPE_FLOAT
] = bt_value_float_compare
,
384 [BT_VALUE_TYPE_STRING
] = bt_value_string_compare
,
385 [BT_VALUE_TYPE_ARRAY
] = bt_value_array_compare
,
386 [BT_VALUE_TYPE_MAP
] = bt_value_map_compare
,
389 void bt_value_null_freeze(struct bt_value
*object
)
393 void bt_value_generic_freeze(struct bt_value
*object
)
395 object
->is_frozen
= true;
398 void bt_value_array_freeze(struct bt_value
*object
)
401 struct bt_value_array
*typed_array_obj
=
402 BT_VALUE_TO_ARRAY(object
);
404 for (i
= 0; i
< typed_array_obj
->garray
->len
; ++i
) {
405 struct bt_value
*element_obj
=
406 g_ptr_array_index(typed_array_obj
->garray
, i
);
408 bt_value_freeze(element_obj
);
411 bt_value_generic_freeze(object
);
414 void bt_value_map_freeze(struct bt_value
*object
)
417 gpointer key
, element_obj
;
418 const struct bt_value_map
*map_obj
= BT_VALUE_TO_MAP(object
);
420 g_hash_table_iter_init(&iter
, map_obj
->ght
);
422 while (g_hash_table_iter_next(&iter
, &key
, &element_obj
)) {
423 bt_value_freeze(element_obj
);
426 bt_value_generic_freeze(object
);
430 void (* const freeze_funcs
[])(struct bt_value
*) = {
431 [BT_VALUE_TYPE_NULL
] = bt_value_null_freeze
,
432 [BT_VALUE_TYPE_BOOL
] = bt_value_generic_freeze
,
433 [BT_VALUE_TYPE_INTEGER
] = bt_value_generic_freeze
,
434 [BT_VALUE_TYPE_FLOAT
] = bt_value_generic_freeze
,
435 [BT_VALUE_TYPE_STRING
] = bt_value_generic_freeze
,
436 [BT_VALUE_TYPE_ARRAY
] = bt_value_array_freeze
,
437 [BT_VALUE_TYPE_MAP
] = bt_value_map_freeze
,
441 void bt_value_destroy(struct bt_object
*obj
)
443 struct bt_value
*value
;
445 value
= container_of(obj
, struct bt_value
, base
);
446 assert(value
->type
!= BT_VALUE_TYPE_UNKNOWN
);
448 if (bt_value_is_null(value
)) {
452 if (destroy_funcs
[value
->type
]) {
453 destroy_funcs
[value
->type
](value
);
459 enum bt_value_status
bt_value_freeze(struct bt_value
*object
)
461 enum bt_value_status ret
= BT_VALUE_STATUS_OK
;
464 ret
= BT_VALUE_STATUS_INVAL
;
468 freeze_funcs
[object
->type
](object
);
474 bool bt_value_is_frozen(const struct bt_value
*object
)
476 return object
&& object
->is_frozen
;
479 enum bt_value_type
bt_value_get_type(const struct bt_value
*object
)
482 return BT_VALUE_TYPE_UNKNOWN
;
489 struct bt_value
bt_value_create_base(enum bt_value_type type
)
491 struct bt_value base
;
494 base
.is_frozen
= false;
495 bt_object_init(&base
, bt_value_destroy
);
500 struct bt_value
*bt_value_bool_create_init(bool val
)
502 struct bt_value_bool
*bool_obj
;
504 bool_obj
= g_new0(struct bt_value_bool
, 1);
510 bool_obj
->base
= bt_value_create_base(BT_VALUE_TYPE_BOOL
);
511 bool_obj
->value
= val
;
514 return BT_VALUE_FROM_CONCRETE(bool_obj
);
517 struct bt_value
*bt_value_bool_create(void)
519 return bt_value_bool_create_init(false);
522 struct bt_value
*bt_value_integer_create_init(int64_t val
)
524 struct bt_value_integer
*integer_obj
;
526 integer_obj
= g_new0(struct bt_value_integer
, 1);
532 integer_obj
->base
= bt_value_create_base(BT_VALUE_TYPE_INTEGER
);
533 integer_obj
->value
= val
;
536 return BT_VALUE_FROM_CONCRETE(integer_obj
);
539 struct bt_value
*bt_value_integer_create(void)
541 return bt_value_integer_create_init(0);
544 struct bt_value
*bt_value_float_create_init(double val
)
546 struct bt_value_float
*float_obj
;
548 float_obj
= g_new0(struct bt_value_float
, 1);
554 float_obj
->base
= bt_value_create_base(BT_VALUE_TYPE_FLOAT
);
555 float_obj
->value
= val
;
558 return BT_VALUE_FROM_CONCRETE(float_obj
);
561 struct bt_value
*bt_value_float_create(void)
563 return bt_value_float_create_init(0.);
566 struct bt_value
*bt_value_string_create_init(const char *val
)
568 struct bt_value_string
*string_obj
= NULL
;
574 string_obj
= g_new0(struct bt_value_string
, 1);
580 string_obj
->base
= bt_value_create_base(BT_VALUE_TYPE_STRING
);
581 string_obj
->gstr
= g_string_new(val
);
583 if (!string_obj
->gstr
) {
590 return BT_VALUE_FROM_CONCRETE(string_obj
);
593 struct bt_value
*bt_value_string_create(void)
595 return bt_value_string_create_init("");
598 struct bt_value
*bt_value_array_create(void)
600 struct bt_value_array
*array_obj
;
602 array_obj
= g_new0(struct bt_value_array
, 1);
608 array_obj
->base
= bt_value_create_base(BT_VALUE_TYPE_ARRAY
);
609 array_obj
->garray
= babeltrace_g_ptr_array_new_full(0,
610 (GDestroyNotify
) bt_put
);
612 if (!array_obj
->garray
) {
619 return BT_VALUE_FROM_CONCRETE(array_obj
);
622 struct bt_value
*bt_value_map_create(void)
624 struct bt_value_map
*map_obj
;
626 map_obj
= g_new0(struct bt_value_map
, 1);
632 map_obj
->base
= bt_value_create_base(BT_VALUE_TYPE_MAP
);
633 map_obj
->ght
= g_hash_table_new_full(g_direct_hash
, g_direct_equal
,
634 NULL
, (GDestroyNotify
) bt_put
);
643 return BT_VALUE_FROM_CONCRETE(map_obj
);
646 enum bt_value_status
bt_value_bool_get(const struct bt_value
*bool_obj
,
649 enum bt_value_status ret
= BT_VALUE_STATUS_OK
;
650 struct bt_value_bool
*typed_bool_obj
= BT_VALUE_TO_BOOL(bool_obj
);
652 if (!bool_obj
|| !bt_value_is_bool(bool_obj
) || !val
) {
653 ret
= BT_VALUE_STATUS_INVAL
;
657 *val
= typed_bool_obj
->value
;
663 enum bt_value_status
bt_value_bool_set(struct bt_value
*bool_obj
, bool val
)
665 enum bt_value_status ret
= BT_VALUE_STATUS_OK
;
666 struct bt_value_bool
*typed_bool_obj
= BT_VALUE_TO_BOOL(bool_obj
);
668 if (!bool_obj
|| !bt_value_is_bool(bool_obj
)) {
669 ret
= BT_VALUE_STATUS_INVAL
;
673 if (bool_obj
->is_frozen
) {
674 ret
= BT_VALUE_STATUS_FROZEN
;
678 typed_bool_obj
->value
= val
;
684 enum bt_value_status
bt_value_integer_get(const struct bt_value
*integer_obj
,
687 enum bt_value_status ret
= BT_VALUE_STATUS_OK
;
688 struct bt_value_integer
*typed_integer_obj
=
689 BT_VALUE_TO_INTEGER(integer_obj
);
691 if (!integer_obj
|| !bt_value_is_integer(integer_obj
) || !val
) {
692 ret
= BT_VALUE_STATUS_INVAL
;
696 *val
= typed_integer_obj
->value
;
702 enum bt_value_status
bt_value_integer_set(struct bt_value
*integer_obj
,
705 enum bt_value_status ret
= BT_VALUE_STATUS_OK
;
706 struct bt_value_integer
*typed_integer_obj
=
707 BT_VALUE_TO_INTEGER(integer_obj
);
709 if (!integer_obj
|| !bt_value_is_integer(integer_obj
)) {
710 ret
= BT_VALUE_STATUS_INVAL
;
714 if (integer_obj
->is_frozen
) {
715 ret
= BT_VALUE_STATUS_FROZEN
;
719 typed_integer_obj
->value
= val
;
725 enum bt_value_status
bt_value_float_get(const struct bt_value
*float_obj
,
728 enum bt_value_status ret
= BT_VALUE_STATUS_OK
;
729 struct bt_value_float
*typed_float_obj
=
730 BT_VALUE_TO_FLOAT(float_obj
);
732 if (!float_obj
|| !bt_value_is_float(float_obj
) || !val
) {
733 ret
= BT_VALUE_STATUS_INVAL
;
737 *val
= typed_float_obj
->value
;
743 enum bt_value_status
bt_value_float_set(struct bt_value
*float_obj
,
746 enum bt_value_status ret
= BT_VALUE_STATUS_OK
;
747 struct bt_value_float
*typed_float_obj
=
748 BT_VALUE_TO_FLOAT(float_obj
);
750 if (!float_obj
|| !bt_value_is_float(float_obj
)) {
751 ret
= BT_VALUE_STATUS_INVAL
;
755 if (float_obj
->is_frozen
) {
756 ret
= BT_VALUE_STATUS_FROZEN
;
760 typed_float_obj
->value
= val
;
766 enum bt_value_status
bt_value_string_get(const struct bt_value
*string_obj
,
769 enum bt_value_status ret
= BT_VALUE_STATUS_OK
;
770 struct bt_value_string
*typed_string_obj
=
771 BT_VALUE_TO_STRING(string_obj
);
773 if (!string_obj
|| !bt_value_is_string(string_obj
) || !val
) {
774 ret
= BT_VALUE_STATUS_INVAL
;
778 *val
= typed_string_obj
->gstr
->str
;
784 enum bt_value_status
bt_value_string_set(struct bt_value
*string_obj
,
787 enum bt_value_status ret
= BT_VALUE_STATUS_OK
;
788 struct bt_value_string
*typed_string_obj
=
789 BT_VALUE_TO_STRING(string_obj
);
791 if (!string_obj
|| !bt_value_is_string(string_obj
) || !val
) {
792 ret
= BT_VALUE_STATUS_INVAL
;
796 if (string_obj
->is_frozen
) {
797 ret
= BT_VALUE_STATUS_FROZEN
;
801 g_string_assign(typed_string_obj
->gstr
, val
);
807 int bt_value_array_size(const struct bt_value
*array_obj
)
810 struct bt_value_array
*typed_array_obj
=
811 BT_VALUE_TO_ARRAY(array_obj
);
813 if (!array_obj
|| !bt_value_is_array(array_obj
)) {
814 ret
= BT_VALUE_STATUS_INVAL
;
818 ret
= (int) typed_array_obj
->garray
->len
;
824 bool bt_value_array_is_empty(const struct bt_value
*array_obj
)
826 return bt_value_array_size(array_obj
) == 0;
829 struct bt_value
*bt_value_array_get(const struct bt_value
*array_obj
,
832 struct bt_value
*ret
;
833 struct bt_value_array
*typed_array_obj
=
834 BT_VALUE_TO_ARRAY(array_obj
);
836 if (!array_obj
|| !bt_value_is_array(array_obj
) ||
837 index
>= typed_array_obj
->garray
->len
) {
842 ret
= g_ptr_array_index(typed_array_obj
->garray
, index
);
849 enum bt_value_status
bt_value_array_append(struct bt_value
*array_obj
,
850 struct bt_value
*element_obj
)
852 enum bt_value_status ret
= BT_VALUE_STATUS_OK
;
853 struct bt_value_array
*typed_array_obj
=
854 BT_VALUE_TO_ARRAY(array_obj
);
856 if (!array_obj
|| !bt_value_is_array(array_obj
) || !element_obj
) {
857 ret
= BT_VALUE_STATUS_INVAL
;
861 if (array_obj
->is_frozen
) {
862 ret
= BT_VALUE_STATUS_FROZEN
;
866 g_ptr_array_add(typed_array_obj
->garray
, element_obj
);
873 enum bt_value_status
bt_value_array_append_bool(struct bt_value
*array_obj
,
876 enum bt_value_status ret
;
877 struct bt_value
*bool_obj
= NULL
;
879 bool_obj
= bt_value_bool_create_init(val
);
880 ret
= bt_value_array_append(array_obj
, bool_obj
);
886 enum bt_value_status
bt_value_array_append_integer(
887 struct bt_value
*array_obj
, int64_t val
)
889 enum bt_value_status ret
;
890 struct bt_value
*integer_obj
= NULL
;
892 integer_obj
= bt_value_integer_create_init(val
);
893 ret
= bt_value_array_append(array_obj
, integer_obj
);
899 enum bt_value_status
bt_value_array_append_float(struct bt_value
*array_obj
,
902 enum bt_value_status ret
;
903 struct bt_value
*float_obj
= NULL
;
905 float_obj
= bt_value_float_create_init(val
);
906 ret
= bt_value_array_append(array_obj
, float_obj
);
912 enum bt_value_status
bt_value_array_append_string(struct bt_value
*array_obj
,
915 enum bt_value_status ret
;
916 struct bt_value
*string_obj
= NULL
;
918 string_obj
= bt_value_string_create_init(val
);
919 ret
= bt_value_array_append(array_obj
, string_obj
);
925 enum bt_value_status
bt_value_array_append_empty_array(
926 struct bt_value
*array_obj
)
928 enum bt_value_status ret
;
929 struct bt_value
*empty_array_obj
= NULL
;
931 empty_array_obj
= bt_value_array_create();
932 ret
= bt_value_array_append(array_obj
, empty_array_obj
);
933 bt_put(empty_array_obj
);
938 enum bt_value_status
bt_value_array_append_empty_map(struct bt_value
*array_obj
)
940 enum bt_value_status ret
;
941 struct bt_value
*map_obj
= NULL
;
943 map_obj
= bt_value_map_create();
944 ret
= bt_value_array_append(array_obj
, map_obj
);
950 enum bt_value_status
bt_value_array_set(struct bt_value
*array_obj
,
951 size_t index
, struct bt_value
*element_obj
)
953 enum bt_value_status ret
= BT_VALUE_STATUS_OK
;
954 struct bt_value_array
*typed_array_obj
=
955 BT_VALUE_TO_ARRAY(array_obj
);
957 if (!array_obj
|| !bt_value_is_array(array_obj
) || !element_obj
||
958 index
>= typed_array_obj
->garray
->len
) {
959 ret
= BT_VALUE_STATUS_INVAL
;
963 if (array_obj
->is_frozen
) {
964 ret
= BT_VALUE_STATUS_FROZEN
;
968 bt_put(g_ptr_array_index(typed_array_obj
->garray
, index
));
969 g_ptr_array_index(typed_array_obj
->garray
, index
) = element_obj
;
976 int bt_value_map_size(const struct bt_value
*map_obj
)
979 struct bt_value_map
*typed_map_obj
= BT_VALUE_TO_MAP(map_obj
);
981 if (!map_obj
|| !bt_value_is_map(map_obj
)) {
982 ret
= BT_VALUE_STATUS_INVAL
;
986 ret
= (int) g_hash_table_size(typed_map_obj
->ght
);
992 bool bt_value_map_is_empty(const struct bt_value
*map_obj
)
994 return bt_value_map_size(map_obj
) == 0;
997 struct bt_value
*bt_value_map_get(const struct bt_value
*map_obj
,
1001 struct bt_value
*ret
;
1002 struct bt_value_map
*typed_map_obj
= BT_VALUE_TO_MAP(map_obj
);
1004 if (!map_obj
|| !bt_value_is_map(map_obj
) || !key
) {
1009 quark
= g_quark_from_string(key
);
1010 ret
= g_hash_table_lookup(typed_map_obj
->ght
, GUINT_TO_POINTER(quark
));
1020 bool bt_value_map_has_key(const struct bt_value
*map_obj
, const char *key
)
1024 struct bt_value_map
*typed_map_obj
= BT_VALUE_TO_MAP(map_obj
);
1026 if (!map_obj
|| !bt_value_is_map(map_obj
) || !key
) {
1031 quark
= g_quark_from_string(key
);
1032 ret
= babeltrace_g_hash_table_contains(typed_map_obj
->ght
,
1033 GUINT_TO_POINTER(quark
));
1039 enum bt_value_status
bt_value_map_insert(struct bt_value
*map_obj
,
1040 const char *key
, struct bt_value
*element_obj
)
1043 enum bt_value_status ret
= BT_VALUE_STATUS_OK
;
1044 struct bt_value_map
*typed_map_obj
= BT_VALUE_TO_MAP(map_obj
);
1046 if (!map_obj
|| !bt_value_is_map(map_obj
) || !key
|| !element_obj
) {
1047 ret
= BT_VALUE_STATUS_INVAL
;
1051 if (map_obj
->is_frozen
) {
1052 ret
= BT_VALUE_STATUS_FROZEN
;
1056 quark
= g_quark_from_string(key
);
1057 g_hash_table_insert(typed_map_obj
->ght
,
1058 GUINT_TO_POINTER(quark
), element_obj
);
1059 bt_get(element_obj
);
1065 enum bt_value_status
bt_value_map_insert_bool(struct bt_value
*map_obj
,
1066 const char *key
, bool val
)
1068 enum bt_value_status ret
;
1069 struct bt_value
*bool_obj
= NULL
;
1071 bool_obj
= bt_value_bool_create_init(val
);
1072 ret
= bt_value_map_insert(map_obj
, key
, bool_obj
);
1078 enum bt_value_status
bt_value_map_insert_integer(struct bt_value
*map_obj
,
1079 const char *key
, int64_t val
)
1081 enum bt_value_status ret
;
1082 struct bt_value
*integer_obj
= NULL
;
1084 integer_obj
= bt_value_integer_create_init(val
);
1085 ret
= bt_value_map_insert(map_obj
, key
, integer_obj
);
1086 bt_put(integer_obj
);
1091 enum bt_value_status
bt_value_map_insert_float(struct bt_value
*map_obj
,
1092 const char *key
, double val
)
1094 enum bt_value_status ret
;
1095 struct bt_value
*float_obj
= NULL
;
1097 float_obj
= bt_value_float_create_init(val
);
1098 ret
= bt_value_map_insert(map_obj
, key
, float_obj
);
1104 enum bt_value_status
bt_value_map_insert_string(struct bt_value
*map_obj
,
1105 const char *key
, const char *val
)
1107 enum bt_value_status ret
;
1108 struct bt_value
*string_obj
= NULL
;
1110 string_obj
= bt_value_string_create_init(val
);
1111 ret
= bt_value_map_insert(map_obj
, key
, string_obj
);
1117 enum bt_value_status
bt_value_map_insert_empty_array(struct bt_value
*map_obj
,
1120 enum bt_value_status ret
;
1121 struct bt_value
*array_obj
= NULL
;
1123 array_obj
= bt_value_array_create();
1124 ret
= bt_value_map_insert(map_obj
, key
, array_obj
);
1130 enum bt_value_status
bt_value_map_insert_empty_map(struct bt_value
*map_obj
,
1133 enum bt_value_status ret
;
1134 struct bt_value
*empty_map_obj
= NULL
;
1136 empty_map_obj
= bt_value_map_create();
1137 ret
= bt_value_map_insert(map_obj
, key
, empty_map_obj
);
1138 bt_put(empty_map_obj
);
1143 enum bt_value_status
bt_value_map_foreach(const struct bt_value
*map_obj
,
1144 bt_value_map_foreach_cb cb
, void *data
)
1146 enum bt_value_status ret
= BT_VALUE_STATUS_OK
;
1147 gpointer key
, element_obj
;
1148 GHashTableIter iter
;
1149 struct bt_value_map
*typed_map_obj
= BT_VALUE_TO_MAP(map_obj
);
1151 if (!map_obj
|| !bt_value_is_map(map_obj
) || !cb
) {
1152 ret
= BT_VALUE_STATUS_INVAL
;
1156 g_hash_table_iter_init(&iter
, typed_map_obj
->ght
);
1158 while (g_hash_table_iter_next(&iter
, &key
, &element_obj
)) {
1159 const char *key_str
= g_quark_to_string((unsigned long) key
);
1161 if (!cb(key_str
, element_obj
, data
)) {
1162 ret
= BT_VALUE_STATUS_CANCELLED
;
1171 struct bt_value
*bt_value_copy(const struct bt_value
*object
)
1173 struct bt_value
*copy_obj
= NULL
;
1179 copy_obj
= copy_funcs
[object
->type
](object
);
1185 bool bt_value_compare(const struct bt_value
*object_a
,
1186 const struct bt_value
*object_b
)
1190 if (!object_a
|| !object_b
) {
1194 if (object_a
->type
!= object_b
->type
) {
1198 ret
= compare_funcs
[object_a
->type
](object_a
, object_b
);