7c45dafa4e769b0ed7ba530387d767aef0640d3a
[babeltrace.git] / lib / ctf-writer / values.c
1 /*
2 * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation
3 * Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com>
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 */
23
24 #define BT_LOG_TAG "CTF-WRITER-VALUES"
25 #include <babeltrace2/lib-logging-internal.h>
26
27 #include <stdlib.h>
28 #include <string.h>
29 #include <string.h>
30 #include <inttypes.h>
31 #include <babeltrace2/compiler-internal.h>
32 #include <babeltrace2/common-internal.h>
33 #include <babeltrace2/ctf-writer/object.h>
34 #include <babeltrace2/ctf-writer/values-internal.h>
35 #include <babeltrace2/compat/glib-internal.h>
36 #include <babeltrace2/types.h>
37 #include <babeltrace2/ctf-writer/object-internal.h>
38 #include <babeltrace2/ctf-writer/values-internal.h>
39 #include <babeltrace2/assert-internal.h>
40 #include <babeltrace2/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
65 struct bt_ctf_value {
66 struct bt_ctf_object base;
67 enum bt_ctf_value_type type;
68 bt_bool frozen;
69 };
70
71 static
72 void 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
77 static
78 struct 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
91 struct bt_ctf_value *const bt_ctf_value_null = &bt_ctf_value_null_instance;
92 struct bt_ctf_private_value *const bt_ctf_private_value_null =
93 (void *) &bt_ctf_value_null_instance;
94
95 struct bt_ctf_value_bool {
96 struct bt_ctf_value base;
97 bt_bool value;
98 };
99
100 struct bt_ctf_value_integer {
101 struct bt_ctf_value base;
102 int64_t value;
103 };
104
105 struct bt_ctf_value_real {
106 struct bt_ctf_value base;
107 double value;
108 };
109
110 struct bt_ctf_value_string {
111 struct bt_ctf_value base;
112 GString *gstr;
113 };
114
115 struct bt_ctf_value_array {
116 struct bt_ctf_value base;
117 GPtrArray *garray;
118 };
119
120 struct bt_ctf_value_map {
121 struct bt_ctf_value base;
122 GHashTable *ght;
123 };
124
125 static
126 void bt_ctf_value_destroy(struct bt_ctf_object *obj);
127
128 static
129 void 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
135 static
136 void 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
146 static
147 void 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
158 static
159 void (* 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
169 static
170 struct 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
175 static
176 struct 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
182 static
183 struct 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
190 static
191 struct 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
197 static
198 struct 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
204 static
205 struct 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
253 end:
254 return copy_obj;
255 }
256
257 static
258 struct 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
305 end:
306 return copy_obj;
307 }
308
309 static
310 struct 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
320 static
321 bt_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
332 static
333 bt_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
348 static
349 bt_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
364 static
365 bt_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
380 static
381 bt_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
396 static
397 bt_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
435 end:
436 return ret;
437 }
438
439 static
440 bt_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
478 end:
479 return ret;
480 }
481
482 static
483 bt_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
494 static
495 void bt_ctf_value_null_freeze(struct bt_ctf_value *object)
496 {
497 }
498
499 static
500 void bt_ctf_value_generic_freeze(struct bt_ctf_value *object)
501 {
502 object->frozen = BT_TRUE;
503 }
504
505 static
506 void 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
519 static
520 void 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
535 static
536 void (* 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
546 static
547 void 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
566 BT_HIDDEN
567 enum 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
580 end:
581 return ret;
582 }
583
584 BT_HIDDEN
585 enum 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
591 static
592 struct 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
602 BT_HIDDEN
603 struct 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
618 end:
619 return (void *) BT_CTF_VALUE_FROM_CONCRETE(bool_obj);
620 }
621
622 BT_HIDDEN
623 struct 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
628 BT_HIDDEN
629 struct 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
645 end:
646 return (void *) BT_CTF_VALUE_FROM_CONCRETE(integer_obj);
647 }
648
649 BT_HIDDEN
650 struct bt_ctf_private_value *bt_ctf_private_value_integer_create(void)
651 {
652 return bt_ctf_private_value_integer_create_init(0);
653 }
654
655 BT_HIDDEN
656 struct 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
672 end:
673 return (void *) BT_CTF_VALUE_FROM_CONCRETE(real_obj);
674 }
675
676 BT_HIDDEN
677 struct bt_ctf_private_value *bt_ctf_private_value_real_create(void)
678 {
679 return bt_ctf_private_value_real_create_init(0.);
680 }
681
682 BT_HIDDEN
683 struct 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
711 end:
712 return (void *) BT_CTF_VALUE_FROM_CONCRETE(string_obj);
713 }
714
715 BT_HIDDEN
716 struct bt_ctf_private_value *bt_ctf_private_value_string_create(void)
717 {
718 return bt_ctf_private_value_string_create_init("");
719 }
720
721 BT_HIDDEN
722 struct 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
746 end:
747 return (void *) BT_CTF_VALUE_FROM_CONCRETE(array_obj);
748 }
749
750 BT_HIDDEN
751 struct 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
775 end:
776 return (void *) BT_CTF_VALUE_FROM_CONCRETE(map_obj);
777 }
778
779 BT_HIDDEN
780 bt_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
787 BT_HIDDEN
788 void 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
798 BT_HIDDEN
799 int64_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
806 BT_HIDDEN
807 void 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
818 BT_HIDDEN
819 double 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
826 BT_HIDDEN
827 void 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
837 BT_HIDDEN
838 const 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
845 BT_HIDDEN
846 enum 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
858 BT_HIDDEN
859 uint64_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
866 BT_HIDDEN
867 struct 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
881 BT_HIDDEN
882 struct 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
890 BT_HIDDEN
891 enum 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
910 BT_HIDDEN
911 enum 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
924 BT_HIDDEN
925 enum 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
938 BT_HIDDEN
939 enum 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
952 BT_HIDDEN
953 enum 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
966 BT_HIDDEN
967 enum 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
980 BT_HIDDEN
981 enum 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
994 BT_HIDDEN
995 enum 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
1017 BT_HIDDEN
1018 uint64_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
1025 BT_HIDDEN
1026 struct 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
1036 BT_HIDDEN
1037 struct 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
1043 BT_HIDDEN
1044 bt_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
1053 BT_HIDDEN
1054 enum 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
1072 BT_HIDDEN
1073 enum 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
1086 BT_HIDDEN
1087 enum 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
1100 BT_HIDDEN
1101 enum 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
1114 BT_HIDDEN
1115 enum 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
1129 BT_HIDDEN
1130 enum 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
1143 BT_HIDDEN
1144 enum 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
1157 BT_HIDDEN
1158 enum 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
1186 BT_HIDDEN
1187 enum 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
1195 struct extend_map_element_data {
1196 struct bt_ctf_private_value *extended_obj;
1197 enum bt_ctf_value_status status;
1198 };
1199
1200 static
1201 bt_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
1233 error:
1234 BT_ASSERT(extend_data->status != BT_CTF_VALUE_STATUS_OK);
1235 ret = BT_FALSE;
1236
1237 end:
1238 BT_CTF_OBJECT_PUT_REF_AND_RESET(extension_obj_elem_copy);
1239 return ret;
1240 }
1241
1242 BT_HIDDEN
1243 enum 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
1296 error:
1297 BT_CTF_OBJECT_PUT_REF_AND_RESET(*extended_map_obj);
1298 *extended_map_obj = NULL;
1299
1300 end:
1301 return extend_data.status;
1302 }
1303
1304 BT_HIDDEN
1305 enum 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
1326 BT_HIDDEN
1327 bt_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
1345 end:
1346 return ret;
1347 }
This page took 0.060664 seconds and 4 git commands to generate.