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