Cleanup: bt namespace for compat glib
[babeltrace.git] / lib / values.c
1 /*
2 * Values.c: value objects
3 *
4 * Babeltrace Library
5 *
6 * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation
7 * Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com>
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * SOFTWARE.
26 */
27
28 #include <stdlib.h>
29 #include <string.h>
30 #include <assert.h>
31 #include <string.h>
32 #include <babeltrace/compiler.h>
33 #include <babeltrace/object-internal.h>
34 #include <babeltrace/ref.h>
35 #include <babeltrace/values.h>
36 #include <babeltrace/compat/glib.h>
37
38 #define BT_VALUE_FROM_CONCRETE(_concrete) ((struct bt_value *) (_concrete))
39 #define BT_VALUE_TO_BOOL(_base) ((struct bt_value_bool *) (_base))
40 #define BT_VALUE_TO_INTEGER(_base) ((struct bt_value_integer *) (_base))
41 #define BT_VALUE_TO_FLOAT(_base) ((struct bt_value_float *) (_base))
42 #define BT_VALUE_TO_STRING(_base) ((struct bt_value_string *) (_base))
43 #define BT_VALUE_TO_ARRAY(_base) ((struct bt_value_array *) (_base))
44 #define BT_VALUE_TO_MAP(_base) ((struct bt_value_map *) (_base))
45
46 struct bt_value {
47 struct bt_object base;
48 enum bt_value_type type;
49 bool is_frozen;
50 };
51
52 static
53 struct bt_value bt_value_null_instance = {
54 .type = BT_VALUE_TYPE_NULL,
55 .is_frozen = true,
56 };
57
58 struct bt_value *bt_value_null = &bt_value_null_instance;
59
60 struct bt_value_bool {
61 struct bt_value base;
62 bool value;
63 };
64
65 struct bt_value_integer {
66 struct bt_value base;
67 int64_t value;
68 };
69
70 struct bt_value_float {
71 struct bt_value base;
72 double value;
73 };
74
75 struct bt_value_string {
76 struct bt_value base;
77 GString *gstr;
78 };
79
80 struct bt_value_array {
81 struct bt_value base;
82 GPtrArray *garray;
83 };
84
85 struct bt_value_map {
86 struct bt_value base;
87 GHashTable *ght;
88 };
89
90 static
91 void bt_value_destroy(struct bt_object *obj);
92
93 static
94 void bt_value_string_destroy(struct bt_value *object)
95 {
96 g_string_free(BT_VALUE_TO_STRING(object)->gstr, TRUE);
97 }
98
99 static
100 void bt_value_array_destroy(struct bt_value *object)
101 {
102 /*
103 * Pointer array's registered value destructor will take care
104 * of putting each contained object.
105 */
106 g_ptr_array_free(BT_VALUE_TO_ARRAY(object)->garray, TRUE);
107 }
108
109 static
110 void bt_value_map_destroy(struct bt_value *object)
111 {
112 /*
113 * Hash table's registered value destructor will take care of
114 * putting each contained object. Keys are GQuarks and cannot
115 * be destroyed anyway.
116 */
117 g_hash_table_destroy(BT_VALUE_TO_MAP(object)->ght);
118 }
119
120 static
121 void (* const destroy_funcs[])(struct bt_value *) = {
122 [BT_VALUE_TYPE_NULL] = NULL,
123 [BT_VALUE_TYPE_BOOL] = NULL,
124 [BT_VALUE_TYPE_INTEGER] = NULL,
125 [BT_VALUE_TYPE_FLOAT] = NULL,
126 [BT_VALUE_TYPE_STRING] = bt_value_string_destroy,
127 [BT_VALUE_TYPE_ARRAY] = bt_value_array_destroy,
128 [BT_VALUE_TYPE_MAP] = bt_value_map_destroy,
129 };
130
131 static
132 struct bt_value *bt_value_null_copy(const struct bt_value *null_obj)
133 {
134 return bt_value_null;
135 }
136
137 static
138 struct bt_value *bt_value_bool_copy(const struct bt_value *bool_obj)
139 {
140 return bt_value_bool_create_init(BT_VALUE_TO_BOOL(bool_obj)->value);
141 }
142
143 static
144 struct bt_value *bt_value_integer_copy(const struct bt_value *integer_obj)
145 {
146 return bt_value_integer_create_init(
147 BT_VALUE_TO_INTEGER(integer_obj)->value);
148 }
149
150 static
151 struct bt_value *bt_value_float_copy(const struct bt_value *float_obj)
152 {
153 return bt_value_float_create_init(
154 BT_VALUE_TO_FLOAT(float_obj)->value);
155 }
156
157 static
158 struct bt_value *bt_value_string_copy(const struct bt_value *string_obj)
159 {
160 return bt_value_string_create_init(
161 BT_VALUE_TO_STRING(string_obj)->gstr->str);
162 }
163
164 static
165 struct bt_value *bt_value_array_copy(const struct bt_value *array_obj)
166 {
167 int i;
168 int ret;
169 struct bt_value *copy_obj;
170 struct bt_value_array *typed_array_obj;
171
172 typed_array_obj = BT_VALUE_TO_ARRAY(array_obj);
173 copy_obj = bt_value_array_create();
174
175 if (!copy_obj) {
176 goto end;
177 }
178
179 for (i = 0; i < typed_array_obj->garray->len; ++i) {
180 struct bt_value *element_obj_copy;
181 struct bt_value *element_obj = bt_value_array_get(array_obj, i);
182
183 if (!element_obj) {
184 BT_PUT(copy_obj);
185 goto end;
186 }
187
188 element_obj_copy = bt_value_copy(element_obj);
189 BT_PUT(element_obj);
190
191 if (!element_obj_copy) {
192 BT_PUT(copy_obj);
193 goto end;
194 }
195
196 ret = bt_value_array_append(copy_obj, element_obj_copy);
197 BT_PUT(element_obj_copy);
198
199 if (ret) {
200 BT_PUT(copy_obj);
201 goto end;
202 }
203 }
204
205 end:
206 return copy_obj;
207 }
208
209 static
210 struct bt_value *bt_value_map_copy(const struct bt_value *map_obj)
211 {
212 int ret;
213 GHashTableIter iter;
214 gpointer key, element_obj;
215 struct bt_value *copy_obj;
216 struct bt_value *element_obj_copy;
217 struct bt_value_map *typed_map_obj;
218
219 typed_map_obj = BT_VALUE_TO_MAP(map_obj);
220 copy_obj = bt_value_map_create();
221
222 if (!copy_obj) {
223 goto end;
224 }
225
226 g_hash_table_iter_init(&iter, typed_map_obj->ght);
227
228 while (g_hash_table_iter_next(&iter, &key, &element_obj)) {
229 const char *key_str = g_quark_to_string(GPOINTER_TO_UINT(key));
230
231 element_obj_copy = bt_value_copy(element_obj);
232
233 if (!element_obj_copy) {
234 BT_PUT(copy_obj);
235 goto end;
236 }
237
238 ret = bt_value_map_insert(copy_obj, key_str, element_obj_copy);
239 BT_PUT(element_obj_copy);
240
241 if (ret) {
242 BT_PUT(copy_obj);
243 goto end;
244 }
245 }
246
247 end:
248 return copy_obj;
249 }
250
251 static
252 struct bt_value *(* const copy_funcs[])(const struct bt_value *) = {
253 [BT_VALUE_TYPE_NULL] = bt_value_null_copy,
254 [BT_VALUE_TYPE_BOOL] = bt_value_bool_copy,
255 [BT_VALUE_TYPE_INTEGER] = bt_value_integer_copy,
256 [BT_VALUE_TYPE_FLOAT] = bt_value_float_copy,
257 [BT_VALUE_TYPE_STRING] = bt_value_string_copy,
258 [BT_VALUE_TYPE_ARRAY] = bt_value_array_copy,
259 [BT_VALUE_TYPE_MAP] = bt_value_map_copy,
260 };
261
262 static
263 bool bt_value_null_compare(const struct bt_value *object_a,
264 const struct bt_value *object_b)
265 {
266 /*
267 * Always true since bt_value_compare() already checks if both
268 * object_a and object_b have the same type, and in the case of
269 * null value objects, they're always the same if it is so.
270 */
271 return true;
272 }
273
274 static
275 bool bt_value_bool_compare(const struct bt_value *object_a,
276 const struct bt_value *object_b)
277 {
278 return BT_VALUE_TO_BOOL(object_a)->value ==
279 BT_VALUE_TO_BOOL(object_b)->value;
280 }
281
282 static
283 bool bt_value_integer_compare(const struct bt_value *object_a,
284 const struct bt_value *object_b)
285 {
286 return BT_VALUE_TO_INTEGER(object_a)->value ==
287 BT_VALUE_TO_INTEGER(object_b)->value;
288 }
289
290 static
291 bool bt_value_float_compare(const struct bt_value *object_a,
292 const struct bt_value *object_b)
293 {
294 return BT_VALUE_TO_FLOAT(object_a)->value ==
295 BT_VALUE_TO_FLOAT(object_b)->value;
296 }
297
298 static
299 bool bt_value_string_compare(const struct bt_value *object_a,
300 const struct bt_value *object_b)
301 {
302 return !strcmp(BT_VALUE_TO_STRING(object_a)->gstr->str,
303 BT_VALUE_TO_STRING(object_b)->gstr->str);
304 }
305
306 static
307 bool bt_value_array_compare(const struct bt_value *object_a,
308 const struct bt_value *object_b)
309 {
310 int i;
311 bool ret = true;
312 const struct bt_value_array *array_obj_a =
313 BT_VALUE_TO_ARRAY(object_a);
314
315 if (bt_value_array_size(object_a) != bt_value_array_size(object_b)) {
316 ret = false;
317 goto end;
318 }
319
320 for (i = 0; i < array_obj_a->garray->len; ++i) {
321 struct bt_value *element_obj_a;
322 struct bt_value *element_obj_b;
323
324 element_obj_a = bt_value_array_get(object_a, i);
325 element_obj_b = bt_value_array_get(object_b, i);
326
327 if (!bt_value_compare(element_obj_a, element_obj_b)) {
328 BT_PUT(element_obj_a);
329 BT_PUT(element_obj_b);
330 ret = false;
331 goto end;
332 }
333
334 BT_PUT(element_obj_a);
335 BT_PUT(element_obj_b);
336 }
337
338 end:
339 return ret;
340 }
341
342 static
343 bool bt_value_map_compare(const struct bt_value *object_a,
344 const struct bt_value *object_b)
345 {
346 bool ret = true;
347 GHashTableIter iter;
348 gpointer key, element_obj_a;
349 const struct bt_value_map *map_obj_a = BT_VALUE_TO_MAP(object_a);
350
351 if (bt_value_map_size(object_a) != bt_value_map_size(object_b)) {
352 ret = false;
353 goto end;
354 }
355
356 g_hash_table_iter_init(&iter, map_obj_a->ght);
357
358 while (g_hash_table_iter_next(&iter, &key, &element_obj_a)) {
359 struct bt_value *element_obj_b;
360 const char *key_str = g_quark_to_string(GPOINTER_TO_UINT(key));
361
362 element_obj_b = bt_value_map_get(object_b, key_str);
363
364 if (!bt_value_compare(element_obj_a, element_obj_b)) {
365 BT_PUT(element_obj_b);
366 ret = false;
367 goto end;
368 }
369
370 BT_PUT(element_obj_b);
371 }
372
373 end:
374 return ret;
375 }
376
377 static
378 bool (* const compare_funcs[])(const struct bt_value *,
379 const struct bt_value *) = {
380 [BT_VALUE_TYPE_NULL] = bt_value_null_compare,
381 [BT_VALUE_TYPE_BOOL] = bt_value_bool_compare,
382 [BT_VALUE_TYPE_INTEGER] = bt_value_integer_compare,
383 [BT_VALUE_TYPE_FLOAT] = bt_value_float_compare,
384 [BT_VALUE_TYPE_STRING] = bt_value_string_compare,
385 [BT_VALUE_TYPE_ARRAY] = bt_value_array_compare,
386 [BT_VALUE_TYPE_MAP] = bt_value_map_compare,
387 };
388
389 void bt_value_null_freeze(struct bt_value *object)
390 {
391 }
392
393 void bt_value_generic_freeze(struct bt_value *object)
394 {
395 object->is_frozen = true;
396 }
397
398 void bt_value_array_freeze(struct bt_value *object)
399 {
400 int i;
401 struct bt_value_array *typed_array_obj =
402 BT_VALUE_TO_ARRAY(object);
403
404 for (i = 0; i < typed_array_obj->garray->len; ++i) {
405 struct bt_value *element_obj =
406 g_ptr_array_index(typed_array_obj->garray, i);
407
408 bt_value_freeze(element_obj);
409 }
410
411 bt_value_generic_freeze(object);
412 }
413
414 void bt_value_map_freeze(struct bt_value *object)
415 {
416 GHashTableIter iter;
417 gpointer key, element_obj;
418 const struct bt_value_map *map_obj = BT_VALUE_TO_MAP(object);
419
420 g_hash_table_iter_init(&iter, map_obj->ght);
421
422 while (g_hash_table_iter_next(&iter, &key, &element_obj)) {
423 bt_value_freeze(element_obj);
424 }
425
426 bt_value_generic_freeze(object);
427 }
428
429 static
430 void (* const freeze_funcs[])(struct bt_value *) = {
431 [BT_VALUE_TYPE_NULL] = bt_value_null_freeze,
432 [BT_VALUE_TYPE_BOOL] = bt_value_generic_freeze,
433 [BT_VALUE_TYPE_INTEGER] = bt_value_generic_freeze,
434 [BT_VALUE_TYPE_FLOAT] = bt_value_generic_freeze,
435 [BT_VALUE_TYPE_STRING] = bt_value_generic_freeze,
436 [BT_VALUE_TYPE_ARRAY] = bt_value_array_freeze,
437 [BT_VALUE_TYPE_MAP] = bt_value_map_freeze,
438 };
439
440 static
441 void bt_value_destroy(struct bt_object *obj)
442 {
443 struct bt_value *value;
444
445 value = container_of(obj, struct bt_value, base);
446 assert(value->type != BT_VALUE_TYPE_UNKNOWN);
447
448 if (bt_value_is_null(value)) {
449 return;
450 }
451
452 if (destroy_funcs[value->type]) {
453 destroy_funcs[value->type](value);
454 }
455
456 g_free(value);
457 }
458
459 enum bt_value_status bt_value_freeze(struct bt_value *object)
460 {
461 enum bt_value_status ret = BT_VALUE_STATUS_OK;
462
463 if (!object) {
464 ret = BT_VALUE_STATUS_INVAL;
465 goto end;
466 }
467
468 freeze_funcs[object->type](object);
469
470 end:
471 return ret;
472 }
473
474 bool bt_value_is_frozen(const struct bt_value *object)
475 {
476 return object && object->is_frozen;
477 }
478
479 enum bt_value_type bt_value_get_type(const struct bt_value *object)
480 {
481 if (!object) {
482 return BT_VALUE_TYPE_UNKNOWN;
483 }
484
485 return object->type;
486 }
487
488 static
489 struct bt_value bt_value_create_base(enum bt_value_type type)
490 {
491 struct bt_value base;
492
493 base.type = type;
494 base.is_frozen = false;
495 bt_object_init(&base, bt_value_destroy);
496
497 return base;
498 }
499
500 struct bt_value *bt_value_bool_create_init(bool val)
501 {
502 struct bt_value_bool *bool_obj;
503
504 bool_obj = g_new0(struct bt_value_bool, 1);
505
506 if (!bool_obj) {
507 goto end;
508 }
509
510 bool_obj->base = bt_value_create_base(BT_VALUE_TYPE_BOOL);
511 bool_obj->value = val;
512
513 end:
514 return BT_VALUE_FROM_CONCRETE(bool_obj);
515 }
516
517 struct bt_value *bt_value_bool_create(void)
518 {
519 return bt_value_bool_create_init(false);
520 }
521
522 struct bt_value *bt_value_integer_create_init(int64_t val)
523 {
524 struct bt_value_integer *integer_obj;
525
526 integer_obj = g_new0(struct bt_value_integer, 1);
527
528 if (!integer_obj) {
529 goto end;
530 }
531
532 integer_obj->base = bt_value_create_base(BT_VALUE_TYPE_INTEGER);
533 integer_obj->value = val;
534
535 end:
536 return BT_VALUE_FROM_CONCRETE(integer_obj);
537 }
538
539 struct bt_value *bt_value_integer_create(void)
540 {
541 return bt_value_integer_create_init(0);
542 }
543
544 struct bt_value *bt_value_float_create_init(double val)
545 {
546 struct bt_value_float *float_obj;
547
548 float_obj = g_new0(struct bt_value_float, 1);
549
550 if (!float_obj) {
551 goto end;
552 }
553
554 float_obj->base = bt_value_create_base(BT_VALUE_TYPE_FLOAT);
555 float_obj->value = val;
556
557 end:
558 return BT_VALUE_FROM_CONCRETE(float_obj);
559 }
560
561 struct bt_value *bt_value_float_create(void)
562 {
563 return bt_value_float_create_init(0.);
564 }
565
566 struct bt_value *bt_value_string_create_init(const char *val)
567 {
568 struct bt_value_string *string_obj = NULL;
569
570 if (!val) {
571 goto end;
572 }
573
574 string_obj = g_new0(struct bt_value_string, 1);
575
576 if (!string_obj) {
577 goto end;
578 }
579
580 string_obj->base = bt_value_create_base(BT_VALUE_TYPE_STRING);
581 string_obj->gstr = g_string_new(val);
582
583 if (!string_obj->gstr) {
584 g_free(string_obj);
585 string_obj = NULL;
586 goto end;
587 }
588
589 end:
590 return BT_VALUE_FROM_CONCRETE(string_obj);
591 }
592
593 struct bt_value *bt_value_string_create(void)
594 {
595 return bt_value_string_create_init("");
596 }
597
598 struct bt_value *bt_value_array_create(void)
599 {
600 struct bt_value_array *array_obj;
601
602 array_obj = g_new0(struct bt_value_array, 1);
603
604 if (!array_obj) {
605 goto end;
606 }
607
608 array_obj->base = bt_value_create_base(BT_VALUE_TYPE_ARRAY);
609 array_obj->garray = bt_g_ptr_array_new_full(0,
610 (GDestroyNotify) bt_put);
611
612 if (!array_obj->garray) {
613 g_free(array_obj);
614 array_obj = NULL;
615 goto end;
616 }
617
618 end:
619 return BT_VALUE_FROM_CONCRETE(array_obj);
620 }
621
622 struct bt_value *bt_value_map_create(void)
623 {
624 struct bt_value_map *map_obj;
625
626 map_obj = g_new0(struct bt_value_map, 1);
627
628 if (!map_obj) {
629 goto end;
630 }
631
632 map_obj->base = bt_value_create_base(BT_VALUE_TYPE_MAP);
633 map_obj->ght = g_hash_table_new_full(g_direct_hash, g_direct_equal,
634 NULL, (GDestroyNotify) bt_put);
635
636 if (!map_obj->ght) {
637 g_free(map_obj);
638 map_obj = NULL;
639 goto end;
640 }
641
642 end:
643 return BT_VALUE_FROM_CONCRETE(map_obj);
644 }
645
646 enum bt_value_status bt_value_bool_get(const struct bt_value *bool_obj,
647 bool *val)
648 {
649 enum bt_value_status ret = BT_VALUE_STATUS_OK;
650 struct bt_value_bool *typed_bool_obj = BT_VALUE_TO_BOOL(bool_obj);
651
652 if (!bool_obj || !bt_value_is_bool(bool_obj) || !val) {
653 ret = BT_VALUE_STATUS_INVAL;
654 goto end;
655 }
656
657 *val = typed_bool_obj->value;
658
659 end:
660 return ret;
661 }
662
663 enum bt_value_status bt_value_bool_set(struct bt_value *bool_obj, bool val)
664 {
665 enum bt_value_status ret = BT_VALUE_STATUS_OK;
666 struct bt_value_bool *typed_bool_obj = BT_VALUE_TO_BOOL(bool_obj);
667
668 if (!bool_obj || !bt_value_is_bool(bool_obj)) {
669 ret = BT_VALUE_STATUS_INVAL;
670 goto end;
671 }
672
673 if (bool_obj->is_frozen) {
674 ret = BT_VALUE_STATUS_FROZEN;
675 goto end;
676 }
677
678 typed_bool_obj->value = val;
679
680 end:
681 return ret;
682 }
683
684 enum bt_value_status bt_value_integer_get(const struct bt_value *integer_obj,
685 int64_t *val)
686 {
687 enum bt_value_status ret = BT_VALUE_STATUS_OK;
688 struct bt_value_integer *typed_integer_obj =
689 BT_VALUE_TO_INTEGER(integer_obj);
690
691 if (!integer_obj || !bt_value_is_integer(integer_obj) || !val) {
692 ret = BT_VALUE_STATUS_INVAL;
693 goto end;
694 }
695
696 *val = typed_integer_obj->value;
697
698 end:
699 return ret;
700 }
701
702 enum bt_value_status bt_value_integer_set(struct bt_value *integer_obj,
703 int64_t val)
704 {
705 enum bt_value_status ret = BT_VALUE_STATUS_OK;
706 struct bt_value_integer *typed_integer_obj =
707 BT_VALUE_TO_INTEGER(integer_obj);
708
709 if (!integer_obj || !bt_value_is_integer(integer_obj)) {
710 ret = BT_VALUE_STATUS_INVAL;
711 goto end;
712 }
713
714 if (integer_obj->is_frozen) {
715 ret = BT_VALUE_STATUS_FROZEN;
716 goto end;
717 }
718
719 typed_integer_obj->value = val;
720
721 end:
722 return ret;
723 }
724
725 enum bt_value_status bt_value_float_get(const struct bt_value *float_obj,
726 double *val)
727 {
728 enum bt_value_status ret = BT_VALUE_STATUS_OK;
729 struct bt_value_float *typed_float_obj =
730 BT_VALUE_TO_FLOAT(float_obj);
731
732 if (!float_obj || !bt_value_is_float(float_obj) || !val) {
733 ret = BT_VALUE_STATUS_INVAL;
734 goto end;
735 }
736
737 *val = typed_float_obj->value;
738
739 end:
740 return ret;
741 }
742
743 enum bt_value_status bt_value_float_set(struct bt_value *float_obj,
744 double val)
745 {
746 enum bt_value_status ret = BT_VALUE_STATUS_OK;
747 struct bt_value_float *typed_float_obj =
748 BT_VALUE_TO_FLOAT(float_obj);
749
750 if (!float_obj || !bt_value_is_float(float_obj)) {
751 ret = BT_VALUE_STATUS_INVAL;
752 goto end;
753 }
754
755 if (float_obj->is_frozen) {
756 ret = BT_VALUE_STATUS_FROZEN;
757 goto end;
758 }
759
760 typed_float_obj->value = val;
761
762 end:
763 return ret;
764 }
765
766 enum bt_value_status bt_value_string_get(const struct bt_value *string_obj,
767 const char **val)
768 {
769 enum bt_value_status ret = BT_VALUE_STATUS_OK;
770 struct bt_value_string *typed_string_obj =
771 BT_VALUE_TO_STRING(string_obj);
772
773 if (!string_obj || !bt_value_is_string(string_obj) || !val) {
774 ret = BT_VALUE_STATUS_INVAL;
775 goto end;
776 }
777
778 *val = typed_string_obj->gstr->str;
779
780 end:
781 return ret;
782 }
783
784 enum bt_value_status bt_value_string_set(struct bt_value *string_obj,
785 const char *val)
786 {
787 enum bt_value_status ret = BT_VALUE_STATUS_OK;
788 struct bt_value_string *typed_string_obj =
789 BT_VALUE_TO_STRING(string_obj);
790
791 if (!string_obj || !bt_value_is_string(string_obj) || !val) {
792 ret = BT_VALUE_STATUS_INVAL;
793 goto end;
794 }
795
796 if (string_obj->is_frozen) {
797 ret = BT_VALUE_STATUS_FROZEN;
798 goto end;
799 }
800
801 g_string_assign(typed_string_obj->gstr, val);
802
803 end:
804 return ret;
805 }
806
807 int bt_value_array_size(const struct bt_value *array_obj)
808 {
809 int ret;
810 struct bt_value_array *typed_array_obj =
811 BT_VALUE_TO_ARRAY(array_obj);
812
813 if (!array_obj || !bt_value_is_array(array_obj)) {
814 ret = BT_VALUE_STATUS_INVAL;
815 goto end;
816 }
817
818 ret = (int) typed_array_obj->garray->len;
819
820 end:
821 return ret;
822 }
823
824 bool bt_value_array_is_empty(const struct bt_value *array_obj)
825 {
826 return bt_value_array_size(array_obj) == 0;
827 }
828
829 struct bt_value *bt_value_array_get(const struct bt_value *array_obj,
830 size_t index)
831 {
832 struct bt_value *ret;
833 struct bt_value_array *typed_array_obj =
834 BT_VALUE_TO_ARRAY(array_obj);
835
836 if (!array_obj || !bt_value_is_array(array_obj) ||
837 index >= typed_array_obj->garray->len) {
838 ret = NULL;
839 goto end;
840 }
841
842 ret = g_ptr_array_index(typed_array_obj->garray, index);
843 bt_get(ret);
844
845 end:
846 return ret;
847 }
848
849 enum bt_value_status bt_value_array_append(struct bt_value *array_obj,
850 struct bt_value *element_obj)
851 {
852 enum bt_value_status ret = BT_VALUE_STATUS_OK;
853 struct bt_value_array *typed_array_obj =
854 BT_VALUE_TO_ARRAY(array_obj);
855
856 if (!array_obj || !bt_value_is_array(array_obj) || !element_obj) {
857 ret = BT_VALUE_STATUS_INVAL;
858 goto end;
859 }
860
861 if (array_obj->is_frozen) {
862 ret = BT_VALUE_STATUS_FROZEN;
863 goto end;
864 }
865
866 g_ptr_array_add(typed_array_obj->garray, element_obj);
867 bt_get(element_obj);
868
869 end:
870 return ret;
871 }
872
873 enum bt_value_status bt_value_array_append_bool(struct bt_value *array_obj,
874 bool val)
875 {
876 enum bt_value_status ret;
877 struct bt_value *bool_obj = NULL;
878
879 bool_obj = bt_value_bool_create_init(val);
880 ret = bt_value_array_append(array_obj, bool_obj);
881 bt_put(bool_obj);
882
883 return ret;
884 }
885
886 enum bt_value_status bt_value_array_append_integer(
887 struct bt_value *array_obj, int64_t val)
888 {
889 enum bt_value_status ret;
890 struct bt_value *integer_obj = NULL;
891
892 integer_obj = bt_value_integer_create_init(val);
893 ret = bt_value_array_append(array_obj, integer_obj);
894 bt_put(integer_obj);
895
896 return ret;
897 }
898
899 enum bt_value_status bt_value_array_append_float(struct bt_value *array_obj,
900 double val)
901 {
902 enum bt_value_status ret;
903 struct bt_value *float_obj = NULL;
904
905 float_obj = bt_value_float_create_init(val);
906 ret = bt_value_array_append(array_obj, float_obj);
907 bt_put(float_obj);
908
909 return ret;
910 }
911
912 enum bt_value_status bt_value_array_append_string(struct bt_value *array_obj,
913 const char *val)
914 {
915 enum bt_value_status ret;
916 struct bt_value *string_obj = NULL;
917
918 string_obj = bt_value_string_create_init(val);
919 ret = bt_value_array_append(array_obj, string_obj);
920 bt_put(string_obj);
921
922 return ret;
923 }
924
925 enum bt_value_status bt_value_array_append_empty_array(
926 struct bt_value *array_obj)
927 {
928 enum bt_value_status ret;
929 struct bt_value *empty_array_obj = NULL;
930
931 empty_array_obj = bt_value_array_create();
932 ret = bt_value_array_append(array_obj, empty_array_obj);
933 bt_put(empty_array_obj);
934
935 return ret;
936 }
937
938 enum bt_value_status bt_value_array_append_empty_map(struct bt_value *array_obj)
939 {
940 enum bt_value_status ret;
941 struct bt_value *map_obj = NULL;
942
943 map_obj = bt_value_map_create();
944 ret = bt_value_array_append(array_obj, map_obj);
945 bt_put(map_obj);
946
947 return ret;
948 }
949
950 enum bt_value_status bt_value_array_set(struct bt_value *array_obj,
951 size_t index, struct bt_value *element_obj)
952 {
953 enum bt_value_status ret = BT_VALUE_STATUS_OK;
954 struct bt_value_array *typed_array_obj =
955 BT_VALUE_TO_ARRAY(array_obj);
956
957 if (!array_obj || !bt_value_is_array(array_obj) || !element_obj ||
958 index >= typed_array_obj->garray->len) {
959 ret = BT_VALUE_STATUS_INVAL;
960 goto end;
961 }
962
963 if (array_obj->is_frozen) {
964 ret = BT_VALUE_STATUS_FROZEN;
965 goto end;
966 }
967
968 bt_put(g_ptr_array_index(typed_array_obj->garray, index));
969 g_ptr_array_index(typed_array_obj->garray, index) = element_obj;
970 bt_get(element_obj);
971
972 end:
973 return ret;
974 }
975
976 int bt_value_map_size(const struct bt_value *map_obj)
977 {
978 int ret;
979 struct bt_value_map *typed_map_obj = BT_VALUE_TO_MAP(map_obj);
980
981 if (!map_obj || !bt_value_is_map(map_obj)) {
982 ret = BT_VALUE_STATUS_INVAL;
983 goto end;
984 }
985
986 ret = (int) g_hash_table_size(typed_map_obj->ght);
987
988 end:
989 return ret;
990 }
991
992 bool bt_value_map_is_empty(const struct bt_value *map_obj)
993 {
994 return bt_value_map_size(map_obj) == 0;
995 }
996
997 struct bt_value *bt_value_map_get(const struct bt_value *map_obj,
998 const char *key)
999 {
1000 GQuark quark;
1001 struct bt_value *ret;
1002 struct bt_value_map *typed_map_obj = BT_VALUE_TO_MAP(map_obj);
1003
1004 if (!map_obj || !bt_value_is_map(map_obj) || !key) {
1005 ret = NULL;
1006 goto end;
1007 }
1008
1009 quark = g_quark_from_string(key);
1010 ret = g_hash_table_lookup(typed_map_obj->ght, GUINT_TO_POINTER(quark));
1011
1012 if (ret) {
1013 bt_get(ret);
1014 }
1015
1016 end:
1017 return ret;
1018 }
1019
1020 bool bt_value_map_has_key(const struct bt_value *map_obj, const char *key)
1021 {
1022 bool ret;
1023 GQuark quark;
1024 struct bt_value_map *typed_map_obj = BT_VALUE_TO_MAP(map_obj);
1025
1026 if (!map_obj || !bt_value_is_map(map_obj) || !key) {
1027 ret = false;
1028 goto end;
1029 }
1030
1031 quark = g_quark_from_string(key);
1032 ret = bt_g_hash_table_contains(typed_map_obj->ght,
1033 GUINT_TO_POINTER(quark));
1034
1035 end:
1036 return ret;
1037 }
1038
1039 enum bt_value_status bt_value_map_insert(struct bt_value *map_obj,
1040 const char *key, struct bt_value *element_obj)
1041 {
1042 GQuark quark;
1043 enum bt_value_status ret = BT_VALUE_STATUS_OK;
1044 struct bt_value_map *typed_map_obj = BT_VALUE_TO_MAP(map_obj);
1045
1046 if (!map_obj || !bt_value_is_map(map_obj) || !key || !element_obj) {
1047 ret = BT_VALUE_STATUS_INVAL;
1048 goto end;
1049 }
1050
1051 if (map_obj->is_frozen) {
1052 ret = BT_VALUE_STATUS_FROZEN;
1053 goto end;
1054 }
1055
1056 quark = g_quark_from_string(key);
1057 g_hash_table_insert(typed_map_obj->ght,
1058 GUINT_TO_POINTER(quark), element_obj);
1059 bt_get(element_obj);
1060
1061 end:
1062 return ret;
1063 }
1064
1065 enum bt_value_status bt_value_map_insert_bool(struct bt_value *map_obj,
1066 const char *key, bool val)
1067 {
1068 enum bt_value_status ret;
1069 struct bt_value *bool_obj = NULL;
1070
1071 bool_obj = bt_value_bool_create_init(val);
1072 ret = bt_value_map_insert(map_obj, key, bool_obj);
1073 bt_put(bool_obj);
1074
1075 return ret;
1076 }
1077
1078 enum bt_value_status bt_value_map_insert_integer(struct bt_value *map_obj,
1079 const char *key, int64_t val)
1080 {
1081 enum bt_value_status ret;
1082 struct bt_value *integer_obj = NULL;
1083
1084 integer_obj = bt_value_integer_create_init(val);
1085 ret = bt_value_map_insert(map_obj, key, integer_obj);
1086 bt_put(integer_obj);
1087
1088 return ret;
1089 }
1090
1091 enum bt_value_status bt_value_map_insert_float(struct bt_value *map_obj,
1092 const char *key, double val)
1093 {
1094 enum bt_value_status ret;
1095 struct bt_value *float_obj = NULL;
1096
1097 float_obj = bt_value_float_create_init(val);
1098 ret = bt_value_map_insert(map_obj, key, float_obj);
1099 bt_put(float_obj);
1100
1101 return ret;
1102 }
1103
1104 enum bt_value_status bt_value_map_insert_string(struct bt_value *map_obj,
1105 const char *key, const char *val)
1106 {
1107 enum bt_value_status ret;
1108 struct bt_value *string_obj = NULL;
1109
1110 string_obj = bt_value_string_create_init(val);
1111 ret = bt_value_map_insert(map_obj, key, string_obj);
1112 bt_put(string_obj);
1113
1114 return ret;
1115 }
1116
1117 enum bt_value_status bt_value_map_insert_empty_array(struct bt_value *map_obj,
1118 const char *key)
1119 {
1120 enum bt_value_status ret;
1121 struct bt_value *array_obj = NULL;
1122
1123 array_obj = bt_value_array_create();
1124 ret = bt_value_map_insert(map_obj, key, array_obj);
1125 bt_put(array_obj);
1126
1127 return ret;
1128 }
1129
1130 enum bt_value_status bt_value_map_insert_empty_map(struct bt_value *map_obj,
1131 const char *key)
1132 {
1133 enum bt_value_status ret;
1134 struct bt_value *empty_map_obj = NULL;
1135
1136 empty_map_obj = bt_value_map_create();
1137 ret = bt_value_map_insert(map_obj, key, empty_map_obj);
1138 bt_put(empty_map_obj);
1139
1140 return ret;
1141 }
1142
1143 enum bt_value_status bt_value_map_foreach(const struct bt_value *map_obj,
1144 bt_value_map_foreach_cb cb, void *data)
1145 {
1146 enum bt_value_status ret = BT_VALUE_STATUS_OK;
1147 gpointer key, element_obj;
1148 GHashTableIter iter;
1149 struct bt_value_map *typed_map_obj = BT_VALUE_TO_MAP(map_obj);
1150
1151 if (!map_obj || !bt_value_is_map(map_obj) || !cb) {
1152 ret = BT_VALUE_STATUS_INVAL;
1153 goto end;
1154 }
1155
1156 g_hash_table_iter_init(&iter, typed_map_obj->ght);
1157
1158 while (g_hash_table_iter_next(&iter, &key, &element_obj)) {
1159 const char *key_str = g_quark_to_string(GPOINTER_TO_UINT(key));
1160
1161 if (!cb(key_str, element_obj, data)) {
1162 ret = BT_VALUE_STATUS_CANCELLED;
1163 break;
1164 }
1165 }
1166
1167 end:
1168 return ret;
1169 }
1170
1171 struct bt_value *bt_value_copy(const struct bt_value *object)
1172 {
1173 struct bt_value *copy_obj = NULL;
1174
1175 if (!object) {
1176 goto end;
1177 }
1178
1179 copy_obj = copy_funcs[object->type](object);
1180
1181 end:
1182 return copy_obj;
1183 }
1184
1185 bool bt_value_compare(const struct bt_value *object_a,
1186 const struct bt_value *object_b)
1187 {
1188 bool ret = false;
1189
1190 if (!object_a || !object_b) {
1191 goto end;
1192 }
1193
1194 if (object_a->type != object_b->type) {
1195 goto end;
1196 }
1197
1198 ret = compare_funcs[object_a->type](object_a, object_b);
1199
1200 end:
1201 return ret;
1202 }
This page took 0.072527 seconds and 4 git commands to generate.