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