configure: re-enable '-Wunused-parameter'
[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
MJ
832 enum bt_value_type expected_type __attribute__((unused)),
833 uint64_t uval,
1778c2a4 834 const char *api_func)
dac5c838 835{
1778c2a4 836 BT_ASSERT_PRE_DEV_VALUE_HOT_FROM_FUNC(api_func, integer_obj);
fdd3a2da
PP
837 BT_VALUE_TO_INTEGER(integer_obj)->value.u = uval;
838}
839
1353b066 840BT_EXPORT
9c08c816 841void bt_value_integer_unsigned_set(struct bt_value *integer_obj,
fdd3a2da
PP
842 uint64_t val)
843{
1778c2a4
PP
844 BT_ASSERT_PRE_VALUE_NON_NULL(integer_obj);
845 BT_ASSERT_PRE_VALUE_IS_UNSIGNED_INT(integer_obj);
846 set_integer_value(integer_obj, BT_VALUE_TYPE_UNSIGNED_INTEGER, val,
847 __func__);
ef267d12 848 BT_LOGT("Set unsigned integer value's raw value: "
fdd3a2da
PP
849 "value-addr=%p, value=%" PRIu64, integer_obj, val);
850}
851
1353b066 852BT_EXPORT
9c08c816 853void bt_value_integer_signed_set(struct bt_value *integer_obj,
fdd3a2da
PP
854 int64_t val)
855{
1778c2a4
PP
856 BT_ASSERT_PRE_VALUE_NON_NULL(integer_obj);
857 BT_ASSERT_PRE_VALUE_IS_SIGNED_INT(integer_obj);
858 set_integer_value(integer_obj, BT_VALUE_TYPE_SIGNED_INTEGER,
859 (uint64_t) val, __func__);
ef267d12 860 BT_LOGT("Set signed integer value's raw value: "
fdd3a2da 861 "value-addr=%p, value=%" PRId64, integer_obj, val);
dac5c838
PP
862}
863
1353b066 864BT_EXPORT
601b0d3c 865double bt_value_real_get(const struct bt_value *real_obj)
dac5c838 866{
d5b13b9b 867 BT_ASSERT_PRE_DEV_VALUE_NON_NULL(real_obj);
1778c2a4 868 BT_ASSERT_PRE_DEV_VALUE_IS_REAL(real_obj);
601b0d3c 869 return BT_VALUE_TO_REAL(real_obj)->value;
dac5c838
PP
870}
871
1353b066 872BT_EXPORT
05e21286 873void bt_value_real_set(struct bt_value *real_obj, double val)
dac5c838 874{
d5b13b9b 875 BT_ASSERT_PRE_VALUE_NON_NULL(real_obj);
1778c2a4 876 BT_ASSERT_PRE_VALUE_IS_REAL(real_obj);
d5b13b9b 877 BT_ASSERT_PRE_DEV_VALUE_HOT(real_obj);
a373bf69 878 BT_VALUE_TO_REAL(real_obj)->value = val;
ef267d12 879 BT_LOGT("Set real number value's raw value: value-addr=%p, value=%f",
a373bf69 880 real_obj, val);
dac5c838
PP
881}
882
1353b066 883BT_EXPORT
601b0d3c 884const char *bt_value_string_get(const struct bt_value *string_obj)
dac5c838 885{
d5b13b9b 886 BT_ASSERT_PRE_DEV_VALUE_NON_NULL(string_obj);
1778c2a4 887 BT_ASSERT_PRE_DEV_VALUE_IS_STRING(string_obj);
601b0d3c 888 return BT_VALUE_TO_STRING(string_obj)->gstr->str;
dac5c838
PP
889}
890
1353b066 891BT_EXPORT
d24d5663 892enum bt_value_string_set_status bt_value_string_set(
05e21286 893 struct bt_value *string_obj, const char *val)
dac5c838 894{
17f3083a 895 BT_ASSERT_PRE_NO_ERROR();
d5b13b9b 896 BT_ASSERT_PRE_VALUE_NON_NULL(string_obj);
1778c2a4 897 BT_ASSERT_PRE_VALUE_IS_STRING(string_obj);
d5b13b9b 898 BT_ASSERT_PRE_DEV_VALUE_HOT(string_obj);
f6ccaed9 899 g_string_assign(BT_VALUE_TO_STRING(string_obj)->gstr, val);
ef267d12 900 BT_LOGT("Set string value's raw value: value-addr=%p, raw-value-addr=%p",
2f42aa0a 901 string_obj, val);
d24d5663 902 return BT_FUNC_STATUS_OK;
dac5c838
PP
903}
904
1353b066 905BT_EXPORT
393729a6 906uint64_t bt_value_array_get_length(const struct bt_value *array_obj)
dac5c838 907{
d5b13b9b 908 BT_ASSERT_PRE_DEV_VALUE_NON_NULL(array_obj);
1778c2a4 909 BT_ASSERT_PRE_DEV_VALUE_IS_ARRAY(array_obj);
601b0d3c 910 return (uint64_t) BT_VALUE_TO_ARRAY(array_obj)->garray->len;
dac5c838
PP
911}
912
1353b066 913BT_EXPORT
da91b29a 914struct bt_value *bt_value_array_borrow_element_by_index(
05e21286 915 struct bt_value *array_obj, uint64_t index)
dac5c838 916{
dac5c838
PP
917 struct bt_value_array *typed_array_obj =
918 BT_VALUE_TO_ARRAY(array_obj);
919
d5b13b9b 920 BT_ASSERT_PRE_DEV_VALUE_NON_NULL(array_obj);
1778c2a4 921 BT_ASSERT_PRE_DEV_VALUE_IS_ARRAY(array_obj);
bdb288b3 922 BT_ASSERT_PRE_DEV_VALID_INDEX(index, typed_array_obj->garray->len);
094ff7c0 923 return g_ptr_array_index(typed_array_obj->garray, index);
dac5c838
PP
924}
925
1353b066 926BT_EXPORT
05e21286
PP
927const struct bt_value *bt_value_array_borrow_element_by_index_const(
928 const struct bt_value *array_obj,
da91b29a
PP
929 uint64_t index)
930{
05e21286 931 return bt_value_array_borrow_element_by_index(
da91b29a
PP
932 (void *) array_obj, index);
933}
934
1778c2a4
PP
935static
936enum bt_value_array_append_element_status append_array_element(
05e21286 937 struct bt_value *array_obj,
1778c2a4 938 struct bt_value *element_obj, const char *api_func)
dac5c838 939{
dac5c838
PP
940 struct bt_value_array *typed_array_obj =
941 BT_VALUE_TO_ARRAY(array_obj);
942
1778c2a4
PP
943 BT_ASSERT_PRE_NO_ERROR_FROM_FUNC(api_func);
944 BT_ASSERT_PRE_NON_NULL_FROM_FUNC(api_func, "array-value-object",
945 array_obj, "Array value object");
946 BT_ASSERT_PRE_NON_NULL_FROM_FUNC(api_func, "element-value-object",
947 element_obj, "Element value object");
948 BT_ASSERT_PRE_VALUE_HAS_TYPE_FROM_FUNC(api_func, "value-object",
949 array_obj, "array", BT_VALUE_TYPE_ARRAY);
950 BT_ASSERT_PRE_DEV_VALUE_HOT_FROM_FUNC(api_func, array_obj);
dac5c838 951 g_ptr_array_add(typed_array_obj->garray, element_obj);
65300d60 952 bt_object_get_ref(element_obj);
ef267d12 953 BT_LOGT("Appended element to array value: array-value-addr=%p, "
2f42aa0a
PP
954 "element-value-addr=%p, new-size=%u",
955 array_obj, element_obj, typed_array_obj->garray->len);
d24d5663 956 return BT_FUNC_STATUS_OK;
dac5c838
PP
957}
958
1353b066 959BT_EXPORT
1778c2a4
PP
960enum bt_value_array_append_element_status bt_value_array_append_element(
961 struct bt_value *array_obj,
962 struct bt_value *element_obj)
963{
964 return append_array_element(array_obj, element_obj, __func__);
965}
966
1353b066 967BT_EXPORT
d24d5663
PP
968enum bt_value_array_append_element_status
969bt_value_array_append_bool_element(struct bt_value *array_obj, bt_bool val)
dac5c838 970{
d24d5663 971 enum bt_value_array_append_element_status ret;
05e21286 972 struct bt_value *bool_obj = NULL;
dac5c838 973
17f3083a
SM
974 BT_ASSERT_PRE_NO_ERROR();
975
05e21286 976 bool_obj = bt_value_bool_create_init(val);
1778c2a4
PP
977 ret = append_array_element(array_obj,
978 (void *) bool_obj, __func__);
65300d60 979 bt_object_put_ref(bool_obj);
dac5c838
PP
980 return ret;
981}
982
1353b066 983BT_EXPORT
d24d5663
PP
984enum bt_value_array_append_element_status
985bt_value_array_append_unsigned_integer_element(struct bt_value *array_obj,
986 uint64_t val)
fdd3a2da 987{
d24d5663 988 enum bt_value_array_append_element_status ret;
fdd3a2da
PP
989 struct bt_value *integer_obj = NULL;
990
17f3083a
SM
991 BT_ASSERT_PRE_NO_ERROR();
992
9c08c816 993 integer_obj = bt_value_integer_unsigned_create_init(val);
1778c2a4
PP
994 ret = append_array_element(array_obj,
995 (void *) integer_obj, __func__);
fdd3a2da
PP
996 bt_object_put_ref(integer_obj);
997 return ret;
998}
999
1353b066 1000BT_EXPORT
d24d5663
PP
1001enum bt_value_array_append_element_status
1002bt_value_array_append_signed_integer_element(struct bt_value *array_obj,
1003 int64_t val)
dac5c838 1004{
d24d5663 1005 enum bt_value_array_append_element_status ret;
05e21286 1006 struct bt_value *integer_obj = NULL;
dac5c838 1007
17f3083a
SM
1008 BT_ASSERT_PRE_NO_ERROR();
1009
9c08c816 1010 integer_obj = bt_value_integer_signed_create_init(val);
1778c2a4
PP
1011 ret = append_array_element(array_obj,
1012 (void *) integer_obj, __func__);
65300d60 1013 bt_object_put_ref(integer_obj);
dac5c838
PP
1014 return ret;
1015}
1016
1353b066 1017BT_EXPORT
d24d5663
PP
1018enum bt_value_array_append_element_status
1019bt_value_array_append_real_element(struct bt_value *array_obj, double val)
dac5c838 1020{
d24d5663 1021 enum bt_value_array_append_element_status ret;
05e21286 1022 struct bt_value *real_obj = NULL;
dac5c838 1023
17f3083a
SM
1024 BT_ASSERT_PRE_NO_ERROR();
1025
05e21286 1026 real_obj = bt_value_real_create_init(val);
1778c2a4
PP
1027 ret = append_array_element(array_obj,
1028 (void *) real_obj, __func__);
65300d60 1029 bt_object_put_ref(real_obj);
dac5c838
PP
1030 return ret;
1031}
1032
1353b066 1033BT_EXPORT
d24d5663
PP
1034enum bt_value_array_append_element_status
1035bt_value_array_append_string_element(struct bt_value *array_obj,
1036 const char *val)
dac5c838 1037{
d24d5663 1038 enum bt_value_array_append_element_status ret;
05e21286 1039 struct bt_value *string_obj = NULL;
dac5c838 1040
17f3083a
SM
1041 BT_ASSERT_PRE_NO_ERROR();
1042
05e21286 1043 string_obj = bt_value_string_create_init(val);
1778c2a4
PP
1044 ret = append_array_element(array_obj,
1045 (void *) string_obj, __func__);
65300d60 1046 bt_object_put_ref(string_obj);
dac5c838
PP
1047 return ret;
1048}
1049
1353b066 1050BT_EXPORT
d24d5663 1051enum bt_value_array_append_element_status
847ab606
PP
1052bt_value_array_append_empty_array_element(struct bt_value *array_obj,
1053 struct bt_value **element_obj)
dac5c838 1054{
d24d5663 1055 enum bt_value_array_append_element_status ret;
05e21286 1056 struct bt_value *empty_array_obj = NULL;
dac5c838 1057
17f3083a
SM
1058 BT_ASSERT_PRE_NO_ERROR();
1059
05e21286 1060 empty_array_obj = bt_value_array_create();
1778c2a4
PP
1061 ret = append_array_element(array_obj,
1062 (void *) empty_array_obj, __func__);
847ab606
PP
1063
1064 if (element_obj) {
1065 *element_obj = empty_array_obj;
1066 }
1067
65300d60 1068 bt_object_put_ref(empty_array_obj);
dac5c838
PP
1069 return ret;
1070}
1071
1353b066 1072BT_EXPORT
d24d5663 1073enum bt_value_array_append_element_status
847ab606
PP
1074bt_value_array_append_empty_map_element(struct bt_value *array_obj,
1075 struct bt_value **element_obj)
dac5c838 1076{
d24d5663 1077 enum bt_value_array_append_element_status ret;
05e21286 1078 struct bt_value *map_obj = NULL;
dac5c838 1079
17f3083a
SM
1080 BT_ASSERT_PRE_NO_ERROR();
1081
05e21286 1082 map_obj = bt_value_map_create();
1778c2a4
PP
1083 ret = append_array_element(array_obj,
1084 (void *) map_obj, __func__);
847ab606
PP
1085
1086 if (element_obj) {
1087 *element_obj = map_obj;
1088 }
1089
65300d60 1090 bt_object_put_ref(map_obj);
dac5c838
PP
1091 return ret;
1092}
1093
1353b066 1094BT_EXPORT
d24d5663
PP
1095enum bt_value_array_set_element_by_index_status
1096bt_value_array_set_element_by_index(struct bt_value *array_obj, uint64_t index,
da91b29a 1097 struct bt_value *element_obj)
dac5c838 1098{
dac5c838
PP
1099 struct bt_value_array *typed_array_obj =
1100 BT_VALUE_TO_ARRAY(array_obj);
1101
17f3083a 1102 BT_ASSERT_PRE_NO_ERROR();
1778c2a4
PP
1103 BT_ASSERT_PRE_NON_NULL("array-value-object", array_obj,
1104 "Array value object");
1105 BT_ASSERT_PRE_NON_NULL("element-value-object", element_obj,
1106 "Element value object");
1107 BT_ASSERT_PRE_VALUE_IS_ARRAY(array_obj);
d5b13b9b 1108 BT_ASSERT_PRE_DEV_VALUE_HOT(array_obj);
bdb288b3 1109 BT_ASSERT_PRE_VALID_INDEX(index, typed_array_obj->garray->len);
65300d60 1110 bt_object_put_ref(g_ptr_array_index(typed_array_obj->garray, index));
dac5c838 1111 g_ptr_array_index(typed_array_obj->garray, index) = element_obj;
65300d60 1112 bt_object_get_ref(element_obj);
ef267d12 1113 BT_LOGT("Set array value's element: array-value-addr=%p, "
2f42aa0a
PP
1114 "index=%" PRIu64 ", element-value-addr=%p",
1115 array_obj, index, element_obj);
d24d5663 1116 return BT_FUNC_STATUS_OK;
dac5c838
PP
1117}
1118
1353b066 1119BT_EXPORT
601b0d3c 1120uint64_t bt_value_map_get_size(const struct bt_value *map_obj)
dac5c838 1121{
d5b13b9b 1122 BT_ASSERT_PRE_DEV_VALUE_NON_NULL(map_obj);
1778c2a4 1123 BT_ASSERT_PRE_DEV_VALUE_IS_MAP(map_obj);
601b0d3c 1124 return (uint64_t) g_hash_table_size(BT_VALUE_TO_MAP(map_obj)->ght);
dac5c838
PP
1125}
1126
1353b066 1127BT_EXPORT
05e21286 1128struct bt_value *bt_value_map_borrow_entry_value(struct bt_value *map_obj,
364747d6 1129 const char *key)
dac5c838 1130{
d5b13b9b
PP
1131 BT_ASSERT_PRE_DEV_VALUE_NON_NULL(map_obj);
1132 BT_ASSERT_PRE_DEV_KEY_NON_NULL(key);
1778c2a4 1133 BT_ASSERT_PRE_DEV_VALUE_IS_MAP(map_obj);
094ff7c0
PP
1134 return g_hash_table_lookup(BT_VALUE_TO_MAP(map_obj)->ght,
1135 GUINT_TO_POINTER(g_quark_from_string(key)));
dac5c838
PP
1136}
1137
1353b066 1138BT_EXPORT
05e21286
PP
1139const struct bt_value *bt_value_map_borrow_entry_value_const(
1140 const struct bt_value *map_obj, const char *key)
da91b29a 1141{
05e21286 1142 return bt_value_map_borrow_entry_value((void *) map_obj, key);
da91b29a
PP
1143}
1144
1353b066 1145BT_EXPORT
07208d85 1146bt_bool bt_value_map_has_entry(const struct bt_value *map_obj, const char *key)
dac5c838 1147{
d5b13b9b
PP
1148 BT_ASSERT_PRE_DEV_VALUE_NON_NULL(map_obj);
1149 BT_ASSERT_PRE_DEV_KEY_NON_NULL(key);
1778c2a4 1150 BT_ASSERT_PRE_DEV_VALUE_IS_MAP(map_obj);
f6ccaed9
PP
1151 return bt_g_hash_table_contains(BT_VALUE_TO_MAP(map_obj)->ght,
1152 GUINT_TO_POINTER(g_quark_from_string(key)));
dac5c838
PP
1153}
1154
1778c2a4
PP
1155static
1156enum bt_value_map_insert_entry_status insert_map_value_entry(
d24d5663 1157 struct bt_value *map_obj, const char *key,
1778c2a4
PP
1158 struct bt_value *element_obj, const char *api_func)
1159{
1160 BT_ASSERT_PRE_NO_ERROR_FROM_FUNC(api_func);
1161 BT_ASSERT_PRE_NON_NULL_FROM_FUNC(api_func, "map-value-object",
1162 map_obj, "Map value object");
1163 BT_ASSERT_PRE_KEY_NON_NULL_FROM_FUNC(api_func, key);
1164 BT_ASSERT_PRE_NON_NULL_FROM_FUNC(api_func,
1165 "element-value-object", element_obj, "Element value object");
1166 BT_ASSERT_PRE_VALUE_HAS_TYPE_FROM_FUNC(api_func, "value-object",
1167 map_obj, "map", BT_VALUE_TYPE_MAP);
1168 BT_ASSERT_PRE_DEV_VALUE_HOT_FROM_FUNC(api_func, map_obj);
f6ccaed9
PP
1169 g_hash_table_insert(BT_VALUE_TO_MAP(map_obj)->ght,
1170 GUINT_TO_POINTER(g_quark_from_string(key)), element_obj);
65300d60 1171 bt_object_get_ref(element_obj);
ef267d12 1172 BT_LOGT("Inserted value into map value: map-value-addr=%p, "
2f42aa0a
PP
1173 "key=\"%s\", element-value-addr=%p",
1174 map_obj, key, element_obj);
d24d5663 1175 return BT_FUNC_STATUS_OK;
dac5c838
PP
1176}
1177
1353b066 1178BT_EXPORT
1778c2a4
PP
1179enum bt_value_map_insert_entry_status bt_value_map_insert_entry(
1180 struct bt_value *map_obj, const char *key,
1181 struct bt_value *element_obj)
1182{
1183 return insert_map_value_entry(map_obj, key, element_obj, __func__);
1184}
1185
1353b066 1186BT_EXPORT
d24d5663 1187enum bt_value_map_insert_entry_status bt_value_map_insert_bool_entry(
05e21286 1188 struct bt_value *map_obj, const char *key, bt_bool val)
dac5c838 1189{
d24d5663 1190 enum bt_value_map_insert_entry_status ret;
05e21286 1191 struct bt_value *bool_obj = NULL;
dac5c838 1192
17f3083a
SM
1193 BT_ASSERT_PRE_NO_ERROR();
1194
05e21286 1195 bool_obj = bt_value_bool_create_init(val);
1778c2a4
PP
1196 ret = insert_map_value_entry(map_obj, key,
1197 (void *) bool_obj, __func__);
65300d60 1198 bt_object_put_ref(bool_obj);
dac5c838
PP
1199 return ret;
1200}
1201
1353b066 1202BT_EXPORT
d24d5663
PP
1203enum bt_value_map_insert_entry_status
1204bt_value_map_insert_unsigned_integer_entry(struct bt_value *map_obj,
1205 const char *key, uint64_t val)
fdd3a2da 1206{
d24d5663 1207 enum bt_value_map_insert_entry_status ret;
fdd3a2da
PP
1208 struct bt_value *integer_obj = NULL;
1209
17f3083a
SM
1210 BT_ASSERT_PRE_NO_ERROR();
1211
9c08c816 1212 integer_obj = bt_value_integer_unsigned_create_init(val);
1778c2a4
PP
1213 ret = insert_map_value_entry(map_obj, key,
1214 (void *) integer_obj, __func__);
fdd3a2da
PP
1215 bt_object_put_ref(integer_obj);
1216 return ret;
1217}
1218
1353b066 1219BT_EXPORT
d24d5663
PP
1220enum bt_value_map_insert_entry_status
1221bt_value_map_insert_signed_integer_entry(struct bt_value *map_obj,
1222 const char *key, int64_t val)
dac5c838 1223{
d24d5663 1224 enum bt_value_map_insert_entry_status ret;
05e21286 1225 struct bt_value *integer_obj = NULL;
dac5c838 1226
17f3083a
SM
1227 BT_ASSERT_PRE_NO_ERROR();
1228
9c08c816 1229 integer_obj = bt_value_integer_signed_create_init(val);
1778c2a4
PP
1230 ret = insert_map_value_entry(map_obj, key,
1231 (void *) integer_obj, __func__);
65300d60 1232 bt_object_put_ref(integer_obj);
dac5c838
PP
1233 return ret;
1234}
1235
1353b066 1236BT_EXPORT
d24d5663 1237enum bt_value_map_insert_entry_status bt_value_map_insert_real_entry(
05e21286 1238 struct bt_value *map_obj, const char *key, double val)
dac5c838 1239{
d24d5663 1240 enum bt_value_map_insert_entry_status ret;
05e21286 1241 struct bt_value *real_obj = NULL;
dac5c838 1242
17f3083a
SM
1243 BT_ASSERT_PRE_NO_ERROR();
1244
05e21286 1245 real_obj = bt_value_real_create_init(val);
1778c2a4
PP
1246 ret = insert_map_value_entry(map_obj, key,
1247 (void *) real_obj, __func__);
65300d60 1248 bt_object_put_ref(real_obj);
dac5c838
PP
1249 return ret;
1250}
1251
1353b066 1252BT_EXPORT
d24d5663 1253enum bt_value_map_insert_entry_status bt_value_map_insert_string_entry(
05e21286 1254 struct bt_value *map_obj, const char *key,
601b0d3c 1255 const char *val)
dac5c838 1256{
d24d5663 1257 enum bt_value_map_insert_entry_status ret;
05e21286 1258 struct bt_value *string_obj = NULL;
dac5c838 1259
17f3083a
SM
1260 BT_ASSERT_PRE_NO_ERROR();
1261
05e21286 1262 string_obj = bt_value_string_create_init(val);
1778c2a4
PP
1263 ret = insert_map_value_entry(map_obj, key,
1264 (void *) string_obj, __func__);
65300d60 1265 bt_object_put_ref(string_obj);
dac5c838
PP
1266 return ret;
1267}
1268
1353b066 1269BT_EXPORT
d24d5663
PP
1270enum bt_value_map_insert_entry_status
1271bt_value_map_insert_empty_array_entry(
847ab606
PP
1272 struct bt_value *map_obj, const char *key,
1273 bt_value **entry_obj)
dac5c838 1274{
d24d5663 1275 enum bt_value_map_insert_entry_status ret;
05e21286 1276 struct bt_value *array_obj = NULL;
dac5c838 1277
17f3083a
SM
1278 BT_ASSERT_PRE_NO_ERROR();
1279
05e21286 1280 array_obj = bt_value_array_create();
1778c2a4
PP
1281 ret = insert_map_value_entry(map_obj, key,
1282 (void *) array_obj, __func__);
847ab606
PP
1283
1284 if (entry_obj) {
1285 *entry_obj = array_obj;
1286 }
1287
65300d60 1288 bt_object_put_ref(array_obj);
dac5c838
PP
1289 return ret;
1290}
1291
1353b066 1292BT_EXPORT
d24d5663 1293enum bt_value_map_insert_entry_status
847ab606
PP
1294bt_value_map_insert_empty_map_entry(struct bt_value *map_obj, const char *key,
1295 bt_value **entry_obj)
dac5c838 1296{
d24d5663 1297 enum bt_value_map_insert_entry_status ret;
05e21286 1298 struct bt_value *empty_map_obj = NULL;
dac5c838 1299
17f3083a
SM
1300 BT_ASSERT_PRE_NO_ERROR();
1301
05e21286 1302 empty_map_obj = bt_value_map_create();
1778c2a4
PP
1303 ret = insert_map_value_entry(map_obj, key,
1304 (void *) empty_map_obj, __func__);
847ab606
PP
1305
1306 if (entry_obj) {
1307 *entry_obj = empty_map_obj;
1308 }
1309
65300d60 1310 bt_object_put_ref(empty_map_obj);
dac5c838
PP
1311 return ret;
1312}
1313
1778c2a4
PP
1314static
1315enum bt_value_map_foreach_entry_status foreach_map_entry(
d24d5663 1316 struct bt_value *map_obj, bt_value_map_foreach_entry_func func,
1778c2a4
PP
1317 void *data, const char *api_func,
1318 const char *user_func_name)
dac5c838 1319{
27c61ce8 1320 int status = BT_FUNC_STATUS_OK;
dac5c838
PP
1321 gpointer key, element_obj;
1322 GHashTableIter iter;
1323 struct bt_value_map *typed_map_obj = BT_VALUE_TO_MAP(map_obj);
1324
1778c2a4
PP
1325 BT_ASSERT_PRE_NO_ERROR_FROM_FUNC(api_func);
1326 BT_ASSERT_PRE_DEV_VALUE_NON_NULL_FROM_FUNC(api_func, map_obj);
1327 BT_ASSERT_PRE_DEV_NON_NULL_FROM_FUNC(api_func, "user-function",
1328 func, "User function");
1329 BT_ASSERT_PRE_VALUE_HAS_TYPE_FROM_FUNC(api_func, "value-object",
1330 map_obj, "map", BT_VALUE_TYPE_MAP);
dac5c838
PP
1331 g_hash_table_iter_init(&iter, typed_map_obj->ght);
1332
1333 while (g_hash_table_iter_next(&iter, &key, &element_obj)) {
5b44aff2 1334 const char *key_str = g_quark_to_string(GPOINTER_TO_UINT(key));
dac5c838 1335
27c61ce8 1336 status = func(key_str, element_obj, data);
1778c2a4
PP
1337 BT_ASSERT_POST_NO_ERROR_IF_NO_ERROR_STATUS(user_func_name,
1338 status);
27c61ce8
PP
1339 if (status != BT_FUNC_STATUS_OK) {
1340 if (status < 0) {
1341 BT_LIB_LOGE_APPEND_CAUSE(
1342 "User function failed while iterating "
1343 "map value entries: "
1344 "status=%s, key=\"%s\", "
1345 "value-addr=%p, data=%p",
1346 bt_common_func_status_string(status),
1347 key_str, element_obj, data);
1348
1349 if (status == BT_FUNC_STATUS_ERROR) {
1350 /*
1351 * User function error becomes a
1352 * user error from this
1353 * function's caller's
1354 * perspective.
1355 */
1356 status = BT_FUNC_STATUS_USER_ERROR;
1357 }
1358 } else {
1359 BT_ASSERT(status == BT_FUNC_STATUS_INTERRUPTED);
1360 BT_LOGT("User interrupted the loop: status=%s, "
1361 "key=\"%s\", value-addr=%p, data=%p",
1362 bt_common_func_status_string(status),
1363 key_str, element_obj, data);
1364 }
1365
dac5c838
PP
1366 break;
1367 }
1368 }
1369
27c61ce8 1370 return status;
dac5c838
PP
1371}
1372
1353b066 1373BT_EXPORT
1778c2a4
PP
1374enum bt_value_map_foreach_entry_status bt_value_map_foreach_entry(
1375 struct bt_value *map_obj, bt_value_map_foreach_entry_func func,
1376 void *data)
1377{
1378 return foreach_map_entry(map_obj, func, data, __func__,
1379 "bt_value_map_foreach_entry_func");
1380}
1381
1353b066 1382BT_EXPORT
d24d5663 1383enum bt_value_map_foreach_entry_const_status bt_value_map_foreach_entry_const(
05e21286 1384 const struct bt_value *map_obj,
40f4ba76 1385 bt_value_map_foreach_entry_const_func func, void *data)
da91b29a 1386{
1778c2a4
PP
1387 return (int) foreach_map_entry((void *) map_obj,
1388 (bt_value_map_foreach_entry_func) func, data, __func__,
1389 "bt_value_map_foreach_entry_const_func");
da91b29a
PP
1390}
1391
770750d3 1392struct extend_map_element_data {
ab26240f 1393 struct bt_value *base_obj;
770750d3
PP
1394};
1395
1396static
27c61ce8
PP
1397bt_value_map_foreach_entry_const_func_status extend_map_element(
1398 const char *key, const struct bt_value *extension_obj_elem,
1399 void *data)
770750d3 1400{
27c61ce8 1401 int status;
770750d3 1402 struct extend_map_element_data *extend_data = data;
05e21286 1403 struct bt_value *extension_obj_elem_copy = NULL;
770750d3
PP
1404
1405 /* Copy object which is to replace the current one */
27c61ce8
PP
1406 status = bt_value_copy(extension_obj_elem, &extension_obj_elem_copy);
1407 if (status) {
870631a2 1408 BT_LIB_LOGE_APPEND_CAUSE("Cannot copy map element: %!+v",
601b0d3c
PP
1409 extension_obj_elem);
1410 goto error;
1411 }
1412
1413 BT_ASSERT(extension_obj_elem_copy);
770750d3 1414
ab26240f 1415 /* Replace in base map value. */
27c61ce8 1416 status = bt_value_map_insert_entry(extend_data->base_obj, key,
e7279cae 1417 extension_obj_elem_copy);
27c61ce8 1418 if (status) {
870631a2 1419 BT_LIB_LOGE_APPEND_CAUSE(
ab26240f
FD
1420 "Cannot replace value in base map value: key=\"%s\", "
1421 "%![base-map-value-]+v, %![element-value-]+v",
27c61ce8 1422 key, extend_data->base_obj, extension_obj_elem_copy);
770750d3
PP
1423 goto error;
1424 }
1425
1426 goto end;
1427
1428error:
27c61ce8 1429 BT_ASSERT(status < 0);
770750d3
PP
1430
1431end:
65300d60 1432 BT_OBJECT_PUT_REF_AND_RESET(extension_obj_elem_copy);
27c61ce8
PP
1433 BT_ASSERT(status == BT_FUNC_STATUS_OK ||
1434 status == BT_FUNC_STATUS_MEMORY_ERROR);
1435 return status;
770750d3
PP
1436}
1437
1353b066 1438BT_EXPORT
d24d5663 1439enum bt_value_map_extend_status bt_value_map_extend(
ab26240f
FD
1440 struct bt_value *base_map_obj,
1441 const struct bt_value *extension_obj)
770750d3 1442{
27c61ce8 1443 int status = BT_FUNC_STATUS_OK;
601b0d3c 1444 struct extend_map_element_data extend_data = {
ab26240f 1445 .base_obj = NULL,
601b0d3c 1446 };
770750d3 1447
17f3083a 1448 BT_ASSERT_PRE_NO_ERROR();
1778c2a4
PP
1449 BT_ASSERT_PRE_NON_NULL("base-value-object", base_map_obj,
1450 "Base value object");
d5b13b9b 1451 BT_ASSERT_PRE_DEV_VALUE_HOT(base_map_obj);
1778c2a4
PP
1452 BT_ASSERT_PRE_NON_NULL("extension-value-object", extension_obj,
1453 "Extension value object");
1454 BT_ASSERT_PRE_VALUE_HAS_TYPE("base-value-object", base_map_obj,
1455 "map", BT_VALUE_TYPE_MAP);
1456 BT_ASSERT_PRE_VALUE_HAS_TYPE("extension-value-object", extension_obj,
1457 "map", BT_VALUE_TYPE_MAP);
2f42aa0a
PP
1458 BT_LOGD("Extending map value: base-value-addr=%p, extension-value-addr=%p",
1459 base_map_obj, extension_obj);
601b0d3c 1460
770750d3
PP
1461 /*
1462 * For each key in the extension map object, replace this key
ab26240f 1463 * in the base map object.
770750d3 1464 */
ab26240f 1465 extend_data.base_obj = base_map_obj;
27c61ce8
PP
1466 status = bt_value_map_foreach_entry_const(extension_obj,
1467 extend_map_element, &extend_data);
1468 if (status != BT_FUNC_STATUS_OK) {
1469 BT_ASSERT(status == BT_FUNC_STATUS_MEMORY_ERROR);
870631a2
PP
1470 BT_LIB_LOGE_APPEND_CAUSE(
1471 "Cannot iterate on the extension object's elements: "
1472 "%![extension-value-]+v", extension_obj);
770750d3
PP
1473 }
1474
27c61ce8 1475 return status;
770750d3
PP
1476}
1477
1353b066 1478BT_EXPORT
d24d5663 1479enum bt_value_copy_status bt_value_copy(const struct bt_value *object,
6be5a99e 1480 struct bt_value **copy_obj)
dac5c838 1481{
d24d5663 1482 enum bt_value_copy_status status = BT_FUNC_STATUS_OK;
dac5c838 1483
17f3083a 1484 BT_ASSERT_PRE_NO_ERROR();
d5b13b9b 1485 BT_ASSERT_PRE_VALUE_NON_NULL(object);
1778c2a4
PP
1486 BT_ASSERT_PRE_NON_NULL("value-object-copy-output", copy_obj,
1487 "Value object copy (output)");
2f42aa0a 1488 BT_LOGD("Copying value object: addr=%p", object);
601b0d3c
PP
1489 *copy_obj = copy_funcs[object->type](object);
1490 if (*copy_obj) {
2f42aa0a
PP
1491 BT_LOGD("Copied value object: copy-value-addr=%p",
1492 copy_obj);
1493 } else {
d24d5663 1494 status = BT_FUNC_STATUS_MEMORY_ERROR;
601b0d3c 1495 *copy_obj = NULL;
870631a2 1496 BT_LIB_LOGE_APPEND_CAUSE("Failed to copy value object.");
2f42aa0a 1497 }
dac5c838 1498
601b0d3c 1499 return status;
dac5c838
PP
1500}
1501
1353b066 1502BT_EXPORT
cd933d89 1503bt_bool bt_value_is_equal(const struct bt_value *object_a,
dac5c838
PP
1504 const struct bt_value *object_b)
1505{
c55a9f58 1506 bt_bool ret = BT_FALSE;
dac5c838 1507
1778c2a4
PP
1508 BT_ASSERT_PRE_DEV_NON_NULL("value-object-a", object_a,
1509 "Value object A");
1510 BT_ASSERT_PRE_DEV_NON_NULL("value-object-b", object_b,
1511 "Value object B");
dac5c838
PP
1512
1513 if (object_a->type != object_b->type) {
ef267d12 1514 BT_LOGT("Values are different: type mismatch: "
2f42aa0a 1515 "value-a-addr=%p, value-b-addr=%p, "
c4628760 1516 "value-a-type=%s, value-b-type=%s",
2f42aa0a 1517 object_a, object_b,
da91b29a
PP
1518 bt_common_value_type_string(object_a->type),
1519 bt_common_value_type_string(object_b->type));
dac5c838
PP
1520 goto end;
1521 }
1522
cd933d89 1523 ret = is_equal_funcs[object_a->type](object_a, object_b);
dac5c838
PP
1524
1525end:
1526 return ret;
1527}
c5b9b441 1528
1353b066 1529BT_EXPORT
c5b9b441
PP
1530void bt_value_get_ref(const struct bt_value *value)
1531{
1532 bt_object_get_ref(value);
1533}
1534
1353b066 1535BT_EXPORT
c5b9b441
PP
1536void bt_value_put_ref(const struct bt_value *value)
1537{
1538 bt_object_put_ref(value);
1539}
This page took 0.176672 seconds and 4 git commands to generate.