2 * objects.c: basic object system
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/ctf-writer/ref-internal.h>
33 #include <babeltrace/compiler.h>
35 #include <babeltrace/objects.h>
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))
46 enum bt_object_type type
;
47 struct bt_ctf_ref ref_count
;
52 struct bt_object bt_object_null_instance
= {
53 .type
= BT_OBJECT_TYPE_NULL
,
57 struct bt_object
*bt_object_null
= &bt_object_null_instance
;
59 struct bt_object_bool
{
60 struct bt_object base
;
64 struct bt_object_integer
{
65 struct bt_object base
;
69 struct bt_object_float
{
70 struct bt_object base
;
74 struct bt_object_string
{
75 struct bt_object base
;
79 struct bt_object_array
{
80 struct bt_object base
;
84 struct bt_object_map
{
85 struct bt_object base
;
90 void bt_object_string_destroy(struct bt_object
*object
)
92 g_string_free(BT_OBJECT_TO_STRING(object
)->gstr
, TRUE
);
96 void bt_object_array_destroy(struct bt_object
*object
)
99 * Pointer array's registered value destructor will take care
100 * of putting each contained object.
102 g_ptr_array_free(BT_OBJECT_TO_ARRAY(object
)->garray
, TRUE
);
106 void bt_object_map_destroy(struct bt_object
*object
)
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.
113 g_hash_table_destroy(BT_OBJECT_TO_MAP(object
)->ght
);
117 void (* 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
,
128 struct bt_object
*bt_object_null_copy(const struct bt_object
*null_obj
)
130 return bt_object_null
;
134 struct bt_object
*bt_object_bool_copy(const struct bt_object
*bool_obj
)
136 return bt_object_bool_create_init(BT_OBJECT_TO_BOOL(bool_obj
)->value
);
140 struct bt_object
*bt_object_integer_copy(const struct bt_object
*integer_obj
)
142 return bt_object_integer_create_init(
143 BT_OBJECT_TO_INTEGER(integer_obj
)->value
);
147 struct bt_object
*bt_object_float_copy(const struct bt_object
*float_obj
)
149 return bt_object_float_create_init(
150 BT_OBJECT_TO_FLOAT(float_obj
)->value
);
154 struct bt_object
*bt_object_string_copy(const struct bt_object
*string_obj
)
156 return bt_object_string_create_init(
157 BT_OBJECT_TO_STRING(string_obj
)->gstr
->str
);
161 struct bt_object
*bt_object_array_copy(const struct bt_object
*array_obj
)
165 struct bt_object
*copy_obj
;
166 struct bt_object_array
*typed_array_obj
;
168 typed_array_obj
= BT_OBJECT_TO_ARRAY(array_obj
);
169 copy_obj
= bt_object_array_create();
175 for (i
= 0; i
< typed_array_obj
->garray
->len
; ++i
) {
176 struct bt_object
*element_obj_copy
;
177 struct bt_object
*element_obj
=
178 bt_object_array_get(array_obj
, i
);
181 BT_OBJECT_PUT(copy_obj
);
185 element_obj_copy
= bt_object_copy(element_obj
);
186 BT_OBJECT_PUT(element_obj
);
188 if (!element_obj_copy
) {
189 BT_OBJECT_PUT(copy_obj
);
193 ret
= bt_object_array_append(copy_obj
, element_obj_copy
);
194 BT_OBJECT_PUT(element_obj_copy
);
197 BT_OBJECT_PUT(copy_obj
);
207 struct bt_object
*bt_object_map_copy(const struct bt_object
*map_obj
)
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
;
216 typed_map_obj
= BT_OBJECT_TO_MAP(map_obj
);
217 copy_obj
= bt_object_map_create();
223 g_hash_table_iter_init(&iter
, typed_map_obj
->ght
);
225 while (g_hash_table_iter_next(&iter
, &key
, &element_obj
)) {
226 const char *key_str
= g_quark_to_string((unsigned long) key
);
228 element_obj_copy
= bt_object_copy(element_obj
);
230 if (!element_obj_copy
) {
231 BT_OBJECT_PUT(copy_obj
);
235 ret
= bt_object_map_insert(copy_obj
, key_str
, element_obj_copy
);
236 BT_OBJECT_PUT(element_obj_copy
);
239 BT_OBJECT_PUT(copy_obj
);
249 struct 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
,
260 bool bt_object_null_compare(const struct bt_object
*object_a
,
261 const struct bt_object
*object_b
)
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.
272 bool bt_object_bool_compare(const struct bt_object
*object_a
,
273 const struct bt_object
*object_b
)
275 return BT_OBJECT_TO_BOOL(object_a
)->value
==
276 BT_OBJECT_TO_BOOL(object_b
)->value
;
280 bool bt_object_integer_compare(const struct bt_object
*object_a
,
281 const struct bt_object
*object_b
)
283 return BT_OBJECT_TO_INTEGER(object_a
)->value
==
284 BT_OBJECT_TO_INTEGER(object_b
)->value
;
288 bool bt_object_float_compare(const struct bt_object
*object_a
,
289 const struct bt_object
*object_b
)
291 return BT_OBJECT_TO_FLOAT(object_a
)->value
==
292 BT_OBJECT_TO_FLOAT(object_b
)->value
;
296 bool bt_object_string_compare(const struct bt_object
*object_a
,
297 const struct bt_object
*object_b
)
299 return !strcmp(BT_OBJECT_TO_STRING(object_a
)->gstr
->str
,
300 BT_OBJECT_TO_STRING(object_b
)->gstr
->str
);
304 bool bt_object_array_compare(const struct bt_object
*object_a
,
305 const struct bt_object
*object_b
)
309 const struct bt_object_array
*array_obj_a
=
310 BT_OBJECT_TO_ARRAY(object_a
);
312 if (bt_object_array_size(object_a
) != bt_object_array_size(object_b
)) {
317 for (i
= 0; i
< array_obj_a
->garray
->len
; ++i
) {
318 struct bt_object
*element_obj_a
;
319 struct bt_object
*element_obj_b
;
321 element_obj_a
= bt_object_array_get(object_a
, i
);
322 element_obj_b
= bt_object_array_get(object_b
, i
);
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
);
331 BT_OBJECT_PUT(element_obj_a
);
332 BT_OBJECT_PUT(element_obj_b
);
340 bool bt_object_map_compare(const struct bt_object
*object_a
,
341 const struct bt_object
*object_b
)
345 gpointer key
, element_obj_a
;
346 const struct bt_object_map
*map_obj_a
= BT_OBJECT_TO_MAP(object_a
);
348 if (bt_object_map_size(object_a
) != bt_object_map_size(object_b
)) {
353 g_hash_table_iter_init(&iter
, map_obj_a
->ght
);
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
);
359 element_obj_b
= bt_object_map_get(object_b
, key_str
);
361 if (!bt_object_compare(element_obj_a
, element_obj_b
)) {
362 BT_OBJECT_PUT(element_obj_b
);
367 BT_OBJECT_PUT(element_obj_b
);
375 bool (* 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
,
386 void bt_object_null_freeze(struct bt_object
*object
)
390 void bt_object_generic_freeze(struct bt_object
*object
)
392 object
->is_frozen
= true;
395 void bt_object_array_freeze(struct bt_object
*object
)
398 struct bt_object_array
*typed_array_obj
=
399 BT_OBJECT_TO_ARRAY(object
);
401 for (i
= 0; i
< typed_array_obj
->garray
->len
; ++i
) {
402 struct bt_object
*element_obj
=
403 g_ptr_array_index(typed_array_obj
->garray
, i
);
405 bt_object_freeze(element_obj
);
408 bt_object_generic_freeze(object
);
411 void bt_object_map_freeze(struct bt_object
*object
)
414 gpointer key
, element_obj
;
415 const struct bt_object_map
*map_obj
= BT_OBJECT_TO_MAP(object
);
417 g_hash_table_iter_init(&iter
, map_obj
->ght
);
419 while (g_hash_table_iter_next(&iter
, &key
, &element_obj
)) {
420 bt_object_freeze(element_obj
);
423 bt_object_generic_freeze(object
);
427 void (* 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
,
438 void bt_object_destroy(struct bt_ctf_ref
*ref_count
)
440 struct bt_object
*object
;
442 object
= container_of(ref_count
, struct bt_object
, ref_count
);
443 assert(object
->type
!= BT_OBJECT_TYPE_UNKNOWN
);
445 if (bt_object_is_null(object
)) {
449 if (destroy_funcs
[object
->type
]) {
450 destroy_funcs
[object
->type
](object
);
456 void bt_object_get(struct bt_object
*object
)
462 bt_ctf_ref_get(&object
->ref_count
);
468 void bt_object_put(struct bt_object
*object
)
474 bt_ctf_ref_put(&object
->ref_count
, bt_object_destroy
);
480 enum bt_object_status
bt_object_freeze(struct bt_object
*object
)
482 enum bt_object_status ret
= BT_OBJECT_STATUS_OK
;
485 ret
= BT_OBJECT_STATUS_INVAL
;
489 freeze_funcs
[object
->type
](object
);
495 bool bt_object_is_frozen(const struct bt_object
*object
)
497 return object
&& object
->is_frozen
;
500 enum bt_object_type
bt_object_get_type(const struct bt_object
*object
)
503 return BT_OBJECT_TYPE_UNKNOWN
;
510 struct bt_object
bt_object_create_base(enum bt_object_type type
)
512 struct bt_object base
;
515 base
.is_frozen
= false;
516 bt_ctf_ref_init(&base
.ref_count
);
521 struct bt_object
*bt_object_bool_create_init(bool val
)
523 struct bt_object_bool
*bool_obj
;
525 bool_obj
= g_new0(struct bt_object_bool
, 1);
531 bool_obj
->base
= bt_object_create_base(BT_OBJECT_TYPE_BOOL
);
532 bool_obj
->value
= val
;
535 return BT_OBJECT_FROM_CONCRETE(bool_obj
);
538 struct bt_object
*bt_object_bool_create(void)
540 return bt_object_bool_create_init(false);
543 struct bt_object
*bt_object_integer_create_init(int64_t val
)
545 struct bt_object_integer
*integer_obj
;
547 integer_obj
= g_new0(struct bt_object_integer
, 1);
553 integer_obj
->base
= bt_object_create_base(BT_OBJECT_TYPE_INTEGER
);
554 integer_obj
->value
= val
;
557 return BT_OBJECT_FROM_CONCRETE(integer_obj
);
560 struct bt_object
*bt_object_integer_create(void)
562 return bt_object_integer_create_init(0);
565 struct bt_object
*bt_object_float_create_init(double val
)
567 struct bt_object_float
*float_obj
;
569 float_obj
= g_new0(struct bt_object_float
, 1);
575 float_obj
->base
= bt_object_create_base(BT_OBJECT_TYPE_FLOAT
);
576 float_obj
->value
= val
;
579 return BT_OBJECT_FROM_CONCRETE(float_obj
);
582 struct bt_object
*bt_object_float_create(void)
584 return bt_object_float_create_init(0.);
587 struct bt_object
*bt_object_string_create_init(const char *val
)
589 struct bt_object_string
*string_obj
= NULL
;
595 string_obj
= g_new0(struct bt_object_string
, 1);
601 string_obj
->base
= bt_object_create_base(BT_OBJECT_TYPE_STRING
);
602 string_obj
->gstr
= g_string_new(val
);
604 if (!string_obj
->gstr
) {
611 return BT_OBJECT_FROM_CONCRETE(string_obj
);
614 struct bt_object
*bt_object_string_create(void)
616 return bt_object_string_create_init("");
619 struct bt_object
*bt_object_array_create(void)
621 struct bt_object_array
*array_obj
;
623 array_obj
= g_new0(struct bt_object_array
, 1);
629 array_obj
->base
= bt_object_create_base(BT_OBJECT_TYPE_ARRAY
);
630 array_obj
->garray
= g_ptr_array_new_full(0,
631 (GDestroyNotify
) bt_object_put
);
633 if (!array_obj
->garray
) {
640 return BT_OBJECT_FROM_CONCRETE(array_obj
);
643 struct bt_object
*bt_object_map_create(void)
645 struct bt_object_map
*map_obj
;
647 map_obj
= g_new0(struct bt_object_map
, 1);
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
);
664 return BT_OBJECT_FROM_CONCRETE(map_obj
);
667 enum bt_object_status
bt_object_bool_get(const struct bt_object
*bool_obj
,
670 enum bt_object_status ret
= BT_OBJECT_STATUS_OK
;
671 struct bt_object_bool
*typed_bool_obj
= BT_OBJECT_TO_BOOL(bool_obj
);
673 if (!bool_obj
|| !bt_object_is_bool(bool_obj
) || !val
) {
674 ret
= BT_OBJECT_STATUS_INVAL
;
678 *val
= typed_bool_obj
->value
;
684 enum bt_object_status
bt_object_bool_set(struct bt_object
*bool_obj
, bool val
)
686 enum bt_object_status ret
= BT_OBJECT_STATUS_OK
;
687 struct bt_object_bool
*typed_bool_obj
= BT_OBJECT_TO_BOOL(bool_obj
);
689 if (!bool_obj
|| !bt_object_is_bool(bool_obj
)) {
690 ret
= BT_OBJECT_STATUS_INVAL
;
694 if (bool_obj
->is_frozen
) {
695 ret
= BT_OBJECT_STATUS_FROZEN
;
699 typed_bool_obj
->value
= val
;
705 enum bt_object_status
bt_object_integer_get(const struct bt_object
*integer_obj
,
708 enum bt_object_status ret
= BT_OBJECT_STATUS_OK
;
709 struct bt_object_integer
*typed_integer_obj
=
710 BT_OBJECT_TO_INTEGER(integer_obj
);
712 if (!integer_obj
|| !bt_object_is_integer(integer_obj
) || !val
) {
713 ret
= BT_OBJECT_STATUS_INVAL
;
717 *val
= typed_integer_obj
->value
;
723 enum bt_object_status
bt_object_integer_set(struct bt_object
*integer_obj
,
726 enum bt_object_status ret
= BT_OBJECT_STATUS_OK
;
727 struct bt_object_integer
*typed_integer_obj
=
728 BT_OBJECT_TO_INTEGER(integer_obj
);
730 if (!integer_obj
|| !bt_object_is_integer(integer_obj
)) {
731 ret
= BT_OBJECT_STATUS_INVAL
;
735 if (integer_obj
->is_frozen
) {
736 ret
= BT_OBJECT_STATUS_FROZEN
;
740 typed_integer_obj
->value
= val
;
746 enum bt_object_status
bt_object_float_get(const struct bt_object
*float_obj
,
749 enum bt_object_status ret
= BT_OBJECT_STATUS_OK
;
750 struct bt_object_float
*typed_float_obj
=
751 BT_OBJECT_TO_FLOAT(float_obj
);
753 if (!float_obj
|| !bt_object_is_float(float_obj
) || !val
) {
754 ret
= BT_OBJECT_STATUS_INVAL
;
758 *val
= typed_float_obj
->value
;
764 enum bt_object_status
bt_object_float_set(struct bt_object
*float_obj
,
767 enum bt_object_status ret
= BT_OBJECT_STATUS_OK
;
768 struct bt_object_float
*typed_float_obj
=
769 BT_OBJECT_TO_FLOAT(float_obj
);
771 if (!float_obj
|| !bt_object_is_float(float_obj
)) {
772 ret
= BT_OBJECT_STATUS_INVAL
;
776 if (float_obj
->is_frozen
) {
777 ret
= BT_OBJECT_STATUS_FROZEN
;
781 typed_float_obj
->value
= val
;
787 enum bt_object_status
bt_object_string_get(const struct bt_object
*string_obj
,
790 enum bt_object_status ret
= BT_OBJECT_STATUS_OK
;
791 struct bt_object_string
*typed_string_obj
=
792 BT_OBJECT_TO_STRING(string_obj
);
794 if (!string_obj
|| !bt_object_is_string(string_obj
) || !val
) {
795 ret
= BT_OBJECT_STATUS_INVAL
;
799 *val
= typed_string_obj
->gstr
->str
;
805 enum bt_object_status
bt_object_string_set(struct bt_object
*string_obj
,
808 enum bt_object_status ret
= BT_OBJECT_STATUS_OK
;
809 struct bt_object_string
*typed_string_obj
=
810 BT_OBJECT_TO_STRING(string_obj
);
812 if (!string_obj
|| !bt_object_is_string(string_obj
) || !val
) {
813 ret
= BT_OBJECT_STATUS_INVAL
;
817 if (string_obj
->is_frozen
) {
818 ret
= BT_OBJECT_STATUS_FROZEN
;
822 g_string_assign(typed_string_obj
->gstr
, val
);
828 int bt_object_array_size(const struct bt_object
*array_obj
)
831 struct bt_object_array
*typed_array_obj
=
832 BT_OBJECT_TO_ARRAY(array_obj
);
834 if (!array_obj
|| !bt_object_is_array(array_obj
)) {
835 ret
= BT_OBJECT_STATUS_INVAL
;
839 ret
= (int) typed_array_obj
->garray
->len
;
845 bool bt_object_array_is_empty(const struct bt_object
*array_obj
)
847 return bt_object_array_size(array_obj
) == 0;
850 struct bt_object
*bt_object_array_get(const struct bt_object
*array_obj
,
853 struct bt_object
*ret
;
854 struct bt_object_array
*typed_array_obj
=
855 BT_OBJECT_TO_ARRAY(array_obj
);
857 if (!array_obj
|| !bt_object_is_array(array_obj
) ||
858 index
>= typed_array_obj
->garray
->len
) {
863 ret
= g_ptr_array_index(typed_array_obj
->garray
, index
);
870 enum bt_object_status
bt_object_array_append(struct bt_object
*array_obj
,
871 struct bt_object
*element_obj
)
873 enum bt_object_status ret
= BT_OBJECT_STATUS_OK
;
874 struct bt_object_array
*typed_array_obj
=
875 BT_OBJECT_TO_ARRAY(array_obj
);
877 if (!array_obj
|| !bt_object_is_array(array_obj
) || !element_obj
) {
878 ret
= BT_OBJECT_STATUS_INVAL
;
882 if (array_obj
->is_frozen
) {
883 ret
= BT_OBJECT_STATUS_FROZEN
;
887 g_ptr_array_add(typed_array_obj
->garray
, element_obj
);
888 bt_object_get(element_obj
);
894 enum bt_object_status
bt_object_array_append_bool(struct bt_object
*array_obj
,
897 enum bt_object_status ret
;
898 struct bt_object
*bool_obj
= NULL
;
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
);
907 enum bt_object_status
bt_object_array_append_integer(
908 struct bt_object
*array_obj
, int64_t val
)
910 enum bt_object_status ret
;
911 struct bt_object
*integer_obj
= NULL
;
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
);
920 enum bt_object_status
bt_object_array_append_float(struct bt_object
*array_obj
,
923 enum bt_object_status ret
;
924 struct bt_object
*float_obj
= NULL
;
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
);
933 enum bt_object_status
bt_object_array_append_string(struct bt_object
*array_obj
,
936 enum bt_object_status ret
;
937 struct bt_object
*string_obj
= NULL
;
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
);
946 enum bt_object_status
bt_object_array_append_array(struct bt_object
*array_obj
)
948 enum bt_object_status ret
;
949 struct bt_object
*empty_array_obj
= NULL
;
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
);
958 enum bt_object_status
bt_object_array_append_map(struct bt_object
*array_obj
)
960 enum bt_object_status ret
;
961 struct bt_object
*map_obj
= NULL
;
963 map_obj
= bt_object_map_create();
964 ret
= bt_object_array_append(array_obj
, map_obj
);
965 bt_object_put(map_obj
);
970 enum bt_object_status
bt_object_array_set(struct bt_object
*array_obj
,
971 size_t index
, struct bt_object
*element_obj
)
973 enum bt_object_status ret
= BT_OBJECT_STATUS_OK
;
974 struct bt_object_array
*typed_array_obj
=
975 BT_OBJECT_TO_ARRAY(array_obj
);
977 if (!array_obj
|| !bt_object_is_array(array_obj
) || !element_obj
||
978 index
>= typed_array_obj
->garray
->len
) {
979 ret
= BT_OBJECT_STATUS_INVAL
;
983 if (array_obj
->is_frozen
) {
984 ret
= BT_OBJECT_STATUS_FROZEN
;
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
);
996 int bt_object_map_size(const struct bt_object
*map_obj
)
999 struct bt_object_map
*typed_map_obj
= BT_OBJECT_TO_MAP(map_obj
);
1001 if (!map_obj
|| !bt_object_is_map(map_obj
)) {
1002 ret
= BT_OBJECT_STATUS_INVAL
;
1006 ret
= (int) g_hash_table_size(typed_map_obj
->ght
);
1012 bool bt_object_map_is_empty(const struct bt_object
*map_obj
)
1014 return bt_object_map_size(map_obj
) == 0;
1017 struct bt_object
*bt_object_map_get(const struct bt_object
*map_obj
,
1021 struct bt_object
*ret
;
1022 struct bt_object_map
*typed_map_obj
= BT_OBJECT_TO_MAP(map_obj
);
1024 if (!map_obj
|| !bt_object_is_map(map_obj
) || !key
) {
1029 quark
= g_quark_from_string(key
);
1030 ret
= g_hash_table_lookup(typed_map_obj
->ght
, GUINT_TO_POINTER(quark
));
1040 bool bt_object_map_has_key(const struct bt_object
*map_obj
, const char *key
)
1044 struct bt_object_map
*typed_map_obj
= BT_OBJECT_TO_MAP(map_obj
);
1046 if (!map_obj
|| !bt_object_is_map(map_obj
) || !key
) {
1051 quark
= g_quark_from_string(key
);
1052 ret
= g_hash_table_contains(typed_map_obj
->ght
,
1053 GUINT_TO_POINTER(quark
));
1059 enum bt_object_status
bt_object_map_insert(struct bt_object
*map_obj
,
1060 const char *key
, struct bt_object
*element_obj
)
1063 enum bt_object_status ret
= BT_OBJECT_STATUS_OK
;
1064 struct bt_object_map
*typed_map_obj
= BT_OBJECT_TO_MAP(map_obj
);
1066 if (!map_obj
|| !bt_object_is_map(map_obj
) || !key
|| !element_obj
) {
1067 ret
= BT_OBJECT_STATUS_INVAL
;
1071 if (map_obj
->is_frozen
) {
1072 ret
= BT_OBJECT_STATUS_FROZEN
;
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
);
1085 enum bt_object_status
bt_object_map_insert_bool(struct bt_object
*map_obj
,
1086 const char *key
, bool val
)
1088 enum bt_object_status ret
;
1089 struct bt_object
*bool_obj
= NULL
;
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
);
1098 enum bt_object_status
bt_object_map_insert_integer(struct bt_object
*map_obj
,
1099 const char *key
, int64_t val
)
1101 enum bt_object_status ret
;
1102 struct bt_object
*integer_obj
= NULL
;
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
);
1111 enum bt_object_status
bt_object_map_insert_float(struct bt_object
*map_obj
,
1112 const char *key
, double val
)
1114 enum bt_object_status ret
;
1115 struct bt_object
*float_obj
= NULL
;
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
);
1124 enum bt_object_status
bt_object_map_insert_string(struct bt_object
*map_obj
,
1125 const char *key
, const char *val
)
1127 enum bt_object_status ret
;
1128 struct bt_object
*string_obj
= NULL
;
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
);
1137 enum bt_object_status
bt_object_map_insert_array(struct bt_object
*map_obj
,
1140 enum bt_object_status ret
;
1141 struct bt_object
*array_obj
= NULL
;
1143 array_obj
= bt_object_array_create();
1144 ret
= bt_object_map_insert(map_obj
, key
, array_obj
);
1145 bt_object_put(array_obj
);
1150 enum bt_object_status
bt_object_map_insert_map(struct bt_object
*map_obj
,
1153 enum bt_object_status ret
;
1154 struct bt_object
*empty_map_obj
= NULL
;
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
);
1163 enum bt_object_status
bt_object_map_foreach(const struct bt_object
*map_obj
,
1164 bt_object_map_foreach_cb cb
, void *data
)
1166 enum bt_object_status ret
= BT_OBJECT_STATUS_OK
;
1167 gpointer key
, element_obj
;
1168 GHashTableIter iter
;
1169 struct bt_object_map
*typed_map_obj
= BT_OBJECT_TO_MAP(map_obj
);
1171 if (!map_obj
|| !bt_object_is_map(map_obj
) || !cb
) {
1172 ret
= BT_OBJECT_STATUS_INVAL
;
1176 g_hash_table_iter_init(&iter
, typed_map_obj
->ght
);
1178 while (g_hash_table_iter_next(&iter
, &key
, &element_obj
)) {
1179 const char *key_str
= g_quark_to_string((unsigned long) key
);
1181 if (!cb(key_str
, element_obj
, data
)) {
1182 ret
= BT_OBJECT_STATUS_CANCELLED
;
1191 struct bt_object
*bt_object_copy(const struct bt_object
*object
)
1193 struct bt_object
*copy_obj
= NULL
;
1199 copy_obj
= copy_funcs
[object
->type
](object
);
1205 bool bt_object_compare(const struct bt_object
*object_a
,
1206 const struct bt_object
*object_b
)
1210 if (!object_a
|| !object_b
) {
1214 if (object_a
->type
!= object_b
->type
) {
1218 ret
= compare_funcs
[object_a
->type
](object_a
, object_b
);