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