lib: rename *_IS_TYPE() and *_HAS_ID() macros -> *_HAS_TYPE()
[babeltrace.git] / src / lib / value.c
CommitLineData
dac5c838 1/*
0235b0db 2 * SPDX-License-Identifier: MIT
dac5c838 3 *
0235b0db 4 * Copyright (c) 2015-2018 Philippe Proulx <pproulx@efficios.com>
dac5c838
PP
5 */
6
350ad6c1 7#define BT_LOG_TAG "LIB/VALUE"
c2d9d9cf 8#include "lib/logging.h"
0f5e83e5 9
dac5c838
PP
10#include <stdlib.h>
11#include <string.h>
dac5c838 12#include <string.h>
2f42aa0a 13#include <inttypes.h>
4fa90f32
PP
14#include <babeltrace2/babeltrace.h>
15
578e048b
MJ
16#include "compat/compiler.h"
17#include "common/common.h"
578e048b 18#include "compat/glib.h"
d98421f2 19#include "lib/assert-cond.h"
578e048b
MJ
20#include "lib/value.h"
21#include "common/assert.h"
d24d5663 22#include "func-status.h"
2f42aa0a 23
2bdc32f7
PP
24#define BT_ASSERT_PRE_DEV_VALUE_HOT(_value, _name) \
25 BT_ASSERT_PRE_DEV_HOT(((struct bt_value *) (_value)), (_name), \
26 ": %!+v", (_value))
27
dac5c838
PP
28#define BT_VALUE_TO_BOOL(_base) ((struct bt_value_bool *) (_base))
29#define BT_VALUE_TO_INTEGER(_base) ((struct bt_value_integer *) (_base))
a373bf69 30#define BT_VALUE_TO_REAL(_base) ((struct bt_value_real *) (_base))
dac5c838
PP
31#define BT_VALUE_TO_STRING(_base) ((struct bt_value_string *) (_base))
32#define BT_VALUE_TO_ARRAY(_base) ((struct bt_value_array *) (_base))
33#define BT_VALUE_TO_MAP(_base) ((struct bt_value_map *) (_base))
34
3fea54f6
PP
35static
36void bt_value_null_instance_release_func(struct bt_object *obj)
37{
38 BT_LOGW("Releasing the null value singleton: addr=%p", obj);
39}
40
dac5c838
PP
41static
42struct bt_value bt_value_null_instance = {
f685129c 43 .base = {
312c056a 44 .is_shared = true,
3fea54f6
PP
45 .ref_count = 1,
46 .release_func = bt_value_null_instance_release_func,
47 .spec_release_func = NULL,
48 .parent_is_owner_listener_func = NULL,
49 .parent = NULL,
f685129c 50 },
dac5c838 51 .type = BT_VALUE_TYPE_NULL,
f6ccaed9 52 .frozen = BT_TRUE,
dac5c838
PP
53};
54
211796dc 55struct bt_value *const bt_value_null = &bt_value_null_instance;
dac5c838 56
dac5c838 57static
83509119 58void bt_value_destroy(struct bt_object *obj);
dac5c838
PP
59
60static
61void bt_value_string_destroy(struct bt_value *object)
62{
63 g_string_free(BT_VALUE_TO_STRING(object)->gstr, TRUE);
238b7404 64 BT_VALUE_TO_STRING(object)->gstr = NULL;
dac5c838
PP
65}
66
67static
68void bt_value_array_destroy(struct bt_value *object)
69{
70 /*
71 * Pointer array's registered value destructor will take care
72 * of putting each contained object.
73 */
74 g_ptr_array_free(BT_VALUE_TO_ARRAY(object)->garray, TRUE);
238b7404 75 BT_VALUE_TO_ARRAY(object)->garray = NULL;
dac5c838
PP
76}
77
78static
79void bt_value_map_destroy(struct bt_value *object)
80{
81 /*
82 * Hash table's registered value destructor will take care of
83 * putting each contained object. Keys are GQuarks and cannot
84 * be destroyed anyway.
85 */
86 g_hash_table_destroy(BT_VALUE_TO_MAP(object)->ght);
238b7404 87 BT_VALUE_TO_MAP(object)->ght = NULL;
dac5c838
PP
88}
89
90static
91void (* const destroy_funcs[])(struct bt_value *) = {
fdd3a2da
PP
92 [BT_VALUE_TYPE_NULL] = NULL,
93 [BT_VALUE_TYPE_BOOL] = NULL,
94 [BT_VALUE_TYPE_UNSIGNED_INTEGER] = NULL,
95 [BT_VALUE_TYPE_SIGNED_INTEGER] = NULL,
96 [BT_VALUE_TYPE_REAL] = NULL,
97 [BT_VALUE_TYPE_STRING] = bt_value_string_destroy,
98 [BT_VALUE_TYPE_ARRAY] = bt_value_array_destroy,
99 [BT_VALUE_TYPE_MAP] = bt_value_map_destroy,
dac5c838
PP
100};
101
102static
05e21286 103struct bt_value *bt_value_null_copy(const struct bt_value *null_obj)
dac5c838 104{
d164ff16
SM
105 BT_ASSERT(null_obj == bt_value_null);
106
6871026b 107 bt_object_get_ref_no_null_check(bt_value_null);
da91b29a 108 return (void *) bt_value_null;
dac5c838
PP
109}
110
111static
05e21286 112struct bt_value *bt_value_bool_copy(const struct bt_value *bool_obj)
dac5c838 113{
05e21286 114 return bt_value_bool_create_init(
601b0d3c 115 BT_VALUE_TO_BOOL(bool_obj)->value);
dac5c838
PP
116}
117
fdd3a2da
PP
118static inline
119struct bt_value *bt_value_integer_create_init(enum bt_value_type type,
120 uint64_t uval);
121
dac5c838 122static
05e21286 123struct bt_value *bt_value_integer_copy(
da91b29a 124 const struct bt_value *integer_obj)
dac5c838 125{
fdd3a2da
PP
126 return bt_value_integer_create_init(integer_obj->type,
127 BT_VALUE_TO_INTEGER(integer_obj)->value.u);
dac5c838
PP
128}
129
130static
05e21286 131struct bt_value *bt_value_real_copy(const struct bt_value *real_obj)
dac5c838 132{
05e21286 133 return bt_value_real_create_init(
a373bf69 134 BT_VALUE_TO_REAL(real_obj)->value);
dac5c838
PP
135}
136
137static
05e21286 138struct bt_value *bt_value_string_copy(const struct bt_value *string_obj)
dac5c838 139{
05e21286 140 return bt_value_string_create_init(
dac5c838
PP
141 BT_VALUE_TO_STRING(string_obj)->gstr->str);
142}
143
144static
05e21286 145struct bt_value *bt_value_array_copy(const struct bt_value *array_obj)
dac5c838
PP
146{
147 int i;
148 int ret;
05e21286 149 struct bt_value *copy_obj;
dac5c838
PP
150 struct bt_value_array *typed_array_obj;
151
2f42aa0a 152 BT_LOGD("Copying array value: addr=%p", array_obj);
dac5c838 153 typed_array_obj = BT_VALUE_TO_ARRAY(array_obj);
05e21286 154 copy_obj = bt_value_array_create();
dac5c838 155 if (!copy_obj) {
870631a2 156 BT_LIB_LOGE_APPEND_CAUSE("Cannot create empty array value.");
dac5c838
PP
157 goto end;
158 }
159
160 for (i = 0; i < typed_array_obj->garray->len; ++i) {
05e21286
PP
161 struct bt_value *element_obj_copy = NULL;
162 const struct bt_value *element_obj =
163 bt_value_array_borrow_element_by_index_const(
601b0d3c 164 array_obj, i);
dac5c838 165
40b59ed9
PP
166 BT_LOGD("Copying array value's element: element-addr=%p, "
167 "index=%d", element_obj, i);
6be5a99e 168 ret = bt_value_copy(element_obj, &element_obj_copy);
601b0d3c 169 if (ret) {
870631a2
PP
170 BT_LIB_LOGE_APPEND_CAUSE(
171 "Cannot copy array value's element: "
2f42aa0a
PP
172 "array-addr=%p, index=%d",
173 array_obj, i);
65300d60 174 BT_OBJECT_PUT_REF_AND_RESET(copy_obj);
dac5c838
PP
175 goto end;
176 }
177
601b0d3c 178 BT_ASSERT(element_obj_copy);
05e21286 179 ret = bt_value_array_append_element(copy_obj,
da91b29a 180 (void *) element_obj_copy);
65300d60 181 BT_OBJECT_PUT_REF_AND_RESET(element_obj_copy);
dac5c838 182 if (ret) {
870631a2
PP
183 BT_LIB_LOGE_APPEND_CAUSE(
184 "Cannot append to array value: addr=%p",
2f42aa0a 185 array_obj);
65300d60 186 BT_OBJECT_PUT_REF_AND_RESET(copy_obj);
dac5c838
PP
187 goto end;
188 }
189 }
190
a704fb0b
PP
191 BT_LOGD("Copied array value: original-addr=%p, copy-addr=%p",
192 array_obj, copy_obj);
2f42aa0a 193
dac5c838
PP
194end:
195 return copy_obj;
196}
197
198static
05e21286 199struct bt_value *bt_value_map_copy(const struct bt_value *map_obj)
dac5c838
PP
200{
201 int ret;
202 GHashTableIter iter;
203 gpointer key, element_obj;
05e21286
PP
204 struct bt_value *copy_obj;
205 struct bt_value *element_obj_copy = NULL;
dac5c838
PP
206 struct bt_value_map *typed_map_obj;
207
2f42aa0a 208 BT_LOGD("Copying map value: addr=%p", map_obj);
dac5c838 209 typed_map_obj = BT_VALUE_TO_MAP(map_obj);
05e21286 210 copy_obj = bt_value_map_create();
dac5c838
PP
211 if (!copy_obj) {
212 goto end;
213 }
214
215 g_hash_table_iter_init(&iter, typed_map_obj->ght);
216
217 while (g_hash_table_iter_next(&iter, &key, &element_obj)) {
5b44aff2 218 const char *key_str = g_quark_to_string(GPOINTER_TO_UINT(key));
dac5c838 219
f6ccaed9 220 BT_ASSERT(key_str);
40b59ed9
PP
221 BT_LOGD("Copying map value's element: element-addr=%p, "
222 "key=\"%s\"", element_obj, key_str);
6be5a99e 223 ret = bt_value_copy(element_obj, &element_obj_copy);
601b0d3c 224 if (ret) {
870631a2
PP
225 BT_LIB_LOGE_APPEND_CAUSE(
226 "Cannot copy map value's element: "
2f42aa0a
PP
227 "map-addr=%p, key=\"%s\"",
228 map_obj, key_str);
65300d60 229 BT_OBJECT_PUT_REF_AND_RESET(copy_obj);
dac5c838
PP
230 goto end;
231 }
232
601b0d3c 233 BT_ASSERT(element_obj_copy);
05e21286 234 ret = bt_value_map_insert_entry(copy_obj, key_str,
da91b29a 235 (void *) element_obj_copy);
65300d60 236 BT_OBJECT_PUT_REF_AND_RESET(element_obj_copy);
dac5c838 237 if (ret) {
870631a2
PP
238 BT_LIB_LOGE_APPEND_CAUSE(
239 "Cannot insert into map value: addr=%p, key=\"%s\"",
2f42aa0a 240 map_obj, key_str);
65300d60 241 BT_OBJECT_PUT_REF_AND_RESET(copy_obj);
dac5c838
PP
242 goto end;
243 }
244 }
245
2f42aa0a
PP
246 BT_LOGD("Copied map value: addr=%p", map_obj);
247
dac5c838
PP
248end:
249 return copy_obj;
250}
251
252static
05e21286 253struct bt_value *(* const copy_funcs[])(const struct bt_value *) = {
fdd3a2da
PP
254 [BT_VALUE_TYPE_NULL] = bt_value_null_copy,
255 [BT_VALUE_TYPE_BOOL] = bt_value_bool_copy,
256 [BT_VALUE_TYPE_UNSIGNED_INTEGER] = bt_value_integer_copy,
257 [BT_VALUE_TYPE_SIGNED_INTEGER] = bt_value_integer_copy,
258 [BT_VALUE_TYPE_REAL] = bt_value_real_copy,
259 [BT_VALUE_TYPE_STRING] = bt_value_string_copy,
260 [BT_VALUE_TYPE_ARRAY] = bt_value_array_copy,
261 [BT_VALUE_TYPE_MAP] = bt_value_map_copy,
dac5c838
PP
262};
263
264static
cd933d89 265bt_bool bt_value_null_is_equal(const struct bt_value *object_a,
dac5c838
PP
266 const struct bt_value *object_b)
267{
268 /*
cd933d89 269 * Always BT_TRUE since bt_value_is_equal() already checks if both
dac5c838
PP
270 * object_a and object_b have the same type, and in the case of
271 * null value objects, they're always the same if it is so.
272 */
c55a9f58 273 return BT_TRUE;
dac5c838
PP
274}
275
276static
cd933d89 277bt_bool bt_value_bool_is_equal(const struct bt_value *object_a,
dac5c838
PP
278 const struct bt_value *object_b)
279{
40b59ed9
PP
280 if (BT_VALUE_TO_BOOL(object_a)->value !=
281 BT_VALUE_TO_BOOL(object_b)->value) {
ef267d12 282 BT_LOGT("Boolean value objects are different: "
40b59ed9
PP
283 "bool-a-val=%d, bool-b-val=%d",
284 BT_VALUE_TO_BOOL(object_a)->value,
285 BT_VALUE_TO_BOOL(object_b)->value);
286 return BT_FALSE;
287 }
288
289 return BT_TRUE;
dac5c838
PP
290}
291
292static
cd933d89 293bt_bool bt_value_integer_is_equal(const struct bt_value *object_a,
dac5c838
PP
294 const struct bt_value *object_b)
295{
fdd3a2da
PP
296 if (BT_VALUE_TO_INTEGER(object_a)->value.u !=
297 BT_VALUE_TO_INTEGER(object_b)->value.u) {
298 if (object_a->type == BT_VALUE_TYPE_UNSIGNED_INTEGER) {
ef267d12 299 BT_LOGT("Unsigned integer value objects are different: "
fdd3a2da
PP
300 "int-a-val=%" PRIu64 ", int-b-val=%" PRIu64,
301 BT_VALUE_TO_INTEGER(object_a)->value.u,
302 BT_VALUE_TO_INTEGER(object_b)->value.u);
303 } else {
ef267d12 304 BT_LOGT("Signed integer value objects are different: "
fdd3a2da
PP
305 "int-a-val=%" PRId64 ", int-b-val=%" PRId64,
306 BT_VALUE_TO_INTEGER(object_a)->value.i,
307 BT_VALUE_TO_INTEGER(object_b)->value.i);
308 }
309
40b59ed9
PP
310 return BT_FALSE;
311 }
312
313 return BT_TRUE;
dac5c838
PP
314}
315
316static
cd933d89 317bt_bool bt_value_real_is_equal(const struct bt_value *object_a,
dac5c838
PP
318 const struct bt_value *object_b)
319{
a373bf69
PP
320 if (BT_VALUE_TO_REAL(object_a)->value !=
321 BT_VALUE_TO_REAL(object_b)->value) {
ef267d12 322 BT_LOGT("Real number value objects are different: "
a373bf69
PP
323 "real-a-val=%f, real-b-val=%f",
324 BT_VALUE_TO_REAL(object_a)->value,
325 BT_VALUE_TO_REAL(object_b)->value);
40b59ed9
PP
326 return BT_FALSE;
327 }
328
329 return BT_TRUE;
dac5c838
PP
330}
331
332static
cd933d89 333bt_bool bt_value_string_is_equal(const struct bt_value *object_a,
dac5c838
PP
334 const struct bt_value *object_b)
335{
40b59ed9
PP
336 if (strcmp(BT_VALUE_TO_STRING(object_a)->gstr->str,
337 BT_VALUE_TO_STRING(object_b)->gstr->str) != 0) {
ef267d12 338 BT_LOGT("String value objects are different: "
40b59ed9
PP
339 "string-a-val=\"%s\", string-b-val=\"%s\"",
340 BT_VALUE_TO_STRING(object_a)->gstr->str,
341 BT_VALUE_TO_STRING(object_b)->gstr->str);
342 return BT_FALSE;
343 }
344
345 return BT_TRUE;
dac5c838
PP
346}
347
348static
cd933d89 349bt_bool bt_value_array_is_equal(const struct bt_value *object_a,
dac5c838
PP
350 const struct bt_value *object_b)
351{
352 int i;
c55a9f58 353 bt_bool ret = BT_TRUE;
dac5c838
PP
354 const struct bt_value_array *array_obj_a =
355 BT_VALUE_TO_ARRAY(object_a);
356
393729a6
PP
357 if (bt_value_array_get_length(object_a) !=
358 bt_value_array_get_length(object_b)) {
ef267d12 359 BT_LOGT("Array values are different: size mismatch "
2f42aa0a
PP
360 "value-a-addr=%p, value-b-addr=%p, "
361 "value-a-size=%" PRId64 ", value-b-size=%" PRId64,
362 object_a, object_b,
393729a6
PP
363 bt_value_array_get_length(object_a),
364 bt_value_array_get_length(object_b));
c55a9f58 365 ret = BT_FALSE;
dac5c838
PP
366 goto end;
367 }
368
369 for (i = 0; i < array_obj_a->garray->len; ++i) {
05e21286
PP
370 const struct bt_value *element_obj_a;
371 const struct bt_value *element_obj_b;
dac5c838 372
05e21286 373 element_obj_a = bt_value_array_borrow_element_by_index_const(
da91b29a 374 object_a, i);
05e21286 375 element_obj_b = bt_value_array_borrow_element_by_index_const(
da91b29a 376 object_b, i);
dac5c838 377
cd933d89 378 if (!bt_value_is_equal(element_obj_a, element_obj_b)) {
ef267d12 379 BT_LOGT("Array values's elements are different: "
2f42aa0a 380 "value-a-addr=%p, value-b-addr=%p, index=%d",
32e87ceb 381 element_obj_a, element_obj_b, i);
c55a9f58 382 ret = BT_FALSE;
dac5c838
PP
383 goto end;
384 }
dac5c838
PP
385 }
386
387end:
388 return ret;
389}
390
391static
cd933d89 392bt_bool bt_value_map_is_equal(const struct bt_value *object_a,
dac5c838
PP
393 const struct bt_value *object_b)
394{
c55a9f58 395 bt_bool ret = BT_TRUE;
dac5c838
PP
396 GHashTableIter iter;
397 gpointer key, element_obj_a;
398 const struct bt_value_map *map_obj_a = BT_VALUE_TO_MAP(object_a);
399
601b0d3c
PP
400 if (bt_value_map_get_size(object_a) !=
401 bt_value_map_get_size(object_b)) {
ef267d12 402 BT_LOGT("Map values are different: size mismatch "
2f42aa0a
PP
403 "value-a-addr=%p, value-b-addr=%p, "
404 "value-a-size=%" PRId64 ", value-b-size=%" PRId64,
405 object_a, object_b,
07208d85
PP
406 bt_value_map_get_size(object_a),
407 bt_value_map_get_size(object_b));
c55a9f58 408 ret = BT_FALSE;
dac5c838
PP
409 goto end;
410 }
411
412 g_hash_table_iter_init(&iter, map_obj_a->ght);
413
414 while (g_hash_table_iter_next(&iter, &key, &element_obj_a)) {
05e21286 415 const struct bt_value *element_obj_b;
5b44aff2 416 const char *key_str = g_quark_to_string(GPOINTER_TO_UINT(key));
dac5c838 417
05e21286 418 element_obj_b = bt_value_map_borrow_entry_value_const(object_b,
da91b29a 419 key_str);
dac5c838 420
cd933d89 421 if (!bt_value_is_equal(element_obj_a, element_obj_b)) {
ef267d12 422 BT_LOGT("Map values's elements are different: "
2f42aa0a
PP
423 "value-a-addr=%p, value-b-addr=%p, key=\"%s\"",
424 element_obj_a, element_obj_b, key_str);
c55a9f58 425 ret = BT_FALSE;
dac5c838
PP
426 goto end;
427 }
dac5c838
PP
428 }
429
430end:
431 return ret;
432}
433
434static
cd933d89 435bt_bool (* const is_equal_funcs[])(const struct bt_value *,
dac5c838 436 const struct bt_value *) = {
cd933d89
FD
437 [BT_VALUE_TYPE_NULL] = bt_value_null_is_equal,
438 [BT_VALUE_TYPE_BOOL] = bt_value_bool_is_equal,
439 [BT_VALUE_TYPE_UNSIGNED_INTEGER] = bt_value_integer_is_equal,
440 [BT_VALUE_TYPE_SIGNED_INTEGER] = bt_value_integer_is_equal,
441 [BT_VALUE_TYPE_REAL] = bt_value_real_is_equal,
442 [BT_VALUE_TYPE_STRING] = bt_value_string_is_equal,
443 [BT_VALUE_TYPE_ARRAY] = bt_value_array_is_equal,
444 [BT_VALUE_TYPE_MAP] = bt_value_map_is_equal,
dac5c838
PP
445};
446
f6ccaed9 447static
dac5c838
PP
448void bt_value_null_freeze(struct bt_value *object)
449{
450}
451
f6ccaed9 452static
dac5c838
PP
453void bt_value_generic_freeze(struct bt_value *object)
454{
f6ccaed9 455 object->frozen = BT_TRUE;
dac5c838
PP
456}
457
f6ccaed9 458static
dac5c838
PP
459void bt_value_array_freeze(struct bt_value *object)
460{
461 int i;
462 struct bt_value_array *typed_array_obj =
463 BT_VALUE_TO_ARRAY(object);
464
465 for (i = 0; i < typed_array_obj->garray->len; ++i) {
f6ccaed9 466 bt_value_freeze(g_ptr_array_index(typed_array_obj->garray, i));
dac5c838
PP
467 }
468
469 bt_value_generic_freeze(object);
470}
471
f6ccaed9 472static
dac5c838
PP
473void bt_value_map_freeze(struct bt_value *object)
474{
475 GHashTableIter iter;
476 gpointer key, element_obj;
477 const struct bt_value_map *map_obj = BT_VALUE_TO_MAP(object);
478
479 g_hash_table_iter_init(&iter, map_obj->ght);
480
481 while (g_hash_table_iter_next(&iter, &key, &element_obj)) {
482 bt_value_freeze(element_obj);
483 }
484
485 bt_value_generic_freeze(object);
486}
487
488static
489void (* const freeze_funcs[])(struct bt_value *) = {
fdd3a2da
PP
490 [BT_VALUE_TYPE_NULL] = bt_value_null_freeze,
491 [BT_VALUE_TYPE_BOOL] = bt_value_generic_freeze,
492 [BT_VALUE_TYPE_UNSIGNED_INTEGER] = bt_value_generic_freeze,
493 [BT_VALUE_TYPE_SIGNED_INTEGER] = bt_value_generic_freeze,
494 [BT_VALUE_TYPE_REAL] = bt_value_generic_freeze,
495 [BT_VALUE_TYPE_STRING] = bt_value_generic_freeze,
496 [BT_VALUE_TYPE_ARRAY] = bt_value_array_freeze,
497 [BT_VALUE_TYPE_MAP] = bt_value_map_freeze,
dac5c838
PP
498};
499
500static
83509119 501void bt_value_destroy(struct bt_object *obj)
dac5c838 502{
83509119 503 struct bt_value *value;
dac5c838 504
83509119 505 value = container_of(obj, struct bt_value, base);
2f42aa0a
PP
506 BT_LOGD("Destroying value: addr=%p", value);
507
83509119 508 if (bt_value_is_null(value)) {
2f42aa0a 509 BT_LOGD_STR("Not destroying the null value singleton.");
dac5c838
PP
510 return;
511 }
512
83509119
JG
513 if (destroy_funcs[value->type]) {
514 destroy_funcs[value->type](value);
dac5c838
PP
515 }
516
83509119 517 g_free(value);
dac5c838
PP
518}
519
f6ccaed9 520BT_HIDDEN
d24d5663 521void _bt_value_freeze(const struct bt_value *c_object)
dac5c838 522{
05e21286 523 const struct bt_value *object = (void *) c_object;
dac5c838 524
f6ccaed9 525 BT_ASSERT(object);
dac5c838 526
f6ccaed9 527 if (object->frozen) {
2f42aa0a
PP
528 goto end;
529 }
530
531 BT_LOGD("Freezing value: addr=%p", object);
05e21286 532 freeze_funcs[object->type]((void *) object);
dac5c838
PP
533
534end:
d24d5663 535 return;
dac5c838
PP
536}
537
dac5c838
PP
538enum bt_value_type bt_value_get_type(const struct bt_value *object)
539{
bdb288b3 540 BT_ASSERT_PRE_DEV_NON_NULL(object, "Value object");
dac5c838
PP
541 return object->type;
542}
543
544static
545struct bt_value bt_value_create_base(enum bt_value_type type)
546{
3fea54f6 547 struct bt_value value;
dac5c838 548
3fea54f6
PP
549 value.type = type;
550 value.frozen = BT_FALSE;
551 bt_object_init_shared(&value.base, bt_value_destroy);
552 return value;
dac5c838
PP
553}
554
05e21286 555struct bt_value *bt_value_bool_create_init(bt_bool val)
dac5c838
PP
556{
557 struct bt_value_bool *bool_obj;
558
17f3083a
SM
559 BT_ASSERT_PRE_NO_ERROR();
560
2f42aa0a 561 BT_LOGD("Creating boolean value object: val=%d", val);
dac5c838 562 bool_obj = g_new0(struct bt_value_bool, 1);
dac5c838 563 if (!bool_obj) {
870631a2
PP
564 BT_LIB_LOGE_APPEND_CAUSE(
565 "Failed to allocate one boolean value object.");
dac5c838
PP
566 goto end;
567 }
568
569 bool_obj->base = bt_value_create_base(BT_VALUE_TYPE_BOOL);
570 bool_obj->value = val;
2f42aa0a 571 BT_LOGD("Created boolean value object: addr=%p", bool_obj);
dac5c838
PP
572
573end:
11cd69be 574 return (void *) bool_obj;
dac5c838
PP
575}
576
05e21286 577struct bt_value *bt_value_bool_create(void)
dac5c838 578{
17f3083a
SM
579 BT_ASSERT_PRE_NO_ERROR();
580
05e21286 581 return bt_value_bool_create_init(BT_FALSE);
dac5c838
PP
582}
583
fdd3a2da
PP
584static inline
585struct bt_value *bt_value_integer_create_init(enum bt_value_type type,
586 uint64_t uval)
dac5c838
PP
587{
588 struct bt_value_integer *integer_obj;
589
fdd3a2da
PP
590 BT_ASSERT(type == BT_VALUE_TYPE_UNSIGNED_INTEGER ||
591 type == BT_VALUE_TYPE_SIGNED_INTEGER);
592
593 if (type == BT_VALUE_TYPE_UNSIGNED_INTEGER) {
594 BT_LOGD("Creating unsigned integer value object: val=%" PRIu64,
595 uval);
596 } else {
597 BT_LOGD("Creating signed integer value object: val=%" PRId64,
598 (int64_t) uval);
599 }
600
dac5c838 601 integer_obj = g_new0(struct bt_value_integer, 1);
dac5c838 602 if (!integer_obj) {
870631a2
PP
603 BT_LIB_LOGE_APPEND_CAUSE(
604 "Failed to allocate one integer value object.");
dac5c838
PP
605 goto end;
606 }
607
fdd3a2da
PP
608 integer_obj->base = bt_value_create_base(type);
609 integer_obj->value.u = uval;
610 BT_LOGD("Created %ssigned integer value object: addr=%p",
611 type == BT_VALUE_TYPE_UNSIGNED_INTEGER ? "un" : "",
2f42aa0a 612 integer_obj);
dac5c838
PP
613
614end:
11cd69be 615 return (void *) integer_obj;
dac5c838
PP
616}
617
9c08c816 618struct bt_value *bt_value_integer_unsigned_create_init(uint64_t val)
fdd3a2da 619{
17f3083a
SM
620 BT_ASSERT_PRE_NO_ERROR();
621
fdd3a2da
PP
622 return bt_value_integer_create_init(BT_VALUE_TYPE_UNSIGNED_INTEGER,
623 val);
624}
625
9c08c816 626struct bt_value *bt_value_integer_unsigned_create(void)
fdd3a2da 627{
17f3083a
SM
628 BT_ASSERT_PRE_NO_ERROR();
629
9c08c816 630 return bt_value_integer_unsigned_create_init(0);
fdd3a2da
PP
631}
632
9c08c816 633struct bt_value *bt_value_integer_signed_create_init(int64_t val)
dac5c838 634{
17f3083a
SM
635 BT_ASSERT_PRE_NO_ERROR();
636
fdd3a2da
PP
637 return bt_value_integer_create_init(BT_VALUE_TYPE_SIGNED_INTEGER,
638 (uint64_t) val);
639}
640
9c08c816 641struct bt_value *bt_value_integer_signed_create(void)
fdd3a2da 642{
17f3083a
SM
643 BT_ASSERT_PRE_NO_ERROR();
644
9c08c816 645 return bt_value_integer_signed_create_init(0);
dac5c838
PP
646}
647
05e21286 648struct bt_value *bt_value_real_create_init(double val)
dac5c838 649{
a373bf69 650 struct bt_value_real *real_obj;
dac5c838 651
17f3083a
SM
652 BT_ASSERT_PRE_NO_ERROR();
653
a373bf69
PP
654 BT_LOGD("Creating real number value object: val=%f", val);
655 real_obj = g_new0(struct bt_value_real, 1);
656 if (!real_obj) {
870631a2
PP
657 BT_LIB_LOGE_APPEND_CAUSE(
658 "Failed to allocate one real number value object.");
dac5c838
PP
659 goto end;
660 }
661
a373bf69
PP
662 real_obj->base = bt_value_create_base(BT_VALUE_TYPE_REAL);
663 real_obj->value = val;
664 BT_LOGD("Created real number value object: addr=%p",
665 real_obj);
dac5c838
PP
666
667end:
11cd69be 668 return (void *) real_obj;
dac5c838
PP
669}
670
05e21286 671struct bt_value *bt_value_real_create(void)
dac5c838 672{
17f3083a
SM
673 BT_ASSERT_PRE_NO_ERROR();
674
05e21286 675 return bt_value_real_create_init(0.);
dac5c838
PP
676}
677
05e21286 678struct bt_value *bt_value_string_create_init(const char *val)
dac5c838
PP
679{
680 struct bt_value_string *string_obj = NULL;
681
17f3083a 682 BT_ASSERT_PRE_NO_ERROR();
870631a2 683 BT_ASSERT_PRE_NON_NULL(val, "Value");
17f3083a 684
003c7749 685 BT_LOGD("Creating string value object: val-len=%zu", strlen(val));
dac5c838 686 string_obj = g_new0(struct bt_value_string, 1);
dac5c838 687 if (!string_obj) {
870631a2
PP
688 BT_LIB_LOGE_APPEND_CAUSE(
689 "Failed to allocate one string object.");
dac5c838
PP
690 goto end;
691 }
692
693 string_obj->base = bt_value_create_base(BT_VALUE_TYPE_STRING);
694 string_obj->gstr = g_string_new(val);
dac5c838 695 if (!string_obj->gstr) {
870631a2
PP
696 BT_LIB_LOGE_APPEND_CAUSE(
697 "Failed to allocate a GString.");
dac5c838
PP
698 g_free(string_obj);
699 string_obj = NULL;
700 goto end;
701 }
702
2f42aa0a
PP
703 BT_LOGD("Created string value object: addr=%p",
704 string_obj);
705
dac5c838 706end:
11cd69be 707 return (void *) string_obj;
dac5c838
PP
708}
709
05e21286 710struct bt_value *bt_value_string_create(void)
dac5c838 711{
17f3083a
SM
712 BT_ASSERT_PRE_NO_ERROR();
713
05e21286 714 return bt_value_string_create_init("");
dac5c838
PP
715}
716
05e21286 717struct bt_value *bt_value_array_create(void)
dac5c838
PP
718{
719 struct bt_value_array *array_obj;
720
17f3083a
SM
721 BT_ASSERT_PRE_NO_ERROR();
722
2f42aa0a 723 BT_LOGD_STR("Creating empty array value object.");
dac5c838 724 array_obj = g_new0(struct bt_value_array, 1);
dac5c838 725 if (!array_obj) {
870631a2
PP
726 BT_LIB_LOGE_APPEND_CAUSE(
727 "Failed to allocate one array object.");
dac5c838
PP
728 goto end;
729 }
730
731 array_obj->base = bt_value_create_base(BT_VALUE_TYPE_ARRAY);
5d5982ab 732 array_obj->garray = bt_g_ptr_array_new_full(0,
65300d60 733 (GDestroyNotify) bt_object_put_ref);
dac5c838 734 if (!array_obj->garray) {
870631a2 735 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GPtrArray.");
dac5c838
PP
736 g_free(array_obj);
737 array_obj = NULL;
738 goto end;
739 }
740
2f42aa0a
PP
741 BT_LOGD("Created array value object: addr=%p",
742 array_obj);
743
dac5c838 744end:
11cd69be 745 return (void *) array_obj;
dac5c838
PP
746}
747
05e21286 748struct bt_value *bt_value_map_create(void)
dac5c838
PP
749{
750 struct bt_value_map *map_obj;
751
17f3083a
SM
752 BT_ASSERT_PRE_NO_ERROR();
753
2f42aa0a 754 BT_LOGD_STR("Creating empty map value object.");
dac5c838 755 map_obj = g_new0(struct bt_value_map, 1);
dac5c838 756 if (!map_obj) {
870631a2 757 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate one map object.");
dac5c838
PP
758 goto end;
759 }
760
761 map_obj->base = bt_value_create_base(BT_VALUE_TYPE_MAP);
762 map_obj->ght = g_hash_table_new_full(g_direct_hash, g_direct_equal,
65300d60 763 NULL, (GDestroyNotify) bt_object_put_ref);
dac5c838 764 if (!map_obj->ght) {
870631a2 765 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GHashTable.");
dac5c838
PP
766 g_free(map_obj);
767 map_obj = NULL;
768 goto end;
769 }
770
2f42aa0a
PP
771 BT_LOGD("Created map value object: addr=%p",
772 map_obj);
773
dac5c838 774end:
11cd69be 775 return (void *) map_obj;
dac5c838
PP
776}
777
601b0d3c 778bt_bool bt_value_bool_get(const struct bt_value *bool_obj)
dac5c838 779{
bdb288b3 780 BT_ASSERT_PRE_DEV_NON_NULL(bool_obj, "Value object");
0a83319b 781 BT_ASSERT_PRE_DEV_VALUE_HAS_TYPE(bool_obj, BT_VALUE_TYPE_BOOL);
601b0d3c 782 return BT_VALUE_TO_BOOL(bool_obj)->value;
dac5c838
PP
783}
784
05e21286 785void bt_value_bool_set(struct bt_value *bool_obj, bt_bool val)
dac5c838 786{
f6ccaed9 787 BT_ASSERT_PRE_NON_NULL(bool_obj, "Value object");
0a83319b 788 BT_ASSERT_PRE_VALUE_HAS_TYPE(bool_obj, BT_VALUE_TYPE_BOOL);
bdb288b3 789 BT_ASSERT_PRE_DEV_VALUE_HOT(bool_obj, "Value object");
f6ccaed9 790 BT_VALUE_TO_BOOL(bool_obj)->value = val;
ef267d12 791 BT_LOGT("Set boolean value's raw value: value-addr=%p, value=%d",
2f42aa0a 792 bool_obj, val);
dac5c838
PP
793}
794
9c08c816 795uint64_t bt_value_integer_unsigned_get(const struct bt_value *integer_obj)
fdd3a2da 796{
bdb288b3 797 BT_ASSERT_PRE_DEV_NON_NULL(integer_obj, "Value object");
0a83319b 798 BT_ASSERT_PRE_DEV_VALUE_HAS_TYPE(integer_obj,
fdd3a2da
PP
799 BT_VALUE_TYPE_UNSIGNED_INTEGER);
800 return BT_VALUE_TO_INTEGER(integer_obj)->value.u;
801}
802
9c08c816 803int64_t bt_value_integer_signed_get(const struct bt_value *integer_obj)
dac5c838 804{
bdb288b3 805 BT_ASSERT_PRE_DEV_NON_NULL(integer_obj, "Value object");
0a83319b 806 BT_ASSERT_PRE_DEV_VALUE_HAS_TYPE(integer_obj,
fdd3a2da
PP
807 BT_VALUE_TYPE_SIGNED_INTEGER);
808 return BT_VALUE_TO_INTEGER(integer_obj)->value.i;
dac5c838
PP
809}
810
fdd3a2da 811static inline
05e21286 812void bt_value_integer_set(struct bt_value *integer_obj,
fdd3a2da 813 enum bt_value_type expected_type, uint64_t uval)
dac5c838 814{
f6ccaed9 815 BT_ASSERT_PRE_NON_NULL(integer_obj, "Value object");
0a83319b 816 BT_ASSERT_PRE_VALUE_HAS_TYPE(integer_obj, expected_type);
bdb288b3 817 BT_ASSERT_PRE_DEV_VALUE_HOT(integer_obj, "Value object");
fdd3a2da
PP
818 BT_VALUE_TO_INTEGER(integer_obj)->value.u = uval;
819}
820
9c08c816 821void bt_value_integer_unsigned_set(struct bt_value *integer_obj,
fdd3a2da
PP
822 uint64_t val)
823{
824 bt_value_integer_set(integer_obj, BT_VALUE_TYPE_UNSIGNED_INTEGER, val);
ef267d12 825 BT_LOGT("Set unsigned integer value's raw value: "
fdd3a2da
PP
826 "value-addr=%p, value=%" PRIu64, integer_obj, val);
827}
828
9c08c816 829void bt_value_integer_signed_set(struct bt_value *integer_obj,
fdd3a2da
PP
830 int64_t val)
831{
832 bt_value_integer_set(integer_obj, BT_VALUE_TYPE_SIGNED_INTEGER,
833 (uint64_t) val);
ef267d12 834 BT_LOGT("Set signed integer value's raw value: "
fdd3a2da 835 "value-addr=%p, value=%" PRId64, integer_obj, val);
dac5c838
PP
836}
837
601b0d3c 838double bt_value_real_get(const struct bt_value *real_obj)
dac5c838 839{
bdb288b3 840 BT_ASSERT_PRE_DEV_NON_NULL(real_obj, "Value object");
0a83319b 841 BT_ASSERT_PRE_DEV_VALUE_HAS_TYPE(real_obj, BT_VALUE_TYPE_REAL);
601b0d3c 842 return BT_VALUE_TO_REAL(real_obj)->value;
dac5c838
PP
843}
844
05e21286 845void bt_value_real_set(struct bt_value *real_obj, double val)
dac5c838 846{
a373bf69 847 BT_ASSERT_PRE_NON_NULL(real_obj, "Value object");
0a83319b 848 BT_ASSERT_PRE_VALUE_HAS_TYPE(real_obj, BT_VALUE_TYPE_REAL);
bdb288b3 849 BT_ASSERT_PRE_DEV_VALUE_HOT(real_obj, "Value object");
a373bf69 850 BT_VALUE_TO_REAL(real_obj)->value = val;
ef267d12 851 BT_LOGT("Set real number value's raw value: value-addr=%p, value=%f",
a373bf69 852 real_obj, val);
dac5c838
PP
853}
854
601b0d3c 855const char *bt_value_string_get(const struct bt_value *string_obj)
dac5c838 856{
bdb288b3 857 BT_ASSERT_PRE_DEV_NON_NULL(string_obj, "Value object");
0a83319b 858 BT_ASSERT_PRE_DEV_VALUE_HAS_TYPE(string_obj, BT_VALUE_TYPE_STRING);
601b0d3c 859 return BT_VALUE_TO_STRING(string_obj)->gstr->str;
dac5c838
PP
860}
861
d24d5663 862enum bt_value_string_set_status bt_value_string_set(
05e21286 863 struct bt_value *string_obj, const char *val)
dac5c838 864{
17f3083a 865 BT_ASSERT_PRE_NO_ERROR();
f6ccaed9 866 BT_ASSERT_PRE_NON_NULL(string_obj, "Value object");
0a83319b 867 BT_ASSERT_PRE_VALUE_HAS_TYPE(string_obj, BT_VALUE_TYPE_STRING);
bdb288b3 868 BT_ASSERT_PRE_DEV_VALUE_HOT(string_obj, "Value object");
f6ccaed9 869 g_string_assign(BT_VALUE_TO_STRING(string_obj)->gstr, val);
ef267d12 870 BT_LOGT("Set string value's raw value: value-addr=%p, raw-value-addr=%p",
2f42aa0a 871 string_obj, val);
d24d5663 872 return BT_FUNC_STATUS_OK;
dac5c838
PP
873}
874
393729a6 875uint64_t bt_value_array_get_length(const struct bt_value *array_obj)
dac5c838 876{
bdb288b3 877 BT_ASSERT_PRE_DEV_NON_NULL(array_obj, "Value object");
0a83319b 878 BT_ASSERT_PRE_DEV_VALUE_HAS_TYPE(array_obj, BT_VALUE_TYPE_ARRAY);
601b0d3c 879 return (uint64_t) BT_VALUE_TO_ARRAY(array_obj)->garray->len;
dac5c838
PP
880}
881
da91b29a 882struct bt_value *bt_value_array_borrow_element_by_index(
05e21286 883 struct bt_value *array_obj, uint64_t index)
dac5c838 884{
dac5c838
PP
885 struct bt_value_array *typed_array_obj =
886 BT_VALUE_TO_ARRAY(array_obj);
887
bdb288b3 888 BT_ASSERT_PRE_DEV_NON_NULL(array_obj, "Value object");
0a83319b 889 BT_ASSERT_PRE_DEV_VALUE_HAS_TYPE(array_obj, BT_VALUE_TYPE_ARRAY);
bdb288b3 890 BT_ASSERT_PRE_DEV_VALID_INDEX(index, typed_array_obj->garray->len);
094ff7c0 891 return g_ptr_array_index(typed_array_obj->garray, index);
dac5c838
PP
892}
893
05e21286
PP
894const struct bt_value *bt_value_array_borrow_element_by_index_const(
895 const struct bt_value *array_obj,
da91b29a
PP
896 uint64_t index)
897{
05e21286 898 return bt_value_array_borrow_element_by_index(
da91b29a
PP
899 (void *) array_obj, index);
900}
901
d24d5663 902enum bt_value_array_append_element_status bt_value_array_append_element(
05e21286 903 struct bt_value *array_obj,
364747d6 904 struct bt_value *element_obj)
dac5c838 905{
dac5c838
PP
906 struct bt_value_array *typed_array_obj =
907 BT_VALUE_TO_ARRAY(array_obj);
908
17f3083a 909 BT_ASSERT_PRE_NO_ERROR();
f6ccaed9
PP
910 BT_ASSERT_PRE_NON_NULL(array_obj, "Array value object");
911 BT_ASSERT_PRE_NON_NULL(element_obj, "Element value object");
0a83319b 912 BT_ASSERT_PRE_VALUE_HAS_TYPE(array_obj, BT_VALUE_TYPE_ARRAY);
bdb288b3 913 BT_ASSERT_PRE_DEV_VALUE_HOT(array_obj, "Array value object");
dac5c838 914 g_ptr_array_add(typed_array_obj->garray, element_obj);
65300d60 915 bt_object_get_ref(element_obj);
ef267d12 916 BT_LOGT("Appended element to array value: array-value-addr=%p, "
2f42aa0a
PP
917 "element-value-addr=%p, new-size=%u",
918 array_obj, element_obj, typed_array_obj->garray->len);
d24d5663 919 return BT_FUNC_STATUS_OK;
dac5c838
PP
920}
921
d24d5663
PP
922enum bt_value_array_append_element_status
923bt_value_array_append_bool_element(struct bt_value *array_obj, bt_bool val)
dac5c838 924{
d24d5663 925 enum bt_value_array_append_element_status ret;
05e21286 926 struct bt_value *bool_obj = NULL;
dac5c838 927
17f3083a
SM
928 BT_ASSERT_PRE_NO_ERROR();
929
05e21286
PP
930 bool_obj = bt_value_bool_create_init(val);
931 ret = bt_value_array_append_element(array_obj,
da91b29a 932 (void *) bool_obj);
65300d60 933 bt_object_put_ref(bool_obj);
dac5c838
PP
934 return ret;
935}
936
d24d5663
PP
937enum bt_value_array_append_element_status
938bt_value_array_append_unsigned_integer_element(struct bt_value *array_obj,
939 uint64_t val)
fdd3a2da 940{
d24d5663 941 enum bt_value_array_append_element_status ret;
fdd3a2da
PP
942 struct bt_value *integer_obj = NULL;
943
17f3083a
SM
944 BT_ASSERT_PRE_NO_ERROR();
945
9c08c816 946 integer_obj = bt_value_integer_unsigned_create_init(val);
fdd3a2da
PP
947 ret = bt_value_array_append_element(array_obj,
948 (void *) integer_obj);
949 bt_object_put_ref(integer_obj);
950 return ret;
951}
952
d24d5663
PP
953enum bt_value_array_append_element_status
954bt_value_array_append_signed_integer_element(struct bt_value *array_obj,
955 int64_t val)
dac5c838 956{
d24d5663 957 enum bt_value_array_append_element_status ret;
05e21286 958 struct bt_value *integer_obj = NULL;
dac5c838 959
17f3083a
SM
960 BT_ASSERT_PRE_NO_ERROR();
961
9c08c816 962 integer_obj = bt_value_integer_signed_create_init(val);
05e21286 963 ret = bt_value_array_append_element(array_obj,
da91b29a 964 (void *) integer_obj);
65300d60 965 bt_object_put_ref(integer_obj);
dac5c838
PP
966 return ret;
967}
968
d24d5663
PP
969enum bt_value_array_append_element_status
970bt_value_array_append_real_element(struct bt_value *array_obj, double val)
dac5c838 971{
d24d5663 972 enum bt_value_array_append_element_status ret;
05e21286 973 struct bt_value *real_obj = NULL;
dac5c838 974
17f3083a
SM
975 BT_ASSERT_PRE_NO_ERROR();
976
05e21286
PP
977 real_obj = bt_value_real_create_init(val);
978 ret = bt_value_array_append_element(array_obj,
da91b29a 979 (void *) real_obj);
65300d60 980 bt_object_put_ref(real_obj);
dac5c838
PP
981 return ret;
982}
983
d24d5663
PP
984enum bt_value_array_append_element_status
985bt_value_array_append_string_element(struct bt_value *array_obj,
986 const char *val)
dac5c838 987{
d24d5663 988 enum bt_value_array_append_element_status ret;
05e21286 989 struct bt_value *string_obj = NULL;
dac5c838 990
17f3083a
SM
991 BT_ASSERT_PRE_NO_ERROR();
992
05e21286
PP
993 string_obj = bt_value_string_create_init(val);
994 ret = bt_value_array_append_element(array_obj,
da91b29a 995 (void *) string_obj);
65300d60 996 bt_object_put_ref(string_obj);
dac5c838
PP
997 return ret;
998}
999
d24d5663 1000enum bt_value_array_append_element_status
847ab606
PP
1001bt_value_array_append_empty_array_element(struct bt_value *array_obj,
1002 struct bt_value **element_obj)
dac5c838 1003{
d24d5663 1004 enum bt_value_array_append_element_status ret;
05e21286 1005 struct bt_value *empty_array_obj = NULL;
dac5c838 1006
17f3083a
SM
1007 BT_ASSERT_PRE_NO_ERROR();
1008
05e21286
PP
1009 empty_array_obj = bt_value_array_create();
1010 ret = bt_value_array_append_element(array_obj,
da91b29a 1011 (void *) empty_array_obj);
847ab606
PP
1012
1013 if (element_obj) {
1014 *element_obj = empty_array_obj;
1015 }
1016
65300d60 1017 bt_object_put_ref(empty_array_obj);
dac5c838
PP
1018 return ret;
1019}
1020
d24d5663 1021enum bt_value_array_append_element_status
847ab606
PP
1022bt_value_array_append_empty_map_element(struct bt_value *array_obj,
1023 struct bt_value **element_obj)
dac5c838 1024{
d24d5663 1025 enum bt_value_array_append_element_status ret;
05e21286 1026 struct bt_value *map_obj = NULL;
dac5c838 1027
17f3083a
SM
1028 BT_ASSERT_PRE_NO_ERROR();
1029
05e21286
PP
1030 map_obj = bt_value_map_create();
1031 ret = bt_value_array_append_element(array_obj,
da91b29a 1032 (void *) map_obj);
847ab606
PP
1033
1034 if (element_obj) {
1035 *element_obj = map_obj;
1036 }
1037
65300d60 1038 bt_object_put_ref(map_obj);
dac5c838
PP
1039 return ret;
1040}
1041
d24d5663
PP
1042enum bt_value_array_set_element_by_index_status
1043bt_value_array_set_element_by_index(struct bt_value *array_obj, uint64_t index,
da91b29a 1044 struct bt_value *element_obj)
dac5c838 1045{
dac5c838
PP
1046 struct bt_value_array *typed_array_obj =
1047 BT_VALUE_TO_ARRAY(array_obj);
1048
17f3083a 1049 BT_ASSERT_PRE_NO_ERROR();
f6ccaed9
PP
1050 BT_ASSERT_PRE_NON_NULL(array_obj, "Array value object");
1051 BT_ASSERT_PRE_NON_NULL(element_obj, "Element value object");
0a83319b 1052 BT_ASSERT_PRE_VALUE_HAS_TYPE(array_obj, BT_VALUE_TYPE_ARRAY);
bdb288b3
PP
1053 BT_ASSERT_PRE_DEV_VALUE_HOT(array_obj, "Array value object");
1054 BT_ASSERT_PRE_VALID_INDEX(index, typed_array_obj->garray->len);
65300d60 1055 bt_object_put_ref(g_ptr_array_index(typed_array_obj->garray, index));
dac5c838 1056 g_ptr_array_index(typed_array_obj->garray, index) = element_obj;
65300d60 1057 bt_object_get_ref(element_obj);
ef267d12 1058 BT_LOGT("Set array value's element: array-value-addr=%p, "
2f42aa0a
PP
1059 "index=%" PRIu64 ", element-value-addr=%p",
1060 array_obj, index, element_obj);
d24d5663 1061 return BT_FUNC_STATUS_OK;
dac5c838
PP
1062}
1063
601b0d3c 1064uint64_t bt_value_map_get_size(const struct bt_value *map_obj)
dac5c838 1065{
bdb288b3 1066 BT_ASSERT_PRE_DEV_NON_NULL(map_obj, "Value object");
0a83319b 1067 BT_ASSERT_PRE_DEV_VALUE_HAS_TYPE(map_obj, BT_VALUE_TYPE_MAP);
601b0d3c 1068 return (uint64_t) g_hash_table_size(BT_VALUE_TO_MAP(map_obj)->ght);
dac5c838
PP
1069}
1070
05e21286 1071struct bt_value *bt_value_map_borrow_entry_value(struct bt_value *map_obj,
364747d6 1072 const char *key)
dac5c838 1073{
bdb288b3
PP
1074 BT_ASSERT_PRE_DEV_NON_NULL(map_obj, "Value object");
1075 BT_ASSERT_PRE_DEV_NON_NULL(key, "Key");
0a83319b 1076 BT_ASSERT_PRE_DEV_VALUE_HAS_TYPE(map_obj, BT_VALUE_TYPE_MAP);
094ff7c0
PP
1077 return g_hash_table_lookup(BT_VALUE_TO_MAP(map_obj)->ght,
1078 GUINT_TO_POINTER(g_quark_from_string(key)));
dac5c838
PP
1079}
1080
05e21286
PP
1081const struct bt_value *bt_value_map_borrow_entry_value_const(
1082 const struct bt_value *map_obj, const char *key)
da91b29a 1083{
05e21286 1084 return bt_value_map_borrow_entry_value((void *) map_obj, key);
da91b29a
PP
1085}
1086
07208d85 1087bt_bool bt_value_map_has_entry(const struct bt_value *map_obj, const char *key)
dac5c838 1088{
bdb288b3
PP
1089 BT_ASSERT_PRE_DEV_NON_NULL(map_obj, "Value object");
1090 BT_ASSERT_PRE_DEV_NON_NULL(key, "Key");
0a83319b 1091 BT_ASSERT_PRE_DEV_VALUE_HAS_TYPE(map_obj, BT_VALUE_TYPE_MAP);
f6ccaed9
PP
1092 return bt_g_hash_table_contains(BT_VALUE_TO_MAP(map_obj)->ght,
1093 GUINT_TO_POINTER(g_quark_from_string(key)));
dac5c838
PP
1094}
1095
d24d5663
PP
1096enum bt_value_map_insert_entry_status bt_value_map_insert_entry(
1097 struct bt_value *map_obj, const char *key,
1098 struct bt_value *element_obj)
dac5c838 1099{
17f3083a 1100 BT_ASSERT_PRE_NO_ERROR();
f6ccaed9
PP
1101 BT_ASSERT_PRE_NON_NULL(map_obj, "Map value object");
1102 BT_ASSERT_PRE_NON_NULL(key, "Key");
1103 BT_ASSERT_PRE_NON_NULL(element_obj, "Element value object");
0a83319b 1104 BT_ASSERT_PRE_VALUE_HAS_TYPE(map_obj, BT_VALUE_TYPE_MAP);
bdb288b3 1105 BT_ASSERT_PRE_DEV_VALUE_HOT(map_obj, "Map value object");
f6ccaed9
PP
1106 g_hash_table_insert(BT_VALUE_TO_MAP(map_obj)->ght,
1107 GUINT_TO_POINTER(g_quark_from_string(key)), element_obj);
65300d60 1108 bt_object_get_ref(element_obj);
ef267d12 1109 BT_LOGT("Inserted value into map value: map-value-addr=%p, "
2f42aa0a
PP
1110 "key=\"%s\", element-value-addr=%p",
1111 map_obj, key, element_obj);
d24d5663 1112 return BT_FUNC_STATUS_OK;
dac5c838
PP
1113}
1114
d24d5663 1115enum bt_value_map_insert_entry_status bt_value_map_insert_bool_entry(
05e21286 1116 struct bt_value *map_obj, const char *key, bt_bool val)
dac5c838 1117{
d24d5663 1118 enum bt_value_map_insert_entry_status ret;
05e21286 1119 struct bt_value *bool_obj = NULL;
dac5c838 1120
17f3083a
SM
1121 BT_ASSERT_PRE_NO_ERROR();
1122
05e21286
PP
1123 bool_obj = bt_value_bool_create_init(val);
1124 ret = bt_value_map_insert_entry(map_obj, key,
da91b29a 1125 (void *) bool_obj);
65300d60 1126 bt_object_put_ref(bool_obj);
dac5c838
PP
1127 return ret;
1128}
1129
d24d5663
PP
1130enum bt_value_map_insert_entry_status
1131bt_value_map_insert_unsigned_integer_entry(struct bt_value *map_obj,
1132 const char *key, uint64_t val)
fdd3a2da 1133{
d24d5663 1134 enum bt_value_map_insert_entry_status ret;
fdd3a2da
PP
1135 struct bt_value *integer_obj = NULL;
1136
17f3083a
SM
1137 BT_ASSERT_PRE_NO_ERROR();
1138
9c08c816 1139 integer_obj = bt_value_integer_unsigned_create_init(val);
fdd3a2da
PP
1140 ret = bt_value_map_insert_entry(map_obj, key,
1141 (void *) integer_obj);
1142 bt_object_put_ref(integer_obj);
1143 return ret;
1144}
1145
d24d5663
PP
1146enum bt_value_map_insert_entry_status
1147bt_value_map_insert_signed_integer_entry(struct bt_value *map_obj,
1148 const char *key, int64_t val)
dac5c838 1149{
d24d5663 1150 enum bt_value_map_insert_entry_status ret;
05e21286 1151 struct bt_value *integer_obj = NULL;
dac5c838 1152
17f3083a
SM
1153 BT_ASSERT_PRE_NO_ERROR();
1154
9c08c816 1155 integer_obj = bt_value_integer_signed_create_init(val);
05e21286 1156 ret = bt_value_map_insert_entry(map_obj, key,
da91b29a 1157 (void *) integer_obj);
65300d60 1158 bt_object_put_ref(integer_obj);
dac5c838
PP
1159 return ret;
1160}
1161
d24d5663 1162enum bt_value_map_insert_entry_status bt_value_map_insert_real_entry(
05e21286 1163 struct bt_value *map_obj, const char *key, double val)
dac5c838 1164{
d24d5663 1165 enum bt_value_map_insert_entry_status ret;
05e21286 1166 struct bt_value *real_obj = NULL;
dac5c838 1167
17f3083a
SM
1168 BT_ASSERT_PRE_NO_ERROR();
1169
05e21286
PP
1170 real_obj = bt_value_real_create_init(val);
1171 ret = bt_value_map_insert_entry(map_obj, key,
da91b29a 1172 (void *) real_obj);
65300d60 1173 bt_object_put_ref(real_obj);
dac5c838
PP
1174 return ret;
1175}
1176
d24d5663 1177enum bt_value_map_insert_entry_status bt_value_map_insert_string_entry(
05e21286 1178 struct bt_value *map_obj, const char *key,
601b0d3c 1179 const char *val)
dac5c838 1180{
d24d5663 1181 enum bt_value_map_insert_entry_status ret;
05e21286 1182 struct bt_value *string_obj = NULL;
dac5c838 1183
17f3083a
SM
1184 BT_ASSERT_PRE_NO_ERROR();
1185
05e21286
PP
1186 string_obj = bt_value_string_create_init(val);
1187 ret = bt_value_map_insert_entry(map_obj, key,
da91b29a 1188 (void *) string_obj);
65300d60 1189 bt_object_put_ref(string_obj);
dac5c838
PP
1190 return ret;
1191}
1192
d24d5663
PP
1193enum bt_value_map_insert_entry_status
1194bt_value_map_insert_empty_array_entry(
847ab606
PP
1195 struct bt_value *map_obj, const char *key,
1196 bt_value **entry_obj)
dac5c838 1197{
d24d5663 1198 enum bt_value_map_insert_entry_status ret;
05e21286 1199 struct bt_value *array_obj = NULL;
dac5c838 1200
17f3083a
SM
1201 BT_ASSERT_PRE_NO_ERROR();
1202
05e21286
PP
1203 array_obj = bt_value_array_create();
1204 ret = bt_value_map_insert_entry(map_obj, key,
da91b29a 1205 (void *) array_obj);
847ab606
PP
1206
1207 if (entry_obj) {
1208 *entry_obj = array_obj;
1209 }
1210
65300d60 1211 bt_object_put_ref(array_obj);
dac5c838
PP
1212 return ret;
1213}
1214
d24d5663 1215enum bt_value_map_insert_entry_status
847ab606
PP
1216bt_value_map_insert_empty_map_entry(struct bt_value *map_obj, const char *key,
1217 bt_value **entry_obj)
dac5c838 1218{
d24d5663 1219 enum bt_value_map_insert_entry_status ret;
05e21286 1220 struct bt_value *empty_map_obj = NULL;
dac5c838 1221
17f3083a
SM
1222 BT_ASSERT_PRE_NO_ERROR();
1223
05e21286
PP
1224 empty_map_obj = bt_value_map_create();
1225 ret = bt_value_map_insert_entry(map_obj, key,
da91b29a 1226 (void *) empty_map_obj);
847ab606
PP
1227
1228 if (entry_obj) {
1229 *entry_obj = empty_map_obj;
1230 }
1231
65300d60 1232 bt_object_put_ref(empty_map_obj);
dac5c838
PP
1233 return ret;
1234}
1235
d24d5663
PP
1236enum bt_value_map_foreach_entry_status bt_value_map_foreach_entry(
1237 struct bt_value *map_obj, bt_value_map_foreach_entry_func func,
1238 void *data)
dac5c838 1239{
27c61ce8 1240 int status = BT_FUNC_STATUS_OK;
dac5c838
PP
1241 gpointer key, element_obj;
1242 GHashTableIter iter;
1243 struct bt_value_map *typed_map_obj = BT_VALUE_TO_MAP(map_obj);
1244
17f3083a
SM
1245 BT_ASSERT_PRE_NO_ERROR();
1246
bdb288b3
PP
1247 BT_ASSERT_PRE_DEV_NON_NULL(map_obj, "Value object");
1248 BT_ASSERT_PRE_DEV_NON_NULL(func, "Callback");
0a83319b 1249 BT_ASSERT_PRE_DEV_VALUE_HAS_TYPE(map_obj, BT_VALUE_TYPE_MAP);
dac5c838
PP
1250 g_hash_table_iter_init(&iter, typed_map_obj->ght);
1251
1252 while (g_hash_table_iter_next(&iter, &key, &element_obj)) {
5b44aff2 1253 const char *key_str = g_quark_to_string(GPOINTER_TO_UINT(key));
dac5c838 1254
27c61ce8
PP
1255 status = func(key_str, element_obj, data);
1256 BT_ASSERT_POST_NO_ERROR_IF_NO_ERROR_STATUS(status);
1257 if (status != BT_FUNC_STATUS_OK) {
1258 if (status < 0) {
1259 BT_LIB_LOGE_APPEND_CAUSE(
1260 "User function failed while iterating "
1261 "map value entries: "
1262 "status=%s, key=\"%s\", "
1263 "value-addr=%p, data=%p",
1264 bt_common_func_status_string(status),
1265 key_str, element_obj, data);
1266
1267 if (status == BT_FUNC_STATUS_ERROR) {
1268 /*
1269 * User function error becomes a
1270 * user error from this
1271 * function's caller's
1272 * perspective.
1273 */
1274 status = BT_FUNC_STATUS_USER_ERROR;
1275 }
1276 } else {
1277 BT_ASSERT(status == BT_FUNC_STATUS_INTERRUPTED);
1278 BT_LOGT("User interrupted the loop: status=%s, "
1279 "key=\"%s\", value-addr=%p, data=%p",
1280 bt_common_func_status_string(status),
1281 key_str, element_obj, data);
1282 }
1283
dac5c838
PP
1284 break;
1285 }
1286 }
1287
27c61ce8 1288 return status;
dac5c838
PP
1289}
1290
d24d5663 1291enum bt_value_map_foreach_entry_const_status bt_value_map_foreach_entry_const(
05e21286 1292 const struct bt_value *map_obj,
40f4ba76 1293 bt_value_map_foreach_entry_const_func func, void *data)
da91b29a 1294{
17f3083a
SM
1295 BT_ASSERT_PRE_NO_ERROR();
1296
d24d5663 1297 return (int) bt_value_map_foreach_entry((void *) map_obj,
40f4ba76 1298 (bt_value_map_foreach_entry_func) func, data);
da91b29a
PP
1299}
1300
770750d3 1301struct extend_map_element_data {
ab26240f 1302 struct bt_value *base_obj;
770750d3
PP
1303};
1304
1305static
27c61ce8
PP
1306bt_value_map_foreach_entry_const_func_status extend_map_element(
1307 const char *key, const struct bt_value *extension_obj_elem,
1308 void *data)
770750d3 1309{
27c61ce8 1310 int status;
770750d3 1311 struct extend_map_element_data *extend_data = data;
05e21286 1312 struct bt_value *extension_obj_elem_copy = NULL;
770750d3
PP
1313
1314 /* Copy object which is to replace the current one */
27c61ce8
PP
1315 status = bt_value_copy(extension_obj_elem, &extension_obj_elem_copy);
1316 if (status) {
870631a2 1317 BT_LIB_LOGE_APPEND_CAUSE("Cannot copy map element: %!+v",
601b0d3c
PP
1318 extension_obj_elem);
1319 goto error;
1320 }
1321
1322 BT_ASSERT(extension_obj_elem_copy);
770750d3 1323
ab26240f 1324 /* Replace in base map value. */
27c61ce8 1325 status = bt_value_map_insert_entry(extend_data->base_obj, key,
e7279cae 1326 extension_obj_elem_copy);
27c61ce8 1327 if (status) {
870631a2 1328 BT_LIB_LOGE_APPEND_CAUSE(
ab26240f
FD
1329 "Cannot replace value in base map value: key=\"%s\", "
1330 "%![base-map-value-]+v, %![element-value-]+v",
27c61ce8 1331 key, extend_data->base_obj, extension_obj_elem_copy);
770750d3
PP
1332 goto error;
1333 }
1334
1335 goto end;
1336
1337error:
27c61ce8 1338 BT_ASSERT(status < 0);
770750d3
PP
1339
1340end:
65300d60 1341 BT_OBJECT_PUT_REF_AND_RESET(extension_obj_elem_copy);
27c61ce8
PP
1342 BT_ASSERT(status == BT_FUNC_STATUS_OK ||
1343 status == BT_FUNC_STATUS_MEMORY_ERROR);
1344 return status;
770750d3
PP
1345}
1346
d24d5663 1347enum bt_value_map_extend_status bt_value_map_extend(
ab26240f
FD
1348 struct bt_value *base_map_obj,
1349 const struct bt_value *extension_obj)
770750d3 1350{
27c61ce8 1351 int status = BT_FUNC_STATUS_OK;
601b0d3c 1352 struct extend_map_element_data extend_data = {
ab26240f 1353 .base_obj = NULL,
601b0d3c 1354 };
770750d3 1355
17f3083a 1356 BT_ASSERT_PRE_NO_ERROR();
f6ccaed9 1357 BT_ASSERT_PRE_NON_NULL(base_map_obj, "Base value object");
ab26240f 1358 BT_ASSERT_PRE_DEV_VALUE_HOT(base_map_obj, "Base value object");
f6ccaed9 1359 BT_ASSERT_PRE_NON_NULL(extension_obj, "Extension value object");
0a83319b
PP
1360 BT_ASSERT_PRE_VALUE_HAS_TYPE(base_map_obj, BT_VALUE_TYPE_MAP);
1361 BT_ASSERT_PRE_VALUE_HAS_TYPE(extension_obj, BT_VALUE_TYPE_MAP);
2f42aa0a
PP
1362 BT_LOGD("Extending map value: base-value-addr=%p, extension-value-addr=%p",
1363 base_map_obj, extension_obj);
601b0d3c 1364
770750d3
PP
1365 /*
1366 * For each key in the extension map object, replace this key
ab26240f 1367 * in the base map object.
770750d3 1368 */
ab26240f 1369 extend_data.base_obj = base_map_obj;
27c61ce8
PP
1370 status = bt_value_map_foreach_entry_const(extension_obj,
1371 extend_map_element, &extend_data);
1372 if (status != BT_FUNC_STATUS_OK) {
1373 BT_ASSERT(status == BT_FUNC_STATUS_MEMORY_ERROR);
870631a2
PP
1374 BT_LIB_LOGE_APPEND_CAUSE(
1375 "Cannot iterate on the extension object's elements: "
1376 "%![extension-value-]+v", extension_obj);
770750d3
PP
1377 }
1378
27c61ce8 1379 return status;
770750d3
PP
1380}
1381
d24d5663 1382enum bt_value_copy_status bt_value_copy(const struct bt_value *object,
6be5a99e 1383 struct bt_value **copy_obj)
dac5c838 1384{
d24d5663 1385 enum bt_value_copy_status status = BT_FUNC_STATUS_OK;
dac5c838 1386
17f3083a 1387 BT_ASSERT_PRE_NO_ERROR();
f6ccaed9 1388 BT_ASSERT_PRE_NON_NULL(object, "Value object");
601b0d3c 1389 BT_ASSERT_PRE_NON_NULL(copy_obj, "Value object copy (output)");
2f42aa0a 1390 BT_LOGD("Copying value object: addr=%p", object);
601b0d3c
PP
1391 *copy_obj = copy_funcs[object->type](object);
1392 if (*copy_obj) {
2f42aa0a
PP
1393 BT_LOGD("Copied value object: copy-value-addr=%p",
1394 copy_obj);
1395 } else {
d24d5663 1396 status = BT_FUNC_STATUS_MEMORY_ERROR;
601b0d3c 1397 *copy_obj = NULL;
870631a2 1398 BT_LIB_LOGE_APPEND_CAUSE("Failed to copy value object.");
2f42aa0a 1399 }
dac5c838 1400
601b0d3c 1401 return status;
dac5c838
PP
1402}
1403
cd933d89 1404bt_bool bt_value_is_equal(const struct bt_value *object_a,
dac5c838
PP
1405 const struct bt_value *object_b)
1406{
c55a9f58 1407 bt_bool ret = BT_FALSE;
dac5c838 1408
bdb288b3
PP
1409 BT_ASSERT_PRE_DEV_NON_NULL(object_a, "Value object A");
1410 BT_ASSERT_PRE_DEV_NON_NULL(object_b, "Value object B");
dac5c838
PP
1411
1412 if (object_a->type != object_b->type) {
ef267d12 1413 BT_LOGT("Values are different: type mismatch: "
2f42aa0a 1414 "value-a-addr=%p, value-b-addr=%p, "
c4628760 1415 "value-a-type=%s, value-b-type=%s",
2f42aa0a 1416 object_a, object_b,
da91b29a
PP
1417 bt_common_value_type_string(object_a->type),
1418 bt_common_value_type_string(object_b->type));
dac5c838
PP
1419 goto end;
1420 }
1421
cd933d89 1422 ret = is_equal_funcs[object_a->type](object_a, object_b);
dac5c838
PP
1423
1424end:
1425 return ret;
1426}
c5b9b441
PP
1427
1428void bt_value_get_ref(const struct bt_value *value)
1429{
1430 bt_object_get_ref(value);
1431}
1432
1433void bt_value_put_ref(const struct bt_value *value)
1434{
1435 bt_object_put_ref(value);
1436}
This page took 0.152382 seconds and 4 git commands to generate.