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