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