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