cpp-common/bt2c/fmt.hpp: use `wise_enum::string_type` in `EnableIfIsWiseEnum` definition
[babeltrace.git] / src / ctf-writer / values.c
1 /*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation
5 * Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com>
6 */
7
8 #define BT_LOG_TAG "CTF-WRITER/VALUES"
9 #include "logging.h"
10
11 #include <stdlib.h>
12 #include <string.h>
13 #include <inttypes.h>
14
15 #include <babeltrace2-ctf-writer/object.h>
16
17 #include "common/assert.h"
18 #include "common/common.h"
19 #include "compat/compiler.h"
20 #include "compat/glib.h"
21
22 #include "assert-pre.h"
23 #include "object.h"
24 #include "values.h"
25
26 #define BT_CTF_VALUE_FROM_CONCRETE(_concrete) ((struct bt_ctf_value *) (_concrete))
27 #define BT_CTF_VALUE_TO_BOOL(_base) ((struct bt_ctf_value_bool *) (_base))
28 #define BT_CTF_VALUE_TO_INTEGER(_base) ((struct bt_ctf_value_integer *) (_base))
29 #define BT_CTF_VALUE_TO_REAL(_base) ((struct bt_ctf_value_real *) (_base))
30 #define BT_CTF_VALUE_TO_STRING(_base) ((struct bt_ctf_value_string *) (_base))
31 #define BT_CTF_VALUE_TO_ARRAY(_base) ((struct bt_ctf_value_array *) (_base))
32 #define BT_CTF_VALUE_TO_MAP(_base) ((struct bt_ctf_value_map *) (_base))
33
34 #define BT_CTF_ASSERT_PRE_VALUE_IS_TYPE(_value, _type) \
35 BT_CTF_ASSERT_PRE(((struct bt_ctf_value *) (_value))->type == (_type), \
36 "Value has the wrong type ID: expected-type=%d", (_type))
37
38 #define BT_CTF_ASSERT_PRE_VALUE_HOT(_value, _name) \
39 BT_CTF_ASSERT_PRE_HOT(((struct bt_ctf_value *) (_value)), (_name), "")
40
41 #define BT_CTF_ASSERT_PRE_VALUE_INDEX_IN_BOUNDS(_index, _count) \
42 BT_CTF_ASSERT_PRE((_index) < (_count), \
43 "Index is out of bound: " \
44 "index=%" PRIu64 ", count=%u", (_index), (_count));
45
46 struct bt_ctf_value {
47 struct bt_ctf_object base;
48 enum bt_ctf_value_type type;
49 bt_ctf_bool frozen;
50 };
51
52 static
53 void bt_ctf_value_null_instance_release_func(struct bt_ctf_object *obj)
54 {
55 BT_LOGW("Releasing the null value singleton: addr=%p", obj);
56 }
57
58 static
59 struct bt_ctf_value bt_ctf_value_null_instance = {
60 .base = {
61 .is_shared = true,
62 .ref_count = 1,
63 .release_func = bt_ctf_value_null_instance_release_func,
64 .spec_release_func = NULL,
65 .parent_is_owner_listener_func = NULL,
66 .parent = NULL,
67 },
68 .type = BT_CTF_VALUE_TYPE_NULL,
69 .frozen = BT_CTF_TRUE,
70 };
71
72 BT_EXPORT
73 struct bt_ctf_value *const bt_ctf_value_null = &bt_ctf_value_null_instance;
74
75 BT_EXPORT
76 struct bt_ctf_private_value *const bt_ctf_private_value_null =
77 (void *) &bt_ctf_value_null_instance;
78
79 struct bt_ctf_value_bool {
80 struct bt_ctf_value base;
81 bt_ctf_bool value;
82 };
83
84 struct bt_ctf_value_integer {
85 struct bt_ctf_value base;
86 int64_t value;
87 };
88
89 struct bt_ctf_value_real {
90 struct bt_ctf_value base;
91 double value;
92 };
93
94 struct bt_ctf_value_string {
95 struct bt_ctf_value base;
96 GString *gstr;
97 };
98
99 struct bt_ctf_value_array {
100 struct bt_ctf_value base;
101 GPtrArray *garray;
102 };
103
104 struct bt_ctf_value_map {
105 struct bt_ctf_value base;
106 GHashTable *ght;
107 };
108
109 static
110 void bt_ctf_value_destroy(struct bt_ctf_object *obj);
111
112 static
113 void bt_ctf_value_string_destroy(struct bt_ctf_value *object)
114 {
115 g_string_free(BT_CTF_VALUE_TO_STRING(object)->gstr, TRUE);
116 BT_CTF_VALUE_TO_STRING(object)->gstr = NULL;
117 }
118
119 static
120 void bt_ctf_value_array_destroy(struct bt_ctf_value *object)
121 {
122 /*
123 * Pointer array's registered value destructor will take care
124 * of putting each contained object.
125 */
126 g_ptr_array_free(BT_CTF_VALUE_TO_ARRAY(object)->garray, TRUE);
127 BT_CTF_VALUE_TO_ARRAY(object)->garray = NULL;
128 }
129
130 static
131 void bt_ctf_value_map_destroy(struct bt_ctf_value *object)
132 {
133 /*
134 * Hash table's registered value destructor will take care of
135 * putting each contained object. Keys are GQuarks and cannot
136 * be destroyed anyway.
137 */
138 g_hash_table_destroy(BT_CTF_VALUE_TO_MAP(object)->ght);
139 BT_CTF_VALUE_TO_MAP(object)->ght = NULL;
140 }
141
142 static
143 void (* const destroy_funcs[])(struct bt_ctf_value *) = {
144 [BT_CTF_VALUE_TYPE_NULL] = NULL,
145 [BT_CTF_VALUE_TYPE_BOOL] = NULL,
146 [BT_CTF_VALUE_TYPE_INTEGER] = NULL,
147 [BT_CTF_VALUE_TYPE_REAL] = NULL,
148 [BT_CTF_VALUE_TYPE_STRING] = bt_ctf_value_string_destroy,
149 [BT_CTF_VALUE_TYPE_ARRAY] = bt_ctf_value_array_destroy,
150 [BT_CTF_VALUE_TYPE_MAP] = bt_ctf_value_map_destroy,
151 };
152
153 static
154 struct bt_ctf_private_value *bt_ctf_value_null_copy(
155 const struct bt_ctf_value *null_obj __attribute__((unused)))
156 {
157 return (void *) bt_ctf_value_null;
158 }
159
160 static
161 struct bt_ctf_private_value *bt_ctf_value_bool_copy(const struct bt_ctf_value *bool_obj)
162 {
163 return bt_ctf_private_value_bool_create_init(
164 BT_CTF_VALUE_TO_BOOL(bool_obj)->value);
165 }
166
167 static
168 struct bt_ctf_private_value *bt_ctf_value_integer_copy(
169 const struct bt_ctf_value *integer_obj)
170 {
171 return bt_ctf_private_value_integer_create_init(
172 BT_CTF_VALUE_TO_INTEGER(integer_obj)->value);
173 }
174
175 static
176 struct bt_ctf_private_value *bt_ctf_value_real_copy(const struct bt_ctf_value *real_obj)
177 {
178 return bt_ctf_private_value_real_create_init(
179 BT_CTF_VALUE_TO_REAL(real_obj)->value);
180 }
181
182 static
183 struct bt_ctf_private_value *bt_ctf_value_string_copy(const struct bt_ctf_value *string_obj)
184 {
185 return bt_ctf_private_value_string_create_init(
186 BT_CTF_VALUE_TO_STRING(string_obj)->gstr->str);
187 }
188
189 static
190 struct bt_ctf_private_value *bt_ctf_value_array_copy(const struct bt_ctf_value *array_obj)
191 {
192 int i;
193 int ret;
194 struct bt_ctf_private_value *copy_obj;
195 struct bt_ctf_value_array *typed_array_obj;
196
197 BT_LOGD("Copying array value: addr=%p", array_obj);
198 typed_array_obj = BT_CTF_VALUE_TO_ARRAY(array_obj);
199 copy_obj = bt_ctf_private_value_array_create();
200 if (!copy_obj) {
201 BT_LOGE_STR("Cannot create empty array value.");
202 goto end;
203 }
204
205 for (i = 0; i < typed_array_obj->garray->len; ++i) {
206 struct bt_ctf_private_value *element_obj_copy = NULL;
207 struct bt_ctf_value *element_obj =
208 bt_ctf_value_array_borrow_element_by_index(
209 array_obj, i);
210
211 BT_ASSERT_DBG(element_obj);
212 BT_LOGD("Copying array value's element: element-addr=%p, "
213 "index=%d", element_obj, i);
214 ret = bt_ctf_value_copy(&element_obj_copy, element_obj);
215 if (ret) {
216 BT_LOGE("Cannot copy array value's element: "
217 "array-addr=%p, index=%d",
218 array_obj, i);
219 BT_CTF_OBJECT_PUT_REF_AND_RESET(copy_obj);
220 goto end;
221 }
222
223 BT_ASSERT_DBG(element_obj_copy);
224 ret = bt_ctf_private_value_array_append_element(copy_obj,
225 (void *) element_obj_copy);
226 BT_CTF_OBJECT_PUT_REF_AND_RESET(element_obj_copy);
227 if (ret) {
228 BT_LOGE("Cannot append to array value: addr=%p",
229 array_obj);
230 BT_CTF_OBJECT_PUT_REF_AND_RESET(copy_obj);
231 goto end;
232 }
233 }
234
235 BT_LOGD("Copied array value: original-addr=%p, copy-addr=%p",
236 array_obj, copy_obj);
237
238 end:
239 return copy_obj;
240 }
241
242 static
243 struct bt_ctf_private_value *bt_ctf_value_map_copy(const struct bt_ctf_value *map_obj)
244 {
245 int ret;
246 GHashTableIter iter;
247 gpointer key, element_obj;
248 struct bt_ctf_private_value *copy_obj;
249 struct bt_ctf_private_value *element_obj_copy = NULL;
250 struct bt_ctf_value_map *typed_map_obj;
251
252 BT_LOGD("Copying map value: addr=%p", map_obj);
253 typed_map_obj = BT_CTF_VALUE_TO_MAP(map_obj);
254 copy_obj = bt_ctf_private_value_map_create();
255 if (!copy_obj) {
256 goto end;
257 }
258
259 g_hash_table_iter_init(&iter, typed_map_obj->ght);
260
261 while (g_hash_table_iter_next(&iter, &key, &element_obj)) {
262 const char *key_str = g_quark_to_string(GPOINTER_TO_UINT(key));
263
264 BT_ASSERT_DBG(key_str);
265 BT_LOGD("Copying map value's element: element-addr=%p, "
266 "key=\"%s\"", element_obj, key_str);
267 ret = bt_ctf_value_copy(&element_obj_copy, element_obj);
268 if (ret) {
269 BT_LOGE("Cannot copy map value's element: "
270 "map-addr=%p, key=\"%s\"",
271 map_obj, key_str);
272 BT_CTF_OBJECT_PUT_REF_AND_RESET(copy_obj);
273 goto end;
274 }
275
276 BT_ASSERT_DBG(element_obj_copy);
277 ret = bt_ctf_private_value_map_insert_entry(copy_obj, key_str,
278 (void *) element_obj_copy);
279 BT_CTF_OBJECT_PUT_REF_AND_RESET(element_obj_copy);
280 if (ret) {
281 BT_LOGE("Cannot insert into map value: addr=%p, key=\"%s\"",
282 map_obj, key_str);
283 BT_CTF_OBJECT_PUT_REF_AND_RESET(copy_obj);
284 goto end;
285 }
286 }
287
288 BT_LOGD("Copied map value: addr=%p", map_obj);
289
290 end:
291 return copy_obj;
292 }
293
294 static
295 struct bt_ctf_private_value *(* const copy_funcs[])(const struct bt_ctf_value *) = {
296 [BT_CTF_VALUE_TYPE_NULL] = bt_ctf_value_null_copy,
297 [BT_CTF_VALUE_TYPE_BOOL] = bt_ctf_value_bool_copy,
298 [BT_CTF_VALUE_TYPE_INTEGER] = bt_ctf_value_integer_copy,
299 [BT_CTF_VALUE_TYPE_REAL] = bt_ctf_value_real_copy,
300 [BT_CTF_VALUE_TYPE_STRING] = bt_ctf_value_string_copy,
301 [BT_CTF_VALUE_TYPE_ARRAY] = bt_ctf_value_array_copy,
302 [BT_CTF_VALUE_TYPE_MAP] = bt_ctf_value_map_copy,
303 };
304
305 static
306 bt_ctf_bool bt_ctf_value_null_compare(
307 const struct bt_ctf_value *object_a __attribute__((unused)),
308 const struct bt_ctf_value *object_b __attribute__((unused)))
309 {
310 /*
311 * Always BT_CTF_TRUE since bt_ctf_value_compare() already checks if both
312 * object_a and object_b have the same type, and in the case of
313 * null value objects, they're always the same if it is so.
314 */
315 return BT_CTF_TRUE;
316 }
317
318 static
319 bt_ctf_bool bt_ctf_value_bool_compare(const struct bt_ctf_value *object_a,
320 const struct bt_ctf_value *object_b)
321 {
322 if (BT_CTF_VALUE_TO_BOOL(object_a)->value !=
323 BT_CTF_VALUE_TO_BOOL(object_b)->value) {
324 BT_LOGT("Boolean value objects are different: "
325 "bool-a-val=%d, bool-b-val=%d",
326 BT_CTF_VALUE_TO_BOOL(object_a)->value,
327 BT_CTF_VALUE_TO_BOOL(object_b)->value);
328 return BT_CTF_FALSE;
329 }
330
331 return BT_CTF_TRUE;
332 }
333
334 static
335 bt_ctf_bool bt_ctf_value_integer_compare(const struct bt_ctf_value *object_a,
336 const struct bt_ctf_value *object_b)
337 {
338 if (BT_CTF_VALUE_TO_INTEGER(object_a)->value !=
339 BT_CTF_VALUE_TO_INTEGER(object_b)->value) {
340 BT_LOGT("Integer value objects are different: "
341 "int-a-val=%" PRId64 ", int-b-val=%" PRId64,
342 BT_CTF_VALUE_TO_INTEGER(object_a)->value,
343 BT_CTF_VALUE_TO_INTEGER(object_b)->value);
344 return BT_CTF_FALSE;
345 }
346
347 return BT_CTF_TRUE;
348 }
349
350 static
351 bt_ctf_bool bt_ctf_value_real_compare(const struct bt_ctf_value *object_a,
352 const struct bt_ctf_value *object_b)
353 {
354 if (BT_CTF_VALUE_TO_REAL(object_a)->value !=
355 BT_CTF_VALUE_TO_REAL(object_b)->value) {
356 BT_LOGT("Real number value objects are different: "
357 "real-a-val=%f, real-b-val=%f",
358 BT_CTF_VALUE_TO_REAL(object_a)->value,
359 BT_CTF_VALUE_TO_REAL(object_b)->value);
360 return BT_CTF_FALSE;
361 }
362
363 return BT_CTF_TRUE;
364 }
365
366 static
367 bt_ctf_bool bt_ctf_value_string_compare(const struct bt_ctf_value *object_a,
368 const struct bt_ctf_value *object_b)
369 {
370 if (strcmp(BT_CTF_VALUE_TO_STRING(object_a)->gstr->str,
371 BT_CTF_VALUE_TO_STRING(object_b)->gstr->str) != 0) {
372 BT_LOGT("String value objects are different: "
373 "string-a-val=\"%s\", string-b-val=\"%s\"",
374 BT_CTF_VALUE_TO_STRING(object_a)->gstr->str,
375 BT_CTF_VALUE_TO_STRING(object_b)->gstr->str);
376 return BT_CTF_FALSE;
377 }
378
379 return BT_CTF_TRUE;
380 }
381
382 static
383 bt_ctf_bool bt_ctf_value_array_compare(const struct bt_ctf_value *object_a,
384 const struct bt_ctf_value *object_b)
385 {
386 int i;
387 bt_ctf_bool ret = BT_CTF_TRUE;
388 const struct bt_ctf_value_array *array_obj_a =
389 BT_CTF_VALUE_TO_ARRAY(object_a);
390
391 if (bt_ctf_value_array_get_length(object_a) !=
392 bt_ctf_value_array_get_length(object_b)) {
393 BT_LOGT("Array values are different: size mismatch "
394 "value-a-addr=%p, value-b-addr=%p, "
395 "value-a-size=%" PRId64 ", value-b-size=%" PRId64,
396 object_a, object_b,
397 bt_ctf_value_array_get_length(object_a),
398 bt_ctf_value_array_get_length(object_b));
399 ret = BT_CTF_FALSE;
400 goto end;
401 }
402
403 for (i = 0; i < array_obj_a->garray->len; ++i) {
404 struct bt_ctf_value *element_obj_a;
405 struct bt_ctf_value *element_obj_b;
406
407 element_obj_a = bt_ctf_value_array_borrow_element_by_index(
408 object_a, i);
409 element_obj_b = bt_ctf_value_array_borrow_element_by_index(
410 object_b, i);
411
412 if (!bt_ctf_value_compare(element_obj_a, element_obj_b)) {
413 BT_LOGT("Array values's elements are different: "
414 "value-a-addr=%p, value-b-addr=%p, index=%d",
415 element_obj_a, element_obj_b, i);
416 ret = BT_CTF_FALSE;
417 goto end;
418 }
419 }
420
421 end:
422 return ret;
423 }
424
425 static
426 bt_ctf_bool bt_ctf_value_map_compare(const struct bt_ctf_value *object_a,
427 const struct bt_ctf_value *object_b)
428 {
429 bt_ctf_bool ret = BT_CTF_TRUE;
430 GHashTableIter iter;
431 gpointer key, element_obj_a;
432 const struct bt_ctf_value_map *map_obj_a = BT_CTF_VALUE_TO_MAP(object_a);
433
434 if (bt_ctf_value_map_get_size(object_a) !=
435 bt_ctf_value_map_get_size(object_b)) {
436 BT_LOGT("Map values are different: size mismatch "
437 "value-a-addr=%p, value-b-addr=%p, "
438 "value-a-size=%" PRId64 ", value-b-size=%" PRId64,
439 object_a, object_b,
440 bt_ctf_value_map_get_size(object_a),
441 bt_ctf_value_map_get_size(object_b));
442 ret = BT_CTF_FALSE;
443 goto end;
444 }
445
446 g_hash_table_iter_init(&iter, map_obj_a->ght);
447
448 while (g_hash_table_iter_next(&iter, &key, &element_obj_a)) {
449 struct bt_ctf_value *element_obj_b;
450 const char *key_str = g_quark_to_string(GPOINTER_TO_UINT(key));
451
452 element_obj_b = bt_ctf_value_map_borrow_entry_value(object_b,
453 key_str);
454
455 if (!bt_ctf_value_compare(element_obj_a, element_obj_b)) {
456 BT_LOGT("Map values's elements are different: "
457 "value-a-addr=%p, value-b-addr=%p, key=\"%s\"",
458 element_obj_a, element_obj_b, key_str);
459 ret = BT_CTF_FALSE;
460 goto end;
461 }
462 }
463
464 end:
465 return ret;
466 }
467
468 static
469 bt_ctf_bool (* const compare_funcs[])(const struct bt_ctf_value *,
470 const struct bt_ctf_value *) = {
471 [BT_CTF_VALUE_TYPE_NULL] = bt_ctf_value_null_compare,
472 [BT_CTF_VALUE_TYPE_BOOL] = bt_ctf_value_bool_compare,
473 [BT_CTF_VALUE_TYPE_INTEGER] = bt_ctf_value_integer_compare,
474 [BT_CTF_VALUE_TYPE_REAL] = bt_ctf_value_real_compare,
475 [BT_CTF_VALUE_TYPE_STRING] = bt_ctf_value_string_compare,
476 [BT_CTF_VALUE_TYPE_ARRAY] = bt_ctf_value_array_compare,
477 [BT_CTF_VALUE_TYPE_MAP] = bt_ctf_value_map_compare,
478 };
479
480 static
481 void bt_ctf_value_null_freeze(struct bt_ctf_value *object __attribute__((unused)))
482 {
483 }
484
485 static
486 void bt_ctf_value_generic_freeze(struct bt_ctf_value *object)
487 {
488 object->frozen = BT_CTF_TRUE;
489 }
490
491 static
492 void bt_ctf_value_array_freeze(struct bt_ctf_value *object)
493 {
494 int i;
495 struct bt_ctf_value_array *typed_array_obj =
496 BT_CTF_VALUE_TO_ARRAY(object);
497
498 for (i = 0; i < typed_array_obj->garray->len; ++i) {
499 bt_ctf_value_freeze(g_ptr_array_index(typed_array_obj->garray, i));
500 }
501
502 bt_ctf_value_generic_freeze(object);
503 }
504
505 static
506 void bt_ctf_value_map_freeze(struct bt_ctf_value *object)
507 {
508 GHashTableIter iter;
509 gpointer key, element_obj;
510 const struct bt_ctf_value_map *map_obj = BT_CTF_VALUE_TO_MAP(object);
511
512 g_hash_table_iter_init(&iter, map_obj->ght);
513
514 while (g_hash_table_iter_next(&iter, &key, &element_obj)) {
515 bt_ctf_value_freeze(element_obj);
516 }
517
518 bt_ctf_value_generic_freeze(object);
519 }
520
521 static
522 void (* const freeze_funcs[])(struct bt_ctf_value *) = {
523 [BT_CTF_VALUE_TYPE_NULL] = bt_ctf_value_null_freeze,
524 [BT_CTF_VALUE_TYPE_BOOL] = bt_ctf_value_generic_freeze,
525 [BT_CTF_VALUE_TYPE_INTEGER] = bt_ctf_value_generic_freeze,
526 [BT_CTF_VALUE_TYPE_REAL] = bt_ctf_value_generic_freeze,
527 [BT_CTF_VALUE_TYPE_STRING] = bt_ctf_value_generic_freeze,
528 [BT_CTF_VALUE_TYPE_ARRAY] = bt_ctf_value_array_freeze,
529 [BT_CTF_VALUE_TYPE_MAP] = bt_ctf_value_map_freeze,
530 };
531
532 static
533 void bt_ctf_value_destroy(struct bt_ctf_object *obj)
534 {
535 struct bt_ctf_value *value;
536
537 value = container_of(obj, struct bt_ctf_value, base);
538 BT_LOGD("Destroying value: addr=%p", value);
539
540 if (bt_ctf_value_is_null(value)) {
541 BT_LOGD_STR("Not destroying the null value singleton.");
542 return;
543 }
544
545 if (destroy_funcs[value->type]) {
546 destroy_funcs[value->type](value);
547 }
548
549 g_free(value);
550 }
551
552 enum bt_ctf_value_status _bt_ctf_value_freeze(struct bt_ctf_value *object)
553 {
554 enum bt_ctf_value_status ret = BT_CTF_VALUE_STATUS_OK;
555
556 BT_ASSERT_DBG(object);
557
558 if (object->frozen) {
559 goto end;
560 }
561
562 BT_LOGD("Freezing value: addr=%p", object);
563 freeze_funcs[object->type](object);
564
565 end:
566 return ret;
567 }
568
569 enum bt_ctf_value_type bt_ctf_value_get_type(const struct bt_ctf_value *object)
570 {
571 BT_CTF_ASSERT_PRE_NON_NULL(object, "Value object");
572 return object->type;
573 }
574
575 static
576 struct bt_ctf_value bt_ctf_value_create_base(enum bt_ctf_value_type type)
577 {
578 struct bt_ctf_value value;
579
580 value.type = type;
581 value.frozen = BT_CTF_FALSE;
582 bt_ctf_object_init_shared(&value.base, bt_ctf_value_destroy);
583 return value;
584 }
585
586 struct bt_ctf_private_value *bt_ctf_private_value_bool_create_init(bt_ctf_bool val)
587 {
588 struct bt_ctf_value_bool *bool_obj;
589
590 BT_LOGD("Creating boolean value object: val=%d", val);
591 bool_obj = g_new0(struct bt_ctf_value_bool, 1);
592 if (!bool_obj) {
593 BT_LOGE_STR("Failed to allocate one boolean value object.");
594 goto end;
595 }
596
597 bool_obj->base = bt_ctf_value_create_base(BT_CTF_VALUE_TYPE_BOOL);
598 bool_obj->value = val;
599 BT_LOGD("Created boolean value object: addr=%p", bool_obj);
600
601 end:
602 return (void *) BT_CTF_VALUE_FROM_CONCRETE(bool_obj);
603 }
604
605 struct bt_ctf_private_value *bt_ctf_private_value_bool_create(void)
606 {
607 return bt_ctf_private_value_bool_create_init(BT_CTF_FALSE);
608 }
609
610 struct bt_ctf_private_value *bt_ctf_private_value_integer_create_init(int64_t val)
611 {
612 struct bt_ctf_value_integer *integer_obj;
613
614 BT_LOGD("Creating integer value object: val=%" PRId64, val);
615 integer_obj = g_new0(struct bt_ctf_value_integer, 1);
616 if (!integer_obj) {
617 BT_LOGE_STR("Failed to allocate one integer value object.");
618 goto end;
619 }
620
621 integer_obj->base = bt_ctf_value_create_base(BT_CTF_VALUE_TYPE_INTEGER);
622 integer_obj->value = val;
623 BT_LOGD("Created integer value object: addr=%p",
624 integer_obj);
625
626 end:
627 return (void *) BT_CTF_VALUE_FROM_CONCRETE(integer_obj);
628 }
629
630 struct bt_ctf_private_value *bt_ctf_private_value_integer_create(void)
631 {
632 return bt_ctf_private_value_integer_create_init(0);
633 }
634
635 struct bt_ctf_private_value *bt_ctf_private_value_real_create_init(double val)
636 {
637 struct bt_ctf_value_real *real_obj;
638
639 BT_LOGD("Creating real number value object: val=%f", val);
640 real_obj = g_new0(struct bt_ctf_value_real, 1);
641 if (!real_obj) {
642 BT_LOGE_STR("Failed to allocate one real number value object.");
643 goto end;
644 }
645
646 real_obj->base = bt_ctf_value_create_base(BT_CTF_VALUE_TYPE_REAL);
647 real_obj->value = val;
648 BT_LOGD("Created real number value object: addr=%p",
649 real_obj);
650
651 end:
652 return (void *) BT_CTF_VALUE_FROM_CONCRETE(real_obj);
653 }
654
655 struct bt_ctf_private_value *bt_ctf_private_value_real_create(void)
656 {
657 return bt_ctf_private_value_real_create_init(0.);
658 }
659
660 struct bt_ctf_private_value *bt_ctf_private_value_string_create_init(const char *val)
661 {
662 struct bt_ctf_value_string *string_obj = NULL;
663
664 if (!val) {
665 BT_LOGW_STR("Invalid parameter: value is NULL.");
666 goto end;
667 }
668
669 BT_LOGD("Creating string value object: val-len=%zu", strlen(val));
670 string_obj = g_new0(struct bt_ctf_value_string, 1);
671 if (!string_obj) {
672 BT_LOGE_STR("Failed to allocate one string object.");
673 goto end;
674 }
675
676 string_obj->base = bt_ctf_value_create_base(BT_CTF_VALUE_TYPE_STRING);
677 string_obj->gstr = g_string_new(val);
678 if (!string_obj->gstr) {
679 BT_LOGE_STR("Failed to allocate a GString.");
680 g_free(string_obj);
681 string_obj = NULL;
682 goto end;
683 }
684
685 BT_LOGD("Created string value object: addr=%p",
686 string_obj);
687
688 end:
689 return (void *) BT_CTF_VALUE_FROM_CONCRETE(string_obj);
690 }
691
692 struct bt_ctf_private_value *bt_ctf_private_value_string_create(void)
693 {
694 return bt_ctf_private_value_string_create_init("");
695 }
696
697 struct bt_ctf_private_value *bt_ctf_private_value_array_create(void)
698 {
699 struct bt_ctf_value_array *array_obj;
700
701 BT_LOGD_STR("Creating empty array value object.");
702 array_obj = g_new0(struct bt_ctf_value_array, 1);
703 if (!array_obj) {
704 BT_LOGE_STR("Failed to allocate one array object.");
705 goto end;
706 }
707
708 array_obj->base = bt_ctf_value_create_base(BT_CTF_VALUE_TYPE_ARRAY);
709 array_obj->garray = bt_g_ptr_array_new_full(0,
710 (GDestroyNotify) bt_ctf_object_put_ref);
711 if (!array_obj->garray) {
712 BT_LOGE_STR("Failed to allocate a GPtrArray.");
713 g_free(array_obj);
714 array_obj = NULL;
715 goto end;
716 }
717
718 BT_LOGD("Created array value object: addr=%p",
719 array_obj);
720
721 end:
722 return (void *) BT_CTF_VALUE_FROM_CONCRETE(array_obj);
723 }
724
725 struct bt_ctf_private_value *bt_ctf_private_value_map_create(void)
726 {
727 struct bt_ctf_value_map *map_obj;
728
729 BT_LOGD_STR("Creating empty map value object.");
730 map_obj = g_new0(struct bt_ctf_value_map, 1);
731 if (!map_obj) {
732 BT_LOGE_STR("Failed to allocate one map object.");
733 goto end;
734 }
735
736 map_obj->base = bt_ctf_value_create_base(BT_CTF_VALUE_TYPE_MAP);
737 map_obj->ght = g_hash_table_new_full(g_direct_hash, g_direct_equal,
738 NULL, (GDestroyNotify) bt_ctf_object_put_ref);
739 if (!map_obj->ght) {
740 BT_LOGE_STR("Failed to allocate a GHashTable.");
741 g_free(map_obj);
742 map_obj = NULL;
743 goto end;
744 }
745
746 BT_LOGD("Created map value object: addr=%p",
747 map_obj);
748
749 end:
750 return (void *) BT_CTF_VALUE_FROM_CONCRETE(map_obj);
751 }
752
753 bt_ctf_bool bt_ctf_value_bool_get(const struct bt_ctf_value *bool_obj)
754 {
755 BT_CTF_ASSERT_PRE_NON_NULL(bool_obj, "Value object");
756 BT_CTF_ASSERT_PRE_VALUE_IS_TYPE(bool_obj, BT_CTF_VALUE_TYPE_BOOL);
757 return BT_CTF_VALUE_TO_BOOL(bool_obj)->value;
758 }
759
760 void bt_ctf_private_value_bool_set(struct bt_ctf_private_value *bool_obj, bt_ctf_bool val)
761 {
762 BT_CTF_ASSERT_PRE_NON_NULL(bool_obj, "Value object");
763 BT_CTF_ASSERT_PRE_VALUE_IS_TYPE(bool_obj, BT_CTF_VALUE_TYPE_BOOL);
764 BT_CTF_ASSERT_PRE_VALUE_HOT(bool_obj, "Value object");
765 BT_CTF_VALUE_TO_BOOL(bool_obj)->value = val;
766 BT_LOGT("Set boolean value's raw value: value-addr=%p, value=%d",
767 bool_obj, val);
768 }
769
770 int64_t bt_ctf_value_integer_get(const struct bt_ctf_value *integer_obj)
771 {
772 BT_CTF_ASSERT_PRE_NON_NULL(integer_obj, "Value object");
773 BT_CTF_ASSERT_PRE_VALUE_IS_TYPE(integer_obj, BT_CTF_VALUE_TYPE_INTEGER);
774 return BT_CTF_VALUE_TO_INTEGER(integer_obj)->value;
775 }
776
777 void bt_ctf_private_value_integer_set(struct bt_ctf_private_value *integer_obj,
778 int64_t val)
779 {
780 BT_CTF_ASSERT_PRE_NON_NULL(integer_obj, "Value object");
781 BT_CTF_ASSERT_PRE_VALUE_IS_TYPE(integer_obj, BT_CTF_VALUE_TYPE_INTEGER);
782 BT_CTF_ASSERT_PRE_VALUE_HOT(integer_obj, "Value object");
783 BT_CTF_VALUE_TO_INTEGER(integer_obj)->value = val;
784 BT_LOGT("Set integer value's raw value: value-addr=%p, value=%" PRId64,
785 integer_obj, val);
786 }
787
788 double bt_ctf_value_real_get(const struct bt_ctf_value *real_obj)
789 {
790 BT_CTF_ASSERT_PRE_NON_NULL(real_obj, "Value object");
791 BT_CTF_ASSERT_PRE_VALUE_IS_TYPE(real_obj, BT_CTF_VALUE_TYPE_REAL);
792 return BT_CTF_VALUE_TO_REAL(real_obj)->value;
793 }
794
795 void bt_ctf_private_value_real_set(struct bt_ctf_private_value *real_obj, double val)
796 {
797 BT_CTF_ASSERT_PRE_NON_NULL(real_obj, "Value object");
798 BT_CTF_ASSERT_PRE_VALUE_IS_TYPE(real_obj, BT_CTF_VALUE_TYPE_REAL);
799 BT_CTF_ASSERT_PRE_VALUE_HOT(real_obj, "Value object");
800 BT_CTF_VALUE_TO_REAL(real_obj)->value = val;
801 BT_LOGT("Set real number value's raw value: value-addr=%p, value=%f",
802 real_obj, val);
803 }
804
805 const char *bt_ctf_value_string_get(const struct bt_ctf_value *string_obj)
806 {
807 BT_CTF_ASSERT_PRE_NON_NULL(string_obj, "Value object");
808 BT_CTF_ASSERT_PRE_VALUE_IS_TYPE(string_obj, BT_CTF_VALUE_TYPE_STRING);
809 return BT_CTF_VALUE_TO_STRING(string_obj)->gstr->str;
810 }
811
812 enum bt_ctf_value_status bt_ctf_private_value_string_set(
813 struct bt_ctf_private_value *string_obj, const char *val)
814 {
815 BT_CTF_ASSERT_PRE_NON_NULL(string_obj, "Value object");
816 BT_CTF_ASSERT_PRE_VALUE_IS_TYPE(string_obj, BT_CTF_VALUE_TYPE_STRING);
817 BT_CTF_ASSERT_PRE_VALUE_HOT(string_obj, "Value object");
818 g_string_assign(BT_CTF_VALUE_TO_STRING(string_obj)->gstr, val);
819 BT_LOGT("Set string value's raw value: value-addr=%p, raw-value-addr=%p",
820 string_obj, val);
821 return BT_CTF_VALUE_STATUS_OK;
822 }
823
824 uint64_t bt_ctf_value_array_get_length(const struct bt_ctf_value *array_obj)
825 {
826 BT_CTF_ASSERT_PRE_NON_NULL(array_obj, "Value object");
827 BT_CTF_ASSERT_PRE_VALUE_IS_TYPE(array_obj, BT_CTF_VALUE_TYPE_ARRAY);
828 return (uint64_t) BT_CTF_VALUE_TO_ARRAY(array_obj)->garray->len;
829 }
830
831 struct bt_ctf_value *bt_ctf_value_array_borrow_element_by_index(
832 const struct bt_ctf_value *array_obj,
833 uint64_t index)
834 {
835 struct bt_ctf_value_array *typed_array_obj =
836 BT_CTF_VALUE_TO_ARRAY(array_obj);
837
838 BT_CTF_ASSERT_PRE_NON_NULL(array_obj, "Value object");
839 BT_CTF_ASSERT_PRE_VALUE_IS_TYPE(array_obj, BT_CTF_VALUE_TYPE_ARRAY);
840 BT_CTF_ASSERT_PRE_VALUE_INDEX_IN_BOUNDS(index,
841 typed_array_obj->garray->len);
842 return g_ptr_array_index(typed_array_obj->garray, index);
843 }
844
845 struct bt_ctf_private_value *bt_ctf_private_value_array_borrow_element_by_index(
846 const struct bt_ctf_private_value *array_obj,
847 uint64_t index)
848 {
849 return (void *) bt_ctf_value_array_borrow_element_by_index(
850 (void *) array_obj, index);
851 }
852
853 enum bt_ctf_value_status bt_ctf_private_value_array_append_element(
854 struct bt_ctf_private_value *array_obj,
855 struct bt_ctf_value *element_obj)
856 {
857 struct bt_ctf_value_array *typed_array_obj =
858 BT_CTF_VALUE_TO_ARRAY(array_obj);
859
860 BT_CTF_ASSERT_PRE_NON_NULL(array_obj, "Array value object");
861 BT_CTF_ASSERT_PRE_NON_NULL(element_obj, "Element value object");
862 BT_CTF_ASSERT_PRE_VALUE_IS_TYPE(array_obj, BT_CTF_VALUE_TYPE_ARRAY);
863 BT_CTF_ASSERT_PRE_VALUE_HOT(array_obj, "Array value object");
864 g_ptr_array_add(typed_array_obj->garray, element_obj);
865 bt_ctf_object_get_ref(element_obj);
866 BT_LOGT("Appended element to array value: array-value-addr=%p, "
867 "element-value-addr=%p, new-size=%u",
868 array_obj, element_obj, typed_array_obj->garray->len);
869 return BT_CTF_VALUE_STATUS_OK;
870 }
871
872 enum bt_ctf_value_status bt_ctf_private_value_array_append_bool_element(
873 struct bt_ctf_private_value *array_obj, bt_ctf_bool val)
874 {
875 enum bt_ctf_value_status ret;
876 struct bt_ctf_private_value *bool_obj = NULL;
877
878 bool_obj = bt_ctf_private_value_bool_create_init(val);
879 ret = bt_ctf_private_value_array_append_element(array_obj,
880 (void *) bool_obj);
881 bt_ctf_object_put_ref(bool_obj);
882 return ret;
883 }
884
885 enum bt_ctf_value_status bt_ctf_private_value_array_append_integer_element(
886 struct bt_ctf_private_value *array_obj, int64_t val)
887 {
888 enum bt_ctf_value_status ret;
889 struct bt_ctf_private_value *integer_obj = NULL;
890
891 integer_obj = bt_ctf_private_value_integer_create_init(val);
892 ret = bt_ctf_private_value_array_append_element(array_obj,
893 (void *) integer_obj);
894 bt_ctf_object_put_ref(integer_obj);
895 return ret;
896 }
897
898 enum bt_ctf_value_status bt_ctf_private_value_array_append_real_element(
899 struct bt_ctf_private_value *array_obj, double val)
900 {
901 enum bt_ctf_value_status ret;
902 struct bt_ctf_private_value *real_obj = NULL;
903
904 real_obj = bt_ctf_private_value_real_create_init(val);
905 ret = bt_ctf_private_value_array_append_element(array_obj,
906 (void *) real_obj);
907 bt_ctf_object_put_ref(real_obj);
908 return ret;
909 }
910
911 enum bt_ctf_value_status bt_ctf_private_value_array_append_string_element(
912 struct bt_ctf_private_value *array_obj, const char *val)
913 {
914 enum bt_ctf_value_status ret;
915 struct bt_ctf_private_value *string_obj = NULL;
916
917 string_obj = bt_ctf_private_value_string_create_init(val);
918 ret = bt_ctf_private_value_array_append_element(array_obj,
919 (void *) string_obj);
920 bt_ctf_object_put_ref(string_obj);
921 return ret;
922 }
923
924 enum bt_ctf_value_status bt_ctf_private_value_array_append_empty_array_element(
925 struct bt_ctf_private_value *array_obj)
926 {
927 enum bt_ctf_value_status ret;
928 struct bt_ctf_private_value *empty_array_obj = NULL;
929
930 empty_array_obj = bt_ctf_private_value_array_create();
931 ret = bt_ctf_private_value_array_append_element(array_obj,
932 (void *) empty_array_obj);
933 bt_ctf_object_put_ref(empty_array_obj);
934 return ret;
935 }
936
937 enum bt_ctf_value_status bt_ctf_private_value_array_append_empty_map_element(
938 struct bt_ctf_private_value *array_obj)
939 {
940 enum bt_ctf_value_status ret;
941 struct bt_ctf_private_value *map_obj = NULL;
942
943 map_obj = bt_ctf_private_value_map_create();
944 ret = bt_ctf_private_value_array_append_element(array_obj,
945 (void *) map_obj);
946 bt_ctf_object_put_ref(map_obj);
947 return ret;
948 }
949
950 enum bt_ctf_value_status bt_ctf_private_value_array_set_element_by_index(
951 struct bt_ctf_private_value *array_obj, uint64_t index,
952 struct bt_ctf_value *element_obj)
953 {
954 struct bt_ctf_value_array *typed_array_obj =
955 BT_CTF_VALUE_TO_ARRAY(array_obj);
956
957 BT_CTF_ASSERT_PRE_NON_NULL(array_obj, "Array value object");
958 BT_CTF_ASSERT_PRE_NON_NULL(element_obj, "Element value object");
959 BT_CTF_ASSERT_PRE_VALUE_IS_TYPE(array_obj, BT_CTF_VALUE_TYPE_ARRAY);
960 BT_CTF_ASSERT_PRE_VALUE_HOT(array_obj, "Array value object");
961 BT_CTF_ASSERT_PRE_VALUE_INDEX_IN_BOUNDS(index,
962 typed_array_obj->garray->len);
963 bt_ctf_object_put_ref(g_ptr_array_index(typed_array_obj->garray, index));
964 g_ptr_array_index(typed_array_obj->garray, index) = element_obj;
965 bt_ctf_object_get_ref(element_obj);
966 BT_LOGT("Set array value's element: array-value-addr=%p, "
967 "index=%" PRIu64 ", element-value-addr=%p",
968 array_obj, index, element_obj);
969 return BT_CTF_VALUE_STATUS_OK;
970 }
971
972 uint64_t bt_ctf_value_map_get_size(const struct bt_ctf_value *map_obj)
973 {
974 BT_CTF_ASSERT_PRE_NON_NULL(map_obj, "Value object");
975 BT_CTF_ASSERT_PRE_VALUE_IS_TYPE(map_obj, BT_CTF_VALUE_TYPE_MAP);
976 return (uint64_t) g_hash_table_size(BT_CTF_VALUE_TO_MAP(map_obj)->ght);
977 }
978
979 struct bt_ctf_value *bt_ctf_value_map_borrow_entry_value(const struct bt_ctf_value *map_obj,
980 const char *key)
981 {
982 BT_CTF_ASSERT_PRE_NON_NULL(map_obj, "Value object");
983 BT_CTF_ASSERT_PRE_NON_NULL(key, "Key");
984 BT_CTF_ASSERT_PRE_VALUE_IS_TYPE(map_obj, BT_CTF_VALUE_TYPE_MAP);
985 return g_hash_table_lookup(BT_CTF_VALUE_TO_MAP(map_obj)->ght,
986 GUINT_TO_POINTER(g_quark_from_string(key)));
987 }
988
989 struct bt_ctf_private_value *bt_ctf_private_value_map_borrow_entry_value(
990 const struct bt_ctf_private_value *map_obj, const char *key)
991 {
992 return (void *) bt_ctf_value_map_borrow_entry_value((void *) map_obj, key);
993 }
994
995 bt_ctf_bool bt_ctf_value_map_has_entry(const struct bt_ctf_value *map_obj, const char *key)
996 {
997 BT_CTF_ASSERT_PRE_NON_NULL(map_obj, "Value object");
998 BT_CTF_ASSERT_PRE_NON_NULL(key, "Key");
999 BT_CTF_ASSERT_PRE_VALUE_IS_TYPE(map_obj, BT_CTF_VALUE_TYPE_MAP);
1000 return bt_g_hash_table_contains(BT_CTF_VALUE_TO_MAP(map_obj)->ght,
1001 GUINT_TO_POINTER(g_quark_from_string(key)));
1002 }
1003
1004 enum bt_ctf_value_status bt_ctf_private_value_map_insert_entry(
1005 struct bt_ctf_private_value *map_obj,
1006 const char *key, struct bt_ctf_value *element_obj)
1007 {
1008 BT_CTF_ASSERT_PRE_NON_NULL(map_obj, "Map value object");
1009 BT_CTF_ASSERT_PRE_NON_NULL(key, "Key");
1010 BT_CTF_ASSERT_PRE_NON_NULL(element_obj, "Element value object");
1011 BT_CTF_ASSERT_PRE_VALUE_IS_TYPE(map_obj, BT_CTF_VALUE_TYPE_MAP);
1012 BT_CTF_ASSERT_PRE_VALUE_HOT(map_obj, "Map value object");
1013 g_hash_table_insert(BT_CTF_VALUE_TO_MAP(map_obj)->ght,
1014 GUINT_TO_POINTER(g_quark_from_string(key)), element_obj);
1015 bt_ctf_object_get_ref(element_obj);
1016 BT_LOGT("Inserted value into map value: map-value-addr=%p, "
1017 "key=\"%s\", element-value-addr=%p",
1018 map_obj, key, element_obj);
1019 return BT_CTF_VALUE_STATUS_OK;
1020 }
1021
1022 enum bt_ctf_value_status bt_ctf_private_value_map_insert_bool_entry(
1023 struct bt_ctf_private_value *map_obj, const char *key, bt_ctf_bool val)
1024 {
1025 enum bt_ctf_value_status ret;
1026 struct bt_ctf_private_value *bool_obj = NULL;
1027
1028 bool_obj = bt_ctf_private_value_bool_create_init(val);
1029 ret = bt_ctf_private_value_map_insert_entry(map_obj, key,
1030 (void *) bool_obj);
1031 bt_ctf_object_put_ref(bool_obj);
1032 return ret;
1033 }
1034
1035 enum bt_ctf_value_status bt_ctf_private_value_map_insert_integer_entry(
1036 struct bt_ctf_private_value *map_obj, const char *key, int64_t val)
1037 {
1038 enum bt_ctf_value_status ret;
1039 struct bt_ctf_private_value *integer_obj = NULL;
1040
1041 integer_obj = bt_ctf_private_value_integer_create_init(val);
1042 ret = bt_ctf_private_value_map_insert_entry(map_obj, key,
1043 (void *) integer_obj);
1044 bt_ctf_object_put_ref(integer_obj);
1045 return ret;
1046 }
1047
1048 enum bt_ctf_value_status bt_ctf_private_value_map_insert_real_entry(
1049 struct bt_ctf_private_value *map_obj, const char *key, double val)
1050 {
1051 enum bt_ctf_value_status ret;
1052 struct bt_ctf_private_value *real_obj = NULL;
1053
1054 real_obj = bt_ctf_private_value_real_create_init(val);
1055 ret = bt_ctf_private_value_map_insert_entry(map_obj, key,
1056 (void *) real_obj);
1057 bt_ctf_object_put_ref(real_obj);
1058 return ret;
1059 }
1060
1061 enum bt_ctf_value_status bt_ctf_private_value_map_insert_string_entry(
1062 struct bt_ctf_private_value *map_obj, const char *key,
1063 const char *val)
1064 {
1065 enum bt_ctf_value_status ret;
1066 struct bt_ctf_private_value *string_obj = NULL;
1067
1068 string_obj = bt_ctf_private_value_string_create_init(val);
1069 ret = bt_ctf_private_value_map_insert_entry(map_obj, key,
1070 (void *) string_obj);
1071 bt_ctf_object_put_ref(string_obj);
1072 return ret;
1073 }
1074
1075 enum bt_ctf_value_status bt_ctf_private_value_map_insert_empty_array_entry(
1076 struct bt_ctf_private_value *map_obj, const char *key)
1077 {
1078 enum bt_ctf_value_status ret;
1079 struct bt_ctf_private_value *array_obj = NULL;
1080
1081 array_obj = bt_ctf_private_value_array_create();
1082 ret = bt_ctf_private_value_map_insert_entry(map_obj, key,
1083 (void *) array_obj);
1084 bt_ctf_object_put_ref(array_obj);
1085 return ret;
1086 }
1087
1088 enum bt_ctf_value_status bt_ctf_private_value_map_insert_empty_map_entry(
1089 struct bt_ctf_private_value *map_obj, const char *key)
1090 {
1091 enum bt_ctf_value_status ret;
1092 struct bt_ctf_private_value *empty_map_obj = NULL;
1093
1094 empty_map_obj = bt_ctf_private_value_map_create();
1095 ret = bt_ctf_private_value_map_insert_entry(map_obj, key,
1096 (void *) empty_map_obj);
1097 bt_ctf_object_put_ref(empty_map_obj);
1098 return ret;
1099 }
1100
1101 enum bt_ctf_value_status bt_ctf_value_map_foreach_entry(const struct bt_ctf_value *map_obj,
1102 bt_ctf_value_map_foreach_entry_cb cb, void *data)
1103 {
1104 enum bt_ctf_value_status ret = BT_CTF_VALUE_STATUS_OK;
1105 gpointer key, element_obj;
1106 GHashTableIter iter;
1107 struct bt_ctf_value_map *typed_map_obj = BT_CTF_VALUE_TO_MAP(map_obj);
1108
1109 BT_CTF_ASSERT_PRE_NON_NULL(map_obj, "Value object");
1110 BT_CTF_ASSERT_PRE_NON_NULL(cb, "Callback");
1111 BT_CTF_ASSERT_PRE_VALUE_IS_TYPE(map_obj, BT_CTF_VALUE_TYPE_MAP);
1112 g_hash_table_iter_init(&iter, typed_map_obj->ght);
1113
1114 while (g_hash_table_iter_next(&iter, &key, &element_obj)) {
1115 const char *key_str = g_quark_to_string(GPOINTER_TO_UINT(key));
1116
1117 if (!cb(key_str, element_obj, data)) {
1118 BT_LOGT("User canceled the loop: key=\"%s\", "
1119 "value-addr=%p, data=%p",
1120 key_str, element_obj, data);
1121 ret = BT_CTF_VALUE_STATUS_CANCELED;
1122 break;
1123 }
1124 }
1125
1126 return ret;
1127 }
1128
1129 enum bt_ctf_value_status bt_ctf_private_value_map_foreach_entry(
1130 const struct bt_ctf_private_value *map_obj,
1131 bt_ctf_private_value_map_foreach_entry_cb cb, void *data)
1132 {
1133 return bt_ctf_value_map_foreach_entry((void *) map_obj,
1134 (bt_ctf_value_map_foreach_entry_cb) cb, data);
1135 }
1136
1137 struct extend_map_element_data {
1138 struct bt_ctf_private_value *extended_obj;
1139 enum bt_ctf_value_status status;
1140 };
1141
1142 static
1143 bt_ctf_bool extend_map_element(const char *key,
1144 struct bt_ctf_value *extension_obj_elem, void *data)
1145 {
1146 bt_ctf_bool ret = BT_CTF_TRUE;
1147 struct extend_map_element_data *extend_data = data;
1148 struct bt_ctf_private_value *extension_obj_elem_copy = NULL;
1149
1150 /* Copy object which is to replace the current one */
1151 extend_data->status = bt_ctf_value_copy(&extension_obj_elem_copy,
1152 extension_obj_elem);
1153 if (extend_data->status) {
1154 BT_LOGE("Cannot copy map element: addr=%p",
1155 extension_obj_elem);
1156 goto error;
1157 }
1158
1159 BT_ASSERT_DBG(extension_obj_elem_copy);
1160
1161 /* Replace in extended object */
1162 extend_data->status = bt_ctf_private_value_map_insert_entry(
1163 extend_data->extended_obj, key,
1164 (void *) extension_obj_elem_copy);
1165 if (extend_data->status) {
1166 BT_LOGE("Cannot replace value in extended value: key=\"%s\", "
1167 "extended-value-addr=%p, element-value-addr=%p",
1168 key, extend_data->extended_obj,
1169 extension_obj_elem_copy);
1170 goto error;
1171 }
1172
1173 goto end;
1174
1175 error:
1176 BT_ASSERT_DBG(extend_data->status != BT_CTF_VALUE_STATUS_OK);
1177 ret = BT_CTF_FALSE;
1178
1179 end:
1180 BT_CTF_OBJECT_PUT_REF_AND_RESET(extension_obj_elem_copy);
1181 return ret;
1182 }
1183
1184 enum bt_ctf_value_status bt_ctf_value_map_extend(
1185 struct bt_ctf_private_value **extended_map_obj,
1186 const struct bt_ctf_value *base_map_obj,
1187 const struct bt_ctf_value *extension_obj)
1188 {
1189 struct extend_map_element_data extend_data = {
1190 .extended_obj = NULL,
1191 .status = BT_CTF_VALUE_STATUS_OK,
1192 };
1193
1194 BT_CTF_ASSERT_PRE_NON_NULL(base_map_obj, "Base value object");
1195 BT_CTF_ASSERT_PRE_NON_NULL(extension_obj, "Extension value object");
1196 BT_CTF_ASSERT_PRE_NON_NULL(extended_map_obj,
1197 "Extended value object (output)");
1198 BT_CTF_ASSERT_PRE_VALUE_IS_TYPE(base_map_obj, BT_CTF_VALUE_TYPE_MAP);
1199 BT_CTF_ASSERT_PRE_VALUE_IS_TYPE(extension_obj, BT_CTF_VALUE_TYPE_MAP);
1200 BT_LOGD("Extending map value: base-value-addr=%p, extension-value-addr=%p",
1201 base_map_obj, extension_obj);
1202 *extended_map_obj = NULL;
1203
1204 /* Create copy of base map object to start with */
1205 extend_data.status = bt_ctf_value_copy(extended_map_obj, base_map_obj);
1206 if (extend_data.status) {
1207 BT_LOGE("Cannot copy base value: base-value-addr=%p",
1208 base_map_obj);
1209 goto error;
1210 }
1211
1212 BT_ASSERT_DBG(extended_map_obj);
1213
1214 /*
1215 * For each key in the extension map object, replace this key
1216 * in the copied map object.
1217 */
1218 extend_data.extended_obj = *extended_map_obj;
1219
1220 if (bt_ctf_value_map_foreach_entry(extension_obj, extend_map_element,
1221 &extend_data)) {
1222 BT_LOGE("Cannot iterate on the extension object's elements: "
1223 "extension-value-addr=%p", extension_obj);
1224 goto error;
1225 }
1226
1227 if (extend_data.status) {
1228 BT_LOGE("Failed to successfully iterate on the extension object's elements: "
1229 "extension-value-addr=%p", extension_obj);
1230 goto error;
1231 }
1232
1233 BT_LOGD("Extended map value: extended-value-addr=%p",
1234 *extended_map_obj);
1235 goto end;
1236
1237 error:
1238 BT_CTF_OBJECT_PUT_REF_AND_RESET(*extended_map_obj);
1239 *extended_map_obj = NULL;
1240
1241 end:
1242 return extend_data.status;
1243 }
1244
1245 enum bt_ctf_value_status bt_ctf_value_copy(struct bt_ctf_private_value **copy_obj,
1246 const struct bt_ctf_value *object)
1247 {
1248 enum bt_ctf_value_status status = BT_CTF_VALUE_STATUS_OK;
1249
1250 BT_CTF_ASSERT_PRE_NON_NULL(object, "Value object");
1251 BT_CTF_ASSERT_PRE_NON_NULL(copy_obj, "Value object copy (output)");
1252 BT_LOGD("Copying value object: addr=%p", object);
1253 *copy_obj = copy_funcs[object->type](object);
1254 if (*copy_obj) {
1255 BT_LOGD("Copied value object: copy-value-addr=%p",
1256 copy_obj);
1257 } else {
1258 status = BT_CTF_VALUE_STATUS_NOMEM;
1259 *copy_obj = NULL;
1260 BT_LOGE_STR("Failed to copy value object.");
1261 }
1262
1263 return status;
1264 }
1265
1266 bt_ctf_bool bt_ctf_value_compare(const struct bt_ctf_value *object_a,
1267 const struct bt_ctf_value *object_b)
1268 {
1269 bt_ctf_bool ret = BT_CTF_FALSE;
1270
1271 BT_CTF_ASSERT_PRE_NON_NULL(object_a, "Value object A");
1272 BT_CTF_ASSERT_PRE_NON_NULL(object_b, "Value object B");
1273
1274 if (object_a->type != object_b->type) {
1275 BT_LOGT("Values are different: type mismatch: "
1276 "value-a-addr=%p, value-b-addr=%p, "
1277 "value-a-type=%d, value-b-type=%d",
1278 object_a, object_b, object_a->type, object_b->type);
1279 goto end;
1280 }
1281
1282 ret = compare_funcs[object_a->type](object_a, object_b);
1283
1284 end:
1285 return ret;
1286 }
This page took 0.064501 seconds and 5 git commands to generate.