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