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