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