lib: value.c: remove BT_VALUE_FROM_CONCRETE() macro
[babeltrace.git] / lib / value.c
CommitLineData
dac5c838 1/*
e2f7325d 2 * Copyright (c) 2015-2018 Philippe Proulx <pproulx@efficios.com>
dac5c838
PP
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */
22
0f5e83e5 23#define BT_LOG_TAG "VALUES"
40547d22 24#include <babeltrace/lib-logging-internal.h>
0f5e83e5 25
dac5c838
PP
26#include <stdlib.h>
27#include <string.h>
dac5c838 28#include <string.h>
2f42aa0a 29#include <inttypes.h>
3d9990ac 30#include <babeltrace/compiler-internal.h>
da91b29a 31#include <babeltrace/common-internal.h>
c6bd8523
PP
32#include <babeltrace/value-const.h>
33#include <babeltrace/value.h>
3d9990ac 34#include <babeltrace/compat/glib-internal.h>
c55a9f58 35#include <babeltrace/types.h>
c5b9b441 36#include <babeltrace/assert-pre-internal.h>
c6bd8523 37#include <babeltrace/value-internal.h>
f6ccaed9 38#include <babeltrace/assert-internal.h>
2f42aa0a 39
dac5c838
PP
40#define BT_VALUE_TO_BOOL(_base) ((struct bt_value_bool *) (_base))
41#define BT_VALUE_TO_INTEGER(_base) ((struct bt_value_integer *) (_base))
a373bf69 42#define BT_VALUE_TO_REAL(_base) ((struct bt_value_real *) (_base))
dac5c838
PP
43#define BT_VALUE_TO_STRING(_base) ((struct bt_value_string *) (_base))
44#define BT_VALUE_TO_ARRAY(_base) ((struct bt_value_array *) (_base))
45#define BT_VALUE_TO_MAP(_base) ((struct bt_value_map *) (_base))
46
f6ccaed9 47#define BT_ASSERT_PRE_VALUE_IS_TYPE(_value, _type) \
da91b29a 48 BT_ASSERT_PRE(((struct bt_value *) (_value))->type == (_type), \
f6ccaed9 49 "Value has the wrong type ID: expected-type=%s, " \
da91b29a 50 "%![value-]+v", bt_common_value_type_string(_type), \
f6ccaed9
PP
51 (_value))
52
53#define BT_ASSERT_PRE_VALUE_HOT(_value, _name) \
da91b29a
PP
54 BT_ASSERT_PRE_HOT(((struct bt_value *) (_value)), (_name), \
55 ": %!+v", (_value))
f6ccaed9
PP
56
57#define BT_ASSERT_PRE_VALUE_INDEX_IN_BOUNDS(_index, _count) \
58 BT_ASSERT_PRE((_index) < (_count), \
59 "Index is out of bound: " \
60 "index=%" PRIu64 ", count=%u", (_index), (_count));
61
3fea54f6
PP
62static
63void bt_value_null_instance_release_func(struct bt_object *obj)
64{
65 BT_LOGW("Releasing the null value singleton: addr=%p", obj);
66}
67
dac5c838
PP
68static
69struct bt_value bt_value_null_instance = {
f685129c 70 .base = {
312c056a 71 .is_shared = true,
3fea54f6
PP
72 .ref_count = 1,
73 .release_func = bt_value_null_instance_release_func,
74 .spec_release_func = NULL,
75 .parent_is_owner_listener_func = NULL,
76 .parent = NULL,
f685129c 77 },
dac5c838 78 .type = BT_VALUE_TYPE_NULL,
f6ccaed9 79 .frozen = BT_TRUE,
dac5c838
PP
80};
81
211796dc 82struct bt_value *const bt_value_null = &bt_value_null_instance;
dac5c838 83
dac5c838 84static
83509119 85void bt_value_destroy(struct bt_object *obj);
dac5c838
PP
86
87static
88void bt_value_string_destroy(struct bt_value *object)
89{
90 g_string_free(BT_VALUE_TO_STRING(object)->gstr, TRUE);
238b7404 91 BT_VALUE_TO_STRING(object)->gstr = NULL;
dac5c838
PP
92}
93
94static
95void bt_value_array_destroy(struct bt_value *object)
96{
97 /*
98 * Pointer array's registered value destructor will take care
99 * of putting each contained object.
100 */
101 g_ptr_array_free(BT_VALUE_TO_ARRAY(object)->garray, TRUE);
238b7404 102 BT_VALUE_TO_ARRAY(object)->garray = NULL;
dac5c838
PP
103}
104
105static
106void bt_value_map_destroy(struct bt_value *object)
107{
108 /*
109 * Hash table's registered value destructor will take care of
110 * putting each contained object. Keys are GQuarks and cannot
111 * be destroyed anyway.
112 */
113 g_hash_table_destroy(BT_VALUE_TO_MAP(object)->ght);
238b7404 114 BT_VALUE_TO_MAP(object)->ght = NULL;
dac5c838
PP
115}
116
117static
118void (* const destroy_funcs[])(struct bt_value *) = {
119 [BT_VALUE_TYPE_NULL] = NULL,
120 [BT_VALUE_TYPE_BOOL] = NULL,
121 [BT_VALUE_TYPE_INTEGER] = NULL,
a373bf69 122 [BT_VALUE_TYPE_REAL] = NULL,
dac5c838
PP
123 [BT_VALUE_TYPE_STRING] = bt_value_string_destroy,
124 [BT_VALUE_TYPE_ARRAY] = bt_value_array_destroy,
125 [BT_VALUE_TYPE_MAP] = bt_value_map_destroy,
126};
127
128static
05e21286 129struct bt_value *bt_value_null_copy(const struct bt_value *null_obj)
dac5c838 130{
da91b29a 131 return (void *) bt_value_null;
dac5c838
PP
132}
133
134static
05e21286 135struct bt_value *bt_value_bool_copy(const struct bt_value *bool_obj)
dac5c838 136{
05e21286 137 return bt_value_bool_create_init(
601b0d3c 138 BT_VALUE_TO_BOOL(bool_obj)->value);
dac5c838
PP
139}
140
141static
05e21286 142struct bt_value *bt_value_integer_copy(
da91b29a 143 const struct bt_value *integer_obj)
dac5c838 144{
05e21286 145 return bt_value_integer_create_init(
dac5c838
PP
146 BT_VALUE_TO_INTEGER(integer_obj)->value);
147}
148
149static
05e21286 150struct bt_value *bt_value_real_copy(const struct bt_value *real_obj)
dac5c838 151{
05e21286 152 return bt_value_real_create_init(
a373bf69 153 BT_VALUE_TO_REAL(real_obj)->value);
dac5c838
PP
154}
155
156static
05e21286 157struct bt_value *bt_value_string_copy(const struct bt_value *string_obj)
dac5c838 158{
05e21286 159 return bt_value_string_create_init(
dac5c838
PP
160 BT_VALUE_TO_STRING(string_obj)->gstr->str);
161}
162
163static
05e21286 164struct bt_value *bt_value_array_copy(const struct bt_value *array_obj)
dac5c838
PP
165{
166 int i;
167 int ret;
05e21286 168 struct bt_value *copy_obj;
dac5c838
PP
169 struct bt_value_array *typed_array_obj;
170
2f42aa0a 171 BT_LOGD("Copying array value: addr=%p", array_obj);
dac5c838 172 typed_array_obj = BT_VALUE_TO_ARRAY(array_obj);
05e21286 173 copy_obj = bt_value_array_create();
dac5c838 174 if (!copy_obj) {
2f42aa0a 175 BT_LOGE_STR("Cannot create empty array value.");
dac5c838
PP
176 goto end;
177 }
178
179 for (i = 0; i < typed_array_obj->garray->len; ++i) {
05e21286
PP
180 struct bt_value *element_obj_copy = NULL;
181 const struct bt_value *element_obj =
182 bt_value_array_borrow_element_by_index_const(
601b0d3c 183 array_obj, i);
dac5c838 184
f6ccaed9 185 BT_ASSERT(element_obj);
40b59ed9
PP
186 BT_LOGD("Copying array value's element: element-addr=%p, "
187 "index=%d", element_obj, i);
6be5a99e 188 ret = bt_value_copy(element_obj, &element_obj_copy);
601b0d3c 189 if (ret) {
2f42aa0a
PP
190 BT_LOGE("Cannot copy array value's element: "
191 "array-addr=%p, index=%d",
192 array_obj, i);
65300d60 193 BT_OBJECT_PUT_REF_AND_RESET(copy_obj);
dac5c838
PP
194 goto end;
195 }
196
601b0d3c 197 BT_ASSERT(element_obj_copy);
05e21286 198 ret = bt_value_array_append_element(copy_obj,
da91b29a 199 (void *) element_obj_copy);
65300d60 200 BT_OBJECT_PUT_REF_AND_RESET(element_obj_copy);
dac5c838 201 if (ret) {
2f42aa0a
PP
202 BT_LOGE("Cannot append to array value: addr=%p",
203 array_obj);
65300d60 204 BT_OBJECT_PUT_REF_AND_RESET(copy_obj);
dac5c838
PP
205 goto end;
206 }
207 }
208
a704fb0b
PP
209 BT_LOGD("Copied array value: original-addr=%p, copy-addr=%p",
210 array_obj, copy_obj);
2f42aa0a 211
dac5c838
PP
212end:
213 return copy_obj;
214}
215
216static
05e21286 217struct bt_value *bt_value_map_copy(const struct bt_value *map_obj)
dac5c838
PP
218{
219 int ret;
220 GHashTableIter iter;
221 gpointer key, element_obj;
05e21286
PP
222 struct bt_value *copy_obj;
223 struct bt_value *element_obj_copy = NULL;
dac5c838
PP
224 struct bt_value_map *typed_map_obj;
225
2f42aa0a 226 BT_LOGD("Copying map value: addr=%p", map_obj);
dac5c838 227 typed_map_obj = BT_VALUE_TO_MAP(map_obj);
05e21286 228 copy_obj = bt_value_map_create();
dac5c838
PP
229 if (!copy_obj) {
230 goto end;
231 }
232
233 g_hash_table_iter_init(&iter, typed_map_obj->ght);
234
235 while (g_hash_table_iter_next(&iter, &key, &element_obj)) {
5b44aff2 236 const char *key_str = g_quark_to_string(GPOINTER_TO_UINT(key));
dac5c838 237
f6ccaed9 238 BT_ASSERT(key_str);
40b59ed9
PP
239 BT_LOGD("Copying map value's element: element-addr=%p, "
240 "key=\"%s\"", element_obj, key_str);
6be5a99e 241 ret = bt_value_copy(element_obj, &element_obj_copy);
601b0d3c 242 if (ret) {
2f42aa0a
PP
243 BT_LOGE("Cannot copy map value's element: "
244 "map-addr=%p, key=\"%s\"",
245 map_obj, key_str);
65300d60 246 BT_OBJECT_PUT_REF_AND_RESET(copy_obj);
dac5c838
PP
247 goto end;
248 }
249
601b0d3c 250 BT_ASSERT(element_obj_copy);
05e21286 251 ret = bt_value_map_insert_entry(copy_obj, key_str,
da91b29a 252 (void *) element_obj_copy);
65300d60 253 BT_OBJECT_PUT_REF_AND_RESET(element_obj_copy);
dac5c838 254 if (ret) {
2f42aa0a
PP
255 BT_LOGE("Cannot insert into map value: addr=%p, key=\"%s\"",
256 map_obj, key_str);
65300d60 257 BT_OBJECT_PUT_REF_AND_RESET(copy_obj);
dac5c838
PP
258 goto end;
259 }
260 }
261
2f42aa0a
PP
262 BT_LOGD("Copied map value: addr=%p", map_obj);
263
dac5c838
PP
264end:
265 return copy_obj;
266}
267
268static
05e21286 269struct bt_value *(* const copy_funcs[])(const struct bt_value *) = {
dac5c838
PP
270 [BT_VALUE_TYPE_NULL] = bt_value_null_copy,
271 [BT_VALUE_TYPE_BOOL] = bt_value_bool_copy,
272 [BT_VALUE_TYPE_INTEGER] = bt_value_integer_copy,
a373bf69 273 [BT_VALUE_TYPE_REAL] = bt_value_real_copy,
dac5c838
PP
274 [BT_VALUE_TYPE_STRING] = bt_value_string_copy,
275 [BT_VALUE_TYPE_ARRAY] = bt_value_array_copy,
276 [BT_VALUE_TYPE_MAP] = bt_value_map_copy,
277};
278
279static
c55a9f58 280bt_bool bt_value_null_compare(const struct bt_value *object_a,
dac5c838
PP
281 const struct bt_value *object_b)
282{
283 /*
c55a9f58 284 * Always BT_TRUE since bt_value_compare() already checks if both
dac5c838
PP
285 * object_a and object_b have the same type, and in the case of
286 * null value objects, they're always the same if it is so.
287 */
c55a9f58 288 return BT_TRUE;
dac5c838
PP
289}
290
291static
c55a9f58 292bt_bool bt_value_bool_compare(const struct bt_value *object_a,
dac5c838
PP
293 const struct bt_value *object_b)
294{
40b59ed9
PP
295 if (BT_VALUE_TO_BOOL(object_a)->value !=
296 BT_VALUE_TO_BOOL(object_b)->value) {
297 BT_LOGV("Boolean value objects are different: "
298 "bool-a-val=%d, bool-b-val=%d",
299 BT_VALUE_TO_BOOL(object_a)->value,
300 BT_VALUE_TO_BOOL(object_b)->value);
301 return BT_FALSE;
302 }
303
304 return BT_TRUE;
dac5c838
PP
305}
306
307static
c55a9f58 308bt_bool bt_value_integer_compare(const struct bt_value *object_a,
dac5c838
PP
309 const struct bt_value *object_b)
310{
40b59ed9
PP
311 if (BT_VALUE_TO_INTEGER(object_a)->value !=
312 BT_VALUE_TO_INTEGER(object_b)->value) {
313 BT_LOGV("Integer value objects are different: "
314 "int-a-val=%" PRId64 ", int-b-val=%" PRId64,
315 BT_VALUE_TO_INTEGER(object_a)->value,
316 BT_VALUE_TO_INTEGER(object_b)->value);
317 return BT_FALSE;
318 }
319
320 return BT_TRUE;
dac5c838
PP
321}
322
323static
a373bf69 324bt_bool bt_value_real_compare(const struct bt_value *object_a,
dac5c838
PP
325 const struct bt_value *object_b)
326{
a373bf69
PP
327 if (BT_VALUE_TO_REAL(object_a)->value !=
328 BT_VALUE_TO_REAL(object_b)->value) {
329 BT_LOGV("Real number value objects are different: "
330 "real-a-val=%f, real-b-val=%f",
331 BT_VALUE_TO_REAL(object_a)->value,
332 BT_VALUE_TO_REAL(object_b)->value);
40b59ed9
PP
333 return BT_FALSE;
334 }
335
336 return BT_TRUE;
dac5c838
PP
337}
338
339static
c55a9f58 340bt_bool bt_value_string_compare(const struct bt_value *object_a,
dac5c838
PP
341 const struct bt_value *object_b)
342{
40b59ed9
PP
343 if (strcmp(BT_VALUE_TO_STRING(object_a)->gstr->str,
344 BT_VALUE_TO_STRING(object_b)->gstr->str) != 0) {
345 BT_LOGV("String value objects are different: "
346 "string-a-val=\"%s\", string-b-val=\"%s\"",
347 BT_VALUE_TO_STRING(object_a)->gstr->str,
348 BT_VALUE_TO_STRING(object_b)->gstr->str);
349 return BT_FALSE;
350 }
351
352 return BT_TRUE;
dac5c838
PP
353}
354
355static
c55a9f58 356bt_bool bt_value_array_compare(const struct bt_value *object_a,
dac5c838
PP
357 const struct bt_value *object_b)
358{
359 int i;
c55a9f58 360 bt_bool ret = BT_TRUE;
dac5c838
PP
361 const struct bt_value_array *array_obj_a =
362 BT_VALUE_TO_ARRAY(object_a);
363
da91b29a
PP
364 if (bt_value_array_get_size(object_a) !=
365 bt_value_array_get_size(object_b)) {
2f42aa0a
PP
366 BT_LOGV("Array values are different: size mismatch "
367 "value-a-addr=%p, value-b-addr=%p, "
368 "value-a-size=%" PRId64 ", value-b-size=%" PRId64,
369 object_a, object_b,
07208d85
PP
370 bt_value_array_get_size(object_a),
371 bt_value_array_get_size(object_b));
c55a9f58 372 ret = BT_FALSE;
dac5c838
PP
373 goto end;
374 }
375
376 for (i = 0; i < array_obj_a->garray->len; ++i) {
05e21286
PP
377 const struct bt_value *element_obj_a;
378 const struct bt_value *element_obj_b;
dac5c838 379
05e21286 380 element_obj_a = bt_value_array_borrow_element_by_index_const(
da91b29a 381 object_a, i);
05e21286 382 element_obj_b = bt_value_array_borrow_element_by_index_const(
da91b29a 383 object_b, i);
dac5c838
PP
384
385 if (!bt_value_compare(element_obj_a, element_obj_b)) {
2f42aa0a
PP
386 BT_LOGV("Array values's elements are different: "
387 "value-a-addr=%p, value-b-addr=%p, index=%d",
32e87ceb 388 element_obj_a, element_obj_b, i);
c55a9f58 389 ret = BT_FALSE;
dac5c838
PP
390 goto end;
391 }
dac5c838
PP
392 }
393
394end:
395 return ret;
396}
397
398static
c55a9f58 399bt_bool bt_value_map_compare(const struct bt_value *object_a,
dac5c838
PP
400 const struct bt_value *object_b)
401{
c55a9f58 402 bt_bool ret = BT_TRUE;
dac5c838
PP
403 GHashTableIter iter;
404 gpointer key, element_obj_a;
405 const struct bt_value_map *map_obj_a = BT_VALUE_TO_MAP(object_a);
406
601b0d3c
PP
407 if (bt_value_map_get_size(object_a) !=
408 bt_value_map_get_size(object_b)) {
2f42aa0a
PP
409 BT_LOGV("Map values are different: size mismatch "
410 "value-a-addr=%p, value-b-addr=%p, "
411 "value-a-size=%" PRId64 ", value-b-size=%" PRId64,
412 object_a, object_b,
07208d85
PP
413 bt_value_map_get_size(object_a),
414 bt_value_map_get_size(object_b));
c55a9f58 415 ret = BT_FALSE;
dac5c838
PP
416 goto end;
417 }
418
419 g_hash_table_iter_init(&iter, map_obj_a->ght);
420
421 while (g_hash_table_iter_next(&iter, &key, &element_obj_a)) {
05e21286 422 const struct bt_value *element_obj_b;
5b44aff2 423 const char *key_str = g_quark_to_string(GPOINTER_TO_UINT(key));
dac5c838 424
05e21286 425 element_obj_b = bt_value_map_borrow_entry_value_const(object_b,
da91b29a 426 key_str);
dac5c838
PP
427
428 if (!bt_value_compare(element_obj_a, element_obj_b)) {
2f42aa0a
PP
429 BT_LOGV("Map values's elements are different: "
430 "value-a-addr=%p, value-b-addr=%p, key=\"%s\"",
431 element_obj_a, element_obj_b, key_str);
c55a9f58 432 ret = BT_FALSE;
dac5c838
PP
433 goto end;
434 }
dac5c838
PP
435 }
436
437end:
438 return ret;
439}
440
441static
c55a9f58 442bt_bool (* const compare_funcs[])(const struct bt_value *,
dac5c838
PP
443 const struct bt_value *) = {
444 [BT_VALUE_TYPE_NULL] = bt_value_null_compare,
445 [BT_VALUE_TYPE_BOOL] = bt_value_bool_compare,
446 [BT_VALUE_TYPE_INTEGER] = bt_value_integer_compare,
a373bf69 447 [BT_VALUE_TYPE_REAL] = bt_value_real_compare,
dac5c838 448 [BT_VALUE_TYPE_STRING] = bt_value_string_compare,
40b59ed9 449 [BT_VALUE_TYPE_ARRAY] = bt_value_array_compare,
dac5c838
PP
450 [BT_VALUE_TYPE_MAP] = bt_value_map_compare,
451};
452
f6ccaed9 453static
dac5c838
PP
454void bt_value_null_freeze(struct bt_value *object)
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 *) = {
496 [BT_VALUE_TYPE_NULL] = bt_value_null_freeze,
497 [BT_VALUE_TYPE_BOOL] = bt_value_generic_freeze,
498 [BT_VALUE_TYPE_INTEGER] = bt_value_generic_freeze,
a373bf69 499 [BT_VALUE_TYPE_REAL] = bt_value_generic_freeze,
dac5c838
PP
500 [BT_VALUE_TYPE_STRING] = bt_value_generic_freeze,
501 [BT_VALUE_TYPE_ARRAY] = bt_value_array_freeze,
502 [BT_VALUE_TYPE_MAP] = bt_value_map_freeze,
503};
504
505static
83509119 506void bt_value_destroy(struct bt_object *obj)
dac5c838 507{
83509119 508 struct bt_value *value;
dac5c838 509
83509119 510 value = container_of(obj, struct bt_value, base);
2f42aa0a
PP
511 BT_LOGD("Destroying value: addr=%p", value);
512
83509119 513 if (bt_value_is_null(value)) {
2f42aa0a 514 BT_LOGD_STR("Not destroying the null value singleton.");
dac5c838
PP
515 return;
516 }
517
83509119
JG
518 if (destroy_funcs[value->type]) {
519 destroy_funcs[value->type](value);
dac5c838
PP
520 }
521
83509119 522 g_free(value);
dac5c838
PP
523}
524
f6ccaed9 525BT_HIDDEN
05e21286 526enum bt_value_status _bt_value_freeze(const struct bt_value *c_object)
dac5c838 527{
05e21286 528 const struct bt_value *object = (void *) c_object;
dac5c838
PP
529 enum bt_value_status ret = BT_VALUE_STATUS_OK;
530
f6ccaed9 531 BT_ASSERT(object);
dac5c838 532
f6ccaed9 533 if (object->frozen) {
2f42aa0a
PP
534 goto end;
535 }
536
537 BT_LOGD("Freezing value: addr=%p", object);
05e21286 538 freeze_funcs[object->type]((void *) object);
dac5c838
PP
539
540end:
541 return ret;
542}
543
dac5c838
PP
544enum bt_value_type bt_value_get_type(const struct bt_value *object)
545{
f6ccaed9 546 BT_ASSERT_PRE_NON_NULL(object, "Value 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
05e21286 561struct bt_value *bt_value_bool_create_init(bt_bool val)
dac5c838
PP
562{
563 struct bt_value_bool *bool_obj;
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) {
2f42aa0a 568 BT_LOGE_STR("Failed to allocate one boolean value object.");
dac5c838
PP
569 goto end;
570 }
571
572 bool_obj->base = bt_value_create_base(BT_VALUE_TYPE_BOOL);
573 bool_obj->value = val;
2f42aa0a 574 BT_LOGD("Created boolean value object: addr=%p", bool_obj);
dac5c838
PP
575
576end:
11cd69be 577 return (void *) bool_obj;
dac5c838
PP
578}
579
05e21286 580struct bt_value *bt_value_bool_create(void)
dac5c838 581{
05e21286 582 return bt_value_bool_create_init(BT_FALSE);
dac5c838
PP
583}
584
05e21286 585struct bt_value *bt_value_integer_create_init(int64_t val)
dac5c838
PP
586{
587 struct bt_value_integer *integer_obj;
588
2f42aa0a 589 BT_LOGD("Creating integer value object: val=%" PRId64, val);
dac5c838 590 integer_obj = g_new0(struct bt_value_integer, 1);
dac5c838 591 if (!integer_obj) {
2f42aa0a 592 BT_LOGE_STR("Failed to allocate one integer value object.");
dac5c838
PP
593 goto end;
594 }
595
596 integer_obj->base = bt_value_create_base(BT_VALUE_TYPE_INTEGER);
597 integer_obj->value = val;
2f42aa0a
PP
598 BT_LOGD("Created integer value object: addr=%p",
599 integer_obj);
dac5c838
PP
600
601end:
11cd69be 602 return (void *) integer_obj;
dac5c838
PP
603}
604
05e21286 605struct bt_value *bt_value_integer_create(void)
dac5c838 606{
05e21286 607 return bt_value_integer_create_init(0);
dac5c838
PP
608}
609
05e21286 610struct bt_value *bt_value_real_create_init(double val)
dac5c838 611{
a373bf69 612 struct bt_value_real *real_obj;
dac5c838 613
a373bf69
PP
614 BT_LOGD("Creating real number value object: val=%f", val);
615 real_obj = g_new0(struct bt_value_real, 1);
616 if (!real_obj) {
617 BT_LOGE_STR("Failed to allocate one real number value object.");
dac5c838
PP
618 goto end;
619 }
620
a373bf69
PP
621 real_obj->base = bt_value_create_base(BT_VALUE_TYPE_REAL);
622 real_obj->value = val;
623 BT_LOGD("Created real number value object: addr=%p",
624 real_obj);
dac5c838
PP
625
626end:
11cd69be 627 return (void *) real_obj;
dac5c838
PP
628}
629
05e21286 630struct bt_value *bt_value_real_create(void)
dac5c838 631{
05e21286 632 return bt_value_real_create_init(0.);
dac5c838
PP
633}
634
05e21286 635struct bt_value *bt_value_string_create_init(const char *val)
dac5c838
PP
636{
637 struct bt_value_string *string_obj = NULL;
638
639 if (!val) {
2f42aa0a 640 BT_LOGW_STR("Invalid parameter: value is NULL.");
dac5c838
PP
641 goto end;
642 }
643
003c7749 644 BT_LOGD("Creating string value object: val-len=%zu", strlen(val));
dac5c838 645 string_obj = g_new0(struct bt_value_string, 1);
dac5c838 646 if (!string_obj) {
2f42aa0a 647 BT_LOGE_STR("Failed to allocate one string object.");
dac5c838
PP
648 goto end;
649 }
650
651 string_obj->base = bt_value_create_base(BT_VALUE_TYPE_STRING);
652 string_obj->gstr = g_string_new(val);
dac5c838 653 if (!string_obj->gstr) {
2f42aa0a 654 BT_LOGE_STR("Failed to allocate a GString.");
dac5c838
PP
655 g_free(string_obj);
656 string_obj = NULL;
657 goto end;
658 }
659
2f42aa0a
PP
660 BT_LOGD("Created string value object: addr=%p",
661 string_obj);
662
dac5c838 663end:
11cd69be 664 return (void *) string_obj;
dac5c838
PP
665}
666
05e21286 667struct bt_value *bt_value_string_create(void)
dac5c838 668{
05e21286 669 return bt_value_string_create_init("");
dac5c838
PP
670}
671
05e21286 672struct bt_value *bt_value_array_create(void)
dac5c838
PP
673{
674 struct bt_value_array *array_obj;
675
2f42aa0a 676 BT_LOGD_STR("Creating empty array value object.");
dac5c838 677 array_obj = g_new0(struct bt_value_array, 1);
dac5c838 678 if (!array_obj) {
2f42aa0a 679 BT_LOGE_STR("Failed to allocate one array object.");
dac5c838
PP
680 goto end;
681 }
682
683 array_obj->base = bt_value_create_base(BT_VALUE_TYPE_ARRAY);
5d5982ab 684 array_obj->garray = bt_g_ptr_array_new_full(0,
65300d60 685 (GDestroyNotify) bt_object_put_ref);
dac5c838 686 if (!array_obj->garray) {
2f42aa0a 687 BT_LOGE_STR("Failed to allocate a GPtrArray.");
dac5c838
PP
688 g_free(array_obj);
689 array_obj = NULL;
690 goto end;
691 }
692
2f42aa0a
PP
693 BT_LOGD("Created array value object: addr=%p",
694 array_obj);
695
dac5c838 696end:
11cd69be 697 return (void *) array_obj;
dac5c838
PP
698}
699
05e21286 700struct bt_value *bt_value_map_create(void)
dac5c838
PP
701{
702 struct bt_value_map *map_obj;
703
2f42aa0a 704 BT_LOGD_STR("Creating empty map value object.");
dac5c838 705 map_obj = g_new0(struct bt_value_map, 1);
dac5c838 706 if (!map_obj) {
2f42aa0a 707 BT_LOGE_STR("Failed to allocate one map object.");
dac5c838
PP
708 goto end;
709 }
710
711 map_obj->base = bt_value_create_base(BT_VALUE_TYPE_MAP);
712 map_obj->ght = g_hash_table_new_full(g_direct_hash, g_direct_equal,
65300d60 713 NULL, (GDestroyNotify) bt_object_put_ref);
dac5c838 714 if (!map_obj->ght) {
2f42aa0a 715 BT_LOGE_STR("Failed to allocate a GHashTable.");
dac5c838
PP
716 g_free(map_obj);
717 map_obj = NULL;
718 goto end;
719 }
720
2f42aa0a
PP
721 BT_LOGD("Created map value object: addr=%p",
722 map_obj);
723
dac5c838 724end:
11cd69be 725 return (void *) map_obj;
dac5c838
PP
726}
727
601b0d3c 728bt_bool bt_value_bool_get(const struct bt_value *bool_obj)
dac5c838 729{
f6ccaed9 730 BT_ASSERT_PRE_NON_NULL(bool_obj, "Value object");
f6ccaed9 731 BT_ASSERT_PRE_VALUE_IS_TYPE(bool_obj, BT_VALUE_TYPE_BOOL);
601b0d3c 732 return BT_VALUE_TO_BOOL(bool_obj)->value;
dac5c838
PP
733}
734
05e21286 735void bt_value_bool_set(struct bt_value *bool_obj, bt_bool val)
dac5c838 736{
f6ccaed9
PP
737 BT_ASSERT_PRE_NON_NULL(bool_obj, "Value object");
738 BT_ASSERT_PRE_VALUE_IS_TYPE(bool_obj, BT_VALUE_TYPE_BOOL);
739 BT_ASSERT_PRE_VALUE_HOT(bool_obj, "Value object");
740 BT_VALUE_TO_BOOL(bool_obj)->value = val;
2f42aa0a
PP
741 BT_LOGV("Set boolean value's raw value: value-addr=%p, value=%d",
742 bool_obj, val);
dac5c838
PP
743}
744
601b0d3c 745int64_t bt_value_integer_get(const struct bt_value *integer_obj)
dac5c838 746{
f6ccaed9 747 BT_ASSERT_PRE_NON_NULL(integer_obj, "Value object");
f6ccaed9 748 BT_ASSERT_PRE_VALUE_IS_TYPE(integer_obj, BT_VALUE_TYPE_INTEGER);
601b0d3c 749 return BT_VALUE_TO_INTEGER(integer_obj)->value;
dac5c838
PP
750}
751
05e21286 752void bt_value_integer_set(struct bt_value *integer_obj,
364747d6 753 int64_t val)
dac5c838 754{
f6ccaed9
PP
755 BT_ASSERT_PRE_NON_NULL(integer_obj, "Value object");
756 BT_ASSERT_PRE_VALUE_IS_TYPE(integer_obj, BT_VALUE_TYPE_INTEGER);
757 BT_ASSERT_PRE_VALUE_HOT(integer_obj, "Value object");
758 BT_VALUE_TO_INTEGER(integer_obj)->value = val;
2f42aa0a
PP
759 BT_LOGV("Set integer value's raw value: value-addr=%p, value=%" PRId64,
760 integer_obj, val);
dac5c838
PP
761}
762
601b0d3c 763double bt_value_real_get(const struct bt_value *real_obj)
dac5c838 764{
a373bf69 765 BT_ASSERT_PRE_NON_NULL(real_obj, "Value object");
a373bf69 766 BT_ASSERT_PRE_VALUE_IS_TYPE(real_obj, BT_VALUE_TYPE_REAL);
601b0d3c 767 return BT_VALUE_TO_REAL(real_obj)->value;
dac5c838
PP
768}
769
05e21286 770void bt_value_real_set(struct bt_value *real_obj, double val)
dac5c838 771{
a373bf69
PP
772 BT_ASSERT_PRE_NON_NULL(real_obj, "Value object");
773 BT_ASSERT_PRE_VALUE_IS_TYPE(real_obj, BT_VALUE_TYPE_REAL);
774 BT_ASSERT_PRE_VALUE_HOT(real_obj, "Value object");
775 BT_VALUE_TO_REAL(real_obj)->value = val;
776 BT_LOGV("Set real number value's raw value: value-addr=%p, value=%f",
777 real_obj, val);
dac5c838
PP
778}
779
601b0d3c 780const char *bt_value_string_get(const struct bt_value *string_obj)
dac5c838 781{
f6ccaed9 782 BT_ASSERT_PRE_NON_NULL(string_obj, "Value object");
f6ccaed9 783 BT_ASSERT_PRE_VALUE_IS_TYPE(string_obj, BT_VALUE_TYPE_STRING);
601b0d3c 784 return BT_VALUE_TO_STRING(string_obj)->gstr->str;
dac5c838
PP
785}
786
05e21286
PP
787enum bt_value_status bt_value_string_set(
788 struct bt_value *string_obj, const char *val)
dac5c838 789{
f6ccaed9 790 BT_ASSERT_PRE_NON_NULL(string_obj, "Value object");
f6ccaed9
PP
791 BT_ASSERT_PRE_VALUE_IS_TYPE(string_obj, BT_VALUE_TYPE_STRING);
792 BT_ASSERT_PRE_VALUE_HOT(string_obj, "Value object");
793 g_string_assign(BT_VALUE_TO_STRING(string_obj)->gstr, val);
2f42aa0a
PP
794 BT_LOGV("Set string value's raw value: value-addr=%p, raw-value-addr=%p",
795 string_obj, val);
f6ccaed9 796 return BT_VALUE_STATUS_OK;
dac5c838
PP
797}
798
601b0d3c 799uint64_t bt_value_array_get_size(const struct bt_value *array_obj)
dac5c838 800{
f6ccaed9
PP
801 BT_ASSERT_PRE_NON_NULL(array_obj, "Value object");
802 BT_ASSERT_PRE_VALUE_IS_TYPE(array_obj, BT_VALUE_TYPE_ARRAY);
601b0d3c 803 return (uint64_t) BT_VALUE_TO_ARRAY(array_obj)->garray->len;
dac5c838
PP
804}
805
da91b29a 806struct bt_value *bt_value_array_borrow_element_by_index(
05e21286 807 struct bt_value *array_obj, uint64_t index)
dac5c838 808{
dac5c838
PP
809 struct bt_value_array *typed_array_obj =
810 BT_VALUE_TO_ARRAY(array_obj);
811
f6ccaed9
PP
812 BT_ASSERT_PRE_NON_NULL(array_obj, "Value object");
813 BT_ASSERT_PRE_VALUE_IS_TYPE(array_obj, BT_VALUE_TYPE_ARRAY);
814 BT_ASSERT_PRE_VALUE_INDEX_IN_BOUNDS(index,
815 typed_array_obj->garray->len);
094ff7c0 816 return g_ptr_array_index(typed_array_obj->garray, index);
dac5c838
PP
817}
818
05e21286
PP
819const struct bt_value *bt_value_array_borrow_element_by_index_const(
820 const struct bt_value *array_obj,
da91b29a
PP
821 uint64_t index)
822{
05e21286 823 return bt_value_array_borrow_element_by_index(
da91b29a
PP
824 (void *) array_obj, index);
825}
826
05e21286
PP
827enum bt_value_status bt_value_array_append_element(
828 struct bt_value *array_obj,
364747d6 829 struct bt_value *element_obj)
dac5c838 830{
dac5c838
PP
831 struct bt_value_array *typed_array_obj =
832 BT_VALUE_TO_ARRAY(array_obj);
833
f6ccaed9
PP
834 BT_ASSERT_PRE_NON_NULL(array_obj, "Array value object");
835 BT_ASSERT_PRE_NON_NULL(element_obj, "Element value object");
836 BT_ASSERT_PRE_VALUE_IS_TYPE(array_obj, BT_VALUE_TYPE_ARRAY);
837 BT_ASSERT_PRE_VALUE_HOT(array_obj, "Array value object");
dac5c838 838 g_ptr_array_add(typed_array_obj->garray, element_obj);
65300d60 839 bt_object_get_ref(element_obj);
2f42aa0a
PP
840 BT_LOGV("Appended element to array value: array-value-addr=%p, "
841 "element-value-addr=%p, new-size=%u",
842 array_obj, element_obj, typed_array_obj->garray->len);
f6ccaed9 843 return BT_VALUE_STATUS_OK;
dac5c838
PP
844}
845
05e21286
PP
846enum bt_value_status bt_value_array_append_bool_element(
847 struct bt_value *array_obj, bt_bool val)
dac5c838
PP
848{
849 enum bt_value_status ret;
05e21286 850 struct bt_value *bool_obj = NULL;
dac5c838 851
05e21286
PP
852 bool_obj = bt_value_bool_create_init(val);
853 ret = bt_value_array_append_element(array_obj,
da91b29a 854 (void *) bool_obj);
65300d60 855 bt_object_put_ref(bool_obj);
dac5c838
PP
856 return ret;
857}
858
05e21286
PP
859enum bt_value_status bt_value_array_append_integer_element(
860 struct bt_value *array_obj, int64_t val)
dac5c838
PP
861{
862 enum bt_value_status ret;
05e21286 863 struct bt_value *integer_obj = NULL;
dac5c838 864
05e21286
PP
865 integer_obj = bt_value_integer_create_init(val);
866 ret = bt_value_array_append_element(array_obj,
da91b29a 867 (void *) integer_obj);
65300d60 868 bt_object_put_ref(integer_obj);
dac5c838
PP
869 return ret;
870}
871
05e21286
PP
872enum bt_value_status bt_value_array_append_real_element(
873 struct bt_value *array_obj, double val)
dac5c838
PP
874{
875 enum bt_value_status ret;
05e21286 876 struct bt_value *real_obj = NULL;
dac5c838 877
05e21286
PP
878 real_obj = bt_value_real_create_init(val);
879 ret = bt_value_array_append_element(array_obj,
da91b29a 880 (void *) real_obj);
65300d60 881 bt_object_put_ref(real_obj);
dac5c838
PP
882 return ret;
883}
884
05e21286
PP
885enum bt_value_status bt_value_array_append_string_element(
886 struct bt_value *array_obj, const char *val)
dac5c838
PP
887{
888 enum bt_value_status ret;
05e21286 889 struct bt_value *string_obj = NULL;
dac5c838 890
05e21286
PP
891 string_obj = bt_value_string_create_init(val);
892 ret = bt_value_array_append_element(array_obj,
da91b29a 893 (void *) string_obj);
65300d60 894 bt_object_put_ref(string_obj);
dac5c838
PP
895 return ret;
896}
897
05e21286
PP
898enum bt_value_status bt_value_array_append_empty_array_element(
899 struct bt_value *array_obj)
dac5c838
PP
900{
901 enum bt_value_status ret;
05e21286 902 struct bt_value *empty_array_obj = NULL;
dac5c838 903
05e21286
PP
904 empty_array_obj = bt_value_array_create();
905 ret = bt_value_array_append_element(array_obj,
da91b29a 906 (void *) empty_array_obj);
65300d60 907 bt_object_put_ref(empty_array_obj);
dac5c838
PP
908 return ret;
909}
910
05e21286
PP
911enum bt_value_status bt_value_array_append_empty_map_element(
912 struct bt_value *array_obj)
dac5c838
PP
913{
914 enum bt_value_status ret;
05e21286 915 struct bt_value *map_obj = NULL;
dac5c838 916
05e21286
PP
917 map_obj = bt_value_map_create();
918 ret = bt_value_array_append_element(array_obj,
da91b29a 919 (void *) map_obj);
65300d60 920 bt_object_put_ref(map_obj);
dac5c838
PP
921 return ret;
922}
923
05e21286
PP
924enum bt_value_status bt_value_array_set_element_by_index(
925 struct bt_value *array_obj, uint64_t index,
da91b29a 926 struct bt_value *element_obj)
dac5c838 927{
dac5c838
PP
928 struct bt_value_array *typed_array_obj =
929 BT_VALUE_TO_ARRAY(array_obj);
930
f6ccaed9
PP
931 BT_ASSERT_PRE_NON_NULL(array_obj, "Array value object");
932 BT_ASSERT_PRE_NON_NULL(element_obj, "Element value object");
933 BT_ASSERT_PRE_VALUE_IS_TYPE(array_obj, BT_VALUE_TYPE_ARRAY);
934 BT_ASSERT_PRE_VALUE_HOT(array_obj, "Array value object");
935 BT_ASSERT_PRE_VALUE_INDEX_IN_BOUNDS(index,
936 typed_array_obj->garray->len);
65300d60 937 bt_object_put_ref(g_ptr_array_index(typed_array_obj->garray, index));
dac5c838 938 g_ptr_array_index(typed_array_obj->garray, index) = element_obj;
65300d60 939 bt_object_get_ref(element_obj);
2f42aa0a
PP
940 BT_LOGV("Set array value's element: array-value-addr=%p, "
941 "index=%" PRIu64 ", element-value-addr=%p",
942 array_obj, index, element_obj);
f6ccaed9 943 return BT_VALUE_STATUS_OK;
dac5c838
PP
944}
945
601b0d3c 946uint64_t bt_value_map_get_size(const struct bt_value *map_obj)
dac5c838 947{
f6ccaed9
PP
948 BT_ASSERT_PRE_NON_NULL(map_obj, "Value object");
949 BT_ASSERT_PRE_VALUE_IS_TYPE(map_obj, BT_VALUE_TYPE_MAP);
601b0d3c 950 return (uint64_t) g_hash_table_size(BT_VALUE_TO_MAP(map_obj)->ght);
dac5c838
PP
951}
952
05e21286 953struct bt_value *bt_value_map_borrow_entry_value(struct bt_value *map_obj,
364747d6 954 const char *key)
dac5c838 955{
f6ccaed9
PP
956 BT_ASSERT_PRE_NON_NULL(map_obj, "Value object");
957 BT_ASSERT_PRE_NON_NULL(key, "Key");
958 BT_ASSERT_PRE_VALUE_IS_TYPE(map_obj, BT_VALUE_TYPE_MAP);
094ff7c0
PP
959 return g_hash_table_lookup(BT_VALUE_TO_MAP(map_obj)->ght,
960 GUINT_TO_POINTER(g_quark_from_string(key)));
dac5c838
PP
961}
962
05e21286
PP
963const struct bt_value *bt_value_map_borrow_entry_value_const(
964 const struct bt_value *map_obj, const char *key)
da91b29a 965{
05e21286 966 return bt_value_map_borrow_entry_value((void *) map_obj, key);
da91b29a
PP
967}
968
07208d85 969bt_bool bt_value_map_has_entry(const struct bt_value *map_obj, const char *key)
dac5c838 970{
f6ccaed9
PP
971 BT_ASSERT_PRE_NON_NULL(map_obj, "Value object");
972 BT_ASSERT_PRE_NON_NULL(key, "Key");
973 BT_ASSERT_PRE_VALUE_IS_TYPE(map_obj, BT_VALUE_TYPE_MAP);
974 return bt_g_hash_table_contains(BT_VALUE_TO_MAP(map_obj)->ght,
975 GUINT_TO_POINTER(g_quark_from_string(key)));
dac5c838
PP
976}
977
05e21286
PP
978enum bt_value_status bt_value_map_insert_entry(
979 struct bt_value *map_obj,
364747d6 980 const char *key, struct bt_value *element_obj)
dac5c838 981{
f6ccaed9
PP
982 BT_ASSERT_PRE_NON_NULL(map_obj, "Map value object");
983 BT_ASSERT_PRE_NON_NULL(key, "Key");
984 BT_ASSERT_PRE_NON_NULL(element_obj, "Element value object");
985 BT_ASSERT_PRE_VALUE_IS_TYPE(map_obj, BT_VALUE_TYPE_MAP);
986 BT_ASSERT_PRE_VALUE_HOT(map_obj, "Map value object");
987 g_hash_table_insert(BT_VALUE_TO_MAP(map_obj)->ght,
988 GUINT_TO_POINTER(g_quark_from_string(key)), element_obj);
65300d60 989 bt_object_get_ref(element_obj);
2f42aa0a
PP
990 BT_LOGV("Inserted value into map value: map-value-addr=%p, "
991 "key=\"%s\", element-value-addr=%p",
992 map_obj, key, element_obj);
f6ccaed9 993 return BT_VALUE_STATUS_OK;
dac5c838
PP
994}
995
05e21286
PP
996enum bt_value_status bt_value_map_insert_bool_entry(
997 struct bt_value *map_obj, const char *key, bt_bool val)
dac5c838
PP
998{
999 enum bt_value_status ret;
05e21286 1000 struct bt_value *bool_obj = NULL;
dac5c838 1001
05e21286
PP
1002 bool_obj = bt_value_bool_create_init(val);
1003 ret = bt_value_map_insert_entry(map_obj, key,
da91b29a 1004 (void *) bool_obj);
65300d60 1005 bt_object_put_ref(bool_obj);
dac5c838
PP
1006 return ret;
1007}
1008
05e21286
PP
1009enum bt_value_status bt_value_map_insert_integer_entry(
1010 struct bt_value *map_obj, const char *key, int64_t val)
dac5c838
PP
1011{
1012 enum bt_value_status ret;
05e21286 1013 struct bt_value *integer_obj = NULL;
dac5c838 1014
05e21286
PP
1015 integer_obj = bt_value_integer_create_init(val);
1016 ret = bt_value_map_insert_entry(map_obj, key,
da91b29a 1017 (void *) integer_obj);
65300d60 1018 bt_object_put_ref(integer_obj);
dac5c838
PP
1019 return ret;
1020}
1021
05e21286
PP
1022enum bt_value_status bt_value_map_insert_real_entry(
1023 struct bt_value *map_obj, const char *key, double val)
dac5c838
PP
1024{
1025 enum bt_value_status ret;
05e21286 1026 struct bt_value *real_obj = NULL;
dac5c838 1027
05e21286
PP
1028 real_obj = bt_value_real_create_init(val);
1029 ret = bt_value_map_insert_entry(map_obj, key,
da91b29a 1030 (void *) real_obj);
65300d60 1031 bt_object_put_ref(real_obj);
dac5c838
PP
1032 return ret;
1033}
1034
05e21286
PP
1035enum bt_value_status bt_value_map_insert_string_entry(
1036 struct bt_value *map_obj, const char *key,
601b0d3c 1037 const char *val)
dac5c838
PP
1038{
1039 enum bt_value_status ret;
05e21286 1040 struct bt_value *string_obj = NULL;
dac5c838 1041
05e21286
PP
1042 string_obj = bt_value_string_create_init(val);
1043 ret = bt_value_map_insert_entry(map_obj, key,
da91b29a 1044 (void *) string_obj);
65300d60 1045 bt_object_put_ref(string_obj);
dac5c838
PP
1046 return ret;
1047}
1048
05e21286
PP
1049enum bt_value_status bt_value_map_insert_empty_array_entry(
1050 struct bt_value *map_obj, const char *key)
dac5c838
PP
1051{
1052 enum bt_value_status ret;
05e21286 1053 struct bt_value *array_obj = NULL;
dac5c838 1054
05e21286
PP
1055 array_obj = bt_value_array_create();
1056 ret = bt_value_map_insert_entry(map_obj, key,
da91b29a 1057 (void *) array_obj);
65300d60 1058 bt_object_put_ref(array_obj);
dac5c838
PP
1059 return ret;
1060}
1061
05e21286
PP
1062enum bt_value_status bt_value_map_insert_empty_map_entry(
1063 struct bt_value *map_obj, const char *key)
dac5c838
PP
1064{
1065 enum bt_value_status ret;
05e21286 1066 struct bt_value *empty_map_obj = NULL;
dac5c838 1067
05e21286
PP
1068 empty_map_obj = bt_value_map_create();
1069 ret = bt_value_map_insert_entry(map_obj, key,
da91b29a 1070 (void *) empty_map_obj);
65300d60 1071 bt_object_put_ref(empty_map_obj);
dac5c838
PP
1072 return ret;
1073}
1074
05e21286 1075enum bt_value_status bt_value_map_foreach_entry(struct bt_value *map_obj,
40f4ba76 1076 bt_value_map_foreach_entry_func func, void *data)
dac5c838
PP
1077{
1078 enum bt_value_status ret = BT_VALUE_STATUS_OK;
1079 gpointer key, element_obj;
1080 GHashTableIter iter;
1081 struct bt_value_map *typed_map_obj = BT_VALUE_TO_MAP(map_obj);
1082
f6ccaed9 1083 BT_ASSERT_PRE_NON_NULL(map_obj, "Value object");
40f4ba76 1084 BT_ASSERT_PRE_NON_NULL(func, "Callback");
f6ccaed9 1085 BT_ASSERT_PRE_VALUE_IS_TYPE(map_obj, BT_VALUE_TYPE_MAP);
dac5c838
PP
1086 g_hash_table_iter_init(&iter, typed_map_obj->ght);
1087
1088 while (g_hash_table_iter_next(&iter, &key, &element_obj)) {
5b44aff2 1089 const char *key_str = g_quark_to_string(GPOINTER_TO_UINT(key));
dac5c838 1090
40f4ba76 1091 if (!func(key_str, element_obj, data)) {
f6ccaed9 1092 BT_LOGV("User canceled the loop: key=\"%s\", "
2f42aa0a
PP
1093 "value-addr=%p, data=%p",
1094 key_str, element_obj, data);
f6ccaed9 1095 ret = BT_VALUE_STATUS_CANCELED;
dac5c838
PP
1096 break;
1097 }
1098 }
1099
dac5c838
PP
1100 return ret;
1101}
1102
05e21286
PP
1103enum bt_value_status bt_value_map_foreach_entry_const(
1104 const struct bt_value *map_obj,
40f4ba76 1105 bt_value_map_foreach_entry_const_func func, void *data)
da91b29a
PP
1106{
1107 return bt_value_map_foreach_entry((void *) map_obj,
40f4ba76 1108 (bt_value_map_foreach_entry_func) func, data);
da91b29a
PP
1109}
1110
770750d3 1111struct extend_map_element_data {
05e21286 1112 struct bt_value *extended_obj;
601b0d3c 1113 enum bt_value_status status;
770750d3
PP
1114};
1115
1116static
c55a9f58 1117bt_bool extend_map_element(const char *key,
05e21286 1118 const struct bt_value *extension_obj_elem, void *data)
770750d3 1119{
c55a9f58 1120 bt_bool ret = BT_TRUE;
770750d3 1121 struct extend_map_element_data *extend_data = data;
05e21286 1122 struct bt_value *extension_obj_elem_copy = NULL;
770750d3
PP
1123
1124 /* Copy object which is to replace the current one */
6be5a99e
PP
1125 extend_data->status = bt_value_copy(extension_obj_elem,
1126 &extension_obj_elem_copy);
601b0d3c
PP
1127 if (extend_data->status) {
1128 BT_LOGE("Cannot copy map element: addr=%p",
1129 extension_obj_elem);
1130 goto error;
1131 }
1132
1133 BT_ASSERT(extension_obj_elem_copy);
770750d3
PP
1134
1135 /* Replace in extended object */
05e21286 1136 extend_data->status = bt_value_map_insert_entry(
601b0d3c
PP
1137 extend_data->extended_obj, key,
1138 (void *) extension_obj_elem_copy);
1139 if (extend_data->status) {
2f42aa0a
PP
1140 BT_LOGE("Cannot replace value in extended value: key=\"%s\", "
1141 "extended-value-addr=%p, element-value-addr=%p",
1142 key, extend_data->extended_obj,
1143 extension_obj_elem_copy);
770750d3
PP
1144 goto error;
1145 }
1146
1147 goto end;
1148
1149error:
601b0d3c 1150 BT_ASSERT(extend_data->status != BT_VALUE_STATUS_OK);
c55a9f58 1151 ret = BT_FALSE;
770750d3
PP
1152
1153end:
65300d60 1154 BT_OBJECT_PUT_REF_AND_RESET(extension_obj_elem_copy);
770750d3
PP
1155 return ret;
1156}
1157
601b0d3c 1158enum bt_value_status bt_value_map_extend(
70991d9f 1159 const struct bt_value *base_map_obj,
35294e83
PP
1160 const struct bt_value *extension_obj,
1161 struct bt_value **extended_map_obj)
770750d3 1162{
601b0d3c
PP
1163 struct extend_map_element_data extend_data = {
1164 .extended_obj = NULL,
1165 .status = BT_VALUE_STATUS_OK,
1166 };
770750d3 1167
f6ccaed9
PP
1168 BT_ASSERT_PRE_NON_NULL(base_map_obj, "Base value object");
1169 BT_ASSERT_PRE_NON_NULL(extension_obj, "Extension value object");
601b0d3c
PP
1170 BT_ASSERT_PRE_NON_NULL(extended_map_obj,
1171 "Extended value object (output)");
f6ccaed9
PP
1172 BT_ASSERT_PRE_VALUE_IS_TYPE(base_map_obj, BT_VALUE_TYPE_MAP);
1173 BT_ASSERT_PRE_VALUE_IS_TYPE(extension_obj, BT_VALUE_TYPE_MAP);
2f42aa0a
PP
1174 BT_LOGD("Extending map value: base-value-addr=%p, extension-value-addr=%p",
1175 base_map_obj, extension_obj);
601b0d3c 1176 *extended_map_obj = NULL;
2f42aa0a 1177
770750d3 1178 /* Create copy of base map object to start with */
6be5a99e 1179 extend_data.status = bt_value_copy(base_map_obj, extended_map_obj);
601b0d3c 1180 if (extend_data.status) {
2f42aa0a
PP
1181 BT_LOGE("Cannot copy base value: base-value-addr=%p",
1182 base_map_obj);
770750d3
PP
1183 goto error;
1184 }
1185
601b0d3c
PP
1186 BT_ASSERT(extended_map_obj);
1187
770750d3
PP
1188 /*
1189 * For each key in the extension map object, replace this key
1190 * in the copied map object.
1191 */
601b0d3c 1192 extend_data.extended_obj = *extended_map_obj;
770750d3 1193
05e21286 1194 if (bt_value_map_foreach_entry_const(extension_obj, extend_map_element,
770750d3 1195 &extend_data)) {
32e87ceb 1196 BT_LOGE("Cannot iterate on the extension object's elements: "
2f42aa0a 1197 "extension-value-addr=%p", extension_obj);
770750d3
PP
1198 goto error;
1199 }
1200
601b0d3c 1201 if (extend_data.status) {
32e87ceb 1202 BT_LOGE("Failed to successfully iterate on the extension object's elements: "
2f42aa0a 1203 "extension-value-addr=%p", extension_obj);
770750d3
PP
1204 goto error;
1205 }
1206
2f42aa0a 1207 BT_LOGD("Extended map value: extended-value-addr=%p",
601b0d3c 1208 *extended_map_obj);
770750d3
PP
1209 goto end;
1210
1211error:
601b0d3c
PP
1212 BT_OBJECT_PUT_REF_AND_RESET(*extended_map_obj);
1213 *extended_map_obj = NULL;
770750d3
PP
1214
1215end:
601b0d3c 1216 return extend_data.status;
770750d3
PP
1217}
1218
6be5a99e
PP
1219enum bt_value_status bt_value_copy(const struct bt_value *object,
1220 struct bt_value **copy_obj)
dac5c838 1221{
601b0d3c 1222 enum bt_value_status status = BT_VALUE_STATUS_OK;
dac5c838 1223
f6ccaed9 1224 BT_ASSERT_PRE_NON_NULL(object, "Value object");
601b0d3c 1225 BT_ASSERT_PRE_NON_NULL(copy_obj, "Value object copy (output)");
2f42aa0a 1226 BT_LOGD("Copying value object: addr=%p", object);
601b0d3c
PP
1227 *copy_obj = copy_funcs[object->type](object);
1228 if (*copy_obj) {
2f42aa0a
PP
1229 BT_LOGD("Copied value object: copy-value-addr=%p",
1230 copy_obj);
1231 } else {
601b0d3c
PP
1232 status = BT_VALUE_STATUS_NOMEM;
1233 *copy_obj = NULL;
2f42aa0a
PP
1234 BT_LOGE_STR("Failed to copy value object.");
1235 }
dac5c838 1236
601b0d3c 1237 return status;
dac5c838
PP
1238}
1239
c55a9f58 1240bt_bool bt_value_compare(const struct bt_value *object_a,
dac5c838
PP
1241 const struct bt_value *object_b)
1242{
c55a9f58 1243 bt_bool ret = BT_FALSE;
dac5c838 1244
f6ccaed9
PP
1245 BT_ASSERT_PRE_NON_NULL(object_a, "Value object A");
1246 BT_ASSERT_PRE_NON_NULL(object_b, "Value object B");
dac5c838
PP
1247
1248 if (object_a->type != object_b->type) {
2f42aa0a
PP
1249 BT_LOGV("Values are different: type mismatch: "
1250 "value-a-addr=%p, value-b-addr=%p, "
c4628760 1251 "value-a-type=%s, value-b-type=%s",
2f42aa0a 1252 object_a, object_b,
da91b29a
PP
1253 bt_common_value_type_string(object_a->type),
1254 bt_common_value_type_string(object_b->type));
dac5c838
PP
1255 goto end;
1256 }
1257
1258 ret = compare_funcs[object_a->type](object_a, object_b);
1259
1260end:
1261 return ret;
1262}
c5b9b441
PP
1263
1264void bt_value_get_ref(const struct bt_value *value)
1265{
1266 bt_object_get_ref(value);
1267}
1268
1269void bt_value_put_ref(const struct bt_value *value)
1270{
1271 bt_object_put_ref(value);
1272}
This page took 0.112108 seconds and 4 git commands to generate.