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