objects: simplify destroy functions
[babeltrace.git] / lib / objects.c
1 /*
2 * objects.c: basic object system
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/ctf-writer/ref-internal.h>
33 #include <babeltrace/compiler.h>
34 #include <glib.h>
35 #include <babeltrace/objects.h>
36
37 #define BT_OBJECT_FROM_CONCRETE(_concrete) ((struct bt_object *) (_concrete))
38 #define BT_OBJECT_TO_BOOL(_base) ((struct bt_object_bool *) (_base))
39 #define BT_OBJECT_TO_INTEGER(_base) ((struct bt_object_integer *) (_base))
40 #define BT_OBJECT_TO_FLOAT(_base) ((struct bt_object_float *) (_base))
41 #define BT_OBJECT_TO_STRING(_base) ((struct bt_object_string *) (_base))
42 #define BT_OBJECT_TO_ARRAY(_base) ((struct bt_object_array *) (_base))
43 #define BT_OBJECT_TO_MAP(_base) ((struct bt_object_map *) (_base))
44
45 struct bt_object {
46 enum bt_object_type type;
47 struct bt_ctf_ref ref_count;
48 };
49
50 static
51 struct bt_object bt_object_null_instance = {
52 .type = BT_OBJECT_TYPE_NULL,
53 };
54
55 struct bt_object *bt_object_null = &bt_object_null_instance;
56
57 struct bt_object_bool {
58 struct bt_object base;
59 bool value;
60 };
61
62 struct bt_object_integer {
63 struct bt_object base;
64 int64_t value;
65 };
66
67 struct bt_object_float {
68 struct bt_object base;
69 double value;
70 };
71
72 struct bt_object_string {
73 struct bt_object base;
74 GString *gstr;
75 };
76
77 struct bt_object_array {
78 struct bt_object base;
79 GPtrArray *garray;
80 };
81
82 struct bt_object_map {
83 struct bt_object base;
84 GHashTable *ght;
85 };
86
87 static
88 void bt_object_string_destroy(struct bt_object *object)
89 {
90 g_string_free(BT_OBJECT_TO_STRING(object)->gstr, TRUE);
91 }
92
93 static
94 void bt_object_array_destroy(struct bt_object *object)
95 {
96 /*
97 * Pointer array's registered value destructor will take care
98 * of putting each contained object.
99 */
100 g_ptr_array_free(BT_OBJECT_TO_ARRAY(object)->garray, TRUE);
101 }
102
103 static
104 void bt_object_map_destroy(struct bt_object *object)
105 {
106 /*
107 * Hash table's registered value destructor will take care of
108 * putting each contained object. Keys are GQuarks and cannot
109 * be destroyed anyway.
110 */
111 g_hash_table_destroy(BT_OBJECT_TO_MAP(object)->ght);
112 }
113
114 static
115 void (* const destroy_funcs[])(struct bt_object *) = {
116 [BT_OBJECT_TYPE_NULL] = NULL,
117 [BT_OBJECT_TYPE_BOOL] = NULL,
118 [BT_OBJECT_TYPE_INTEGER] = NULL,
119 [BT_OBJECT_TYPE_FLOAT] = NULL,
120 [BT_OBJECT_TYPE_STRING] = bt_object_string_destroy,
121 [BT_OBJECT_TYPE_ARRAY] = bt_object_array_destroy,
122 [BT_OBJECT_TYPE_MAP] = bt_object_map_destroy,
123 };
124
125 static
126 struct bt_object *bt_object_null_copy(const struct bt_object *null_obj)
127 {
128 return bt_object_null;
129 }
130
131 static
132 struct bt_object *bt_object_bool_copy(const struct bt_object *bool_obj)
133 {
134 return bt_object_bool_create_init(BT_OBJECT_TO_BOOL(bool_obj)->value);
135 }
136
137 static
138 struct bt_object *bt_object_integer_copy(const struct bt_object *integer_obj)
139 {
140 return bt_object_integer_create_init(
141 BT_OBJECT_TO_INTEGER(integer_obj)->value);
142 }
143
144 static
145 struct bt_object *bt_object_float_copy(const struct bt_object *float_obj)
146 {
147 return bt_object_float_create_init(
148 BT_OBJECT_TO_FLOAT(float_obj)->value);
149 }
150
151 static
152 struct bt_object *bt_object_string_copy(const struct bt_object *string_obj)
153 {
154 return bt_object_string_create_init(
155 BT_OBJECT_TO_STRING(string_obj)->gstr->str);
156 }
157
158 static
159 struct bt_object *bt_object_array_copy(const struct bt_object *array_obj)
160 {
161 int x;
162 int ret;
163 struct bt_object *copy_obj;
164 struct bt_object_array *typed_array_obj;
165
166 typed_array_obj = BT_OBJECT_TO_ARRAY(array_obj);
167 copy_obj = bt_object_array_create();
168
169 if (!copy_obj) {
170 goto end;
171 }
172
173 for (x = 0; x < typed_array_obj->garray->len; ++x) {
174 struct bt_object *element_obj_copy;
175 struct bt_object *element_obj =
176 bt_object_array_get(array_obj, x);
177
178 if (!element_obj) {
179 BT_OBJECT_PUT(copy_obj);
180 goto end;
181 }
182
183 element_obj_copy = bt_object_copy(element_obj);
184 BT_OBJECT_PUT(element_obj);
185
186 if (!element_obj_copy) {
187 BT_OBJECT_PUT(copy_obj);
188 goto end;
189 }
190
191 ret = bt_object_array_append(copy_obj, element_obj_copy);
192 BT_OBJECT_PUT(element_obj_copy);
193
194 if (ret) {
195 BT_OBJECT_PUT(copy_obj);
196 goto end;
197 }
198 }
199
200 end:
201 return copy_obj;
202 }
203
204 static
205 struct bt_object *bt_object_map_copy(const struct bt_object *map_obj)
206 {
207 int ret;
208 GHashTableIter iter;
209 gpointer key, element_obj;
210 struct bt_object *copy_obj;
211 struct bt_object *element_obj_copy;
212 struct bt_object_map *typed_map_obj;
213
214 typed_map_obj = BT_OBJECT_TO_MAP(map_obj);
215 copy_obj = bt_object_map_create();
216
217 if (!copy_obj) {
218 goto end;
219 }
220
221 g_hash_table_iter_init(&iter, typed_map_obj->ght);
222
223 while (g_hash_table_iter_next(&iter, &key, &element_obj)) {
224 const char *key_str = g_quark_to_string((unsigned long) key);
225
226 element_obj_copy = bt_object_copy(element_obj);
227
228 if (!element_obj_copy) {
229 BT_OBJECT_PUT(copy_obj);
230 goto end;
231 }
232
233 ret = bt_object_map_insert(copy_obj, key_str, element_obj_copy);
234 BT_OBJECT_PUT(element_obj_copy);
235
236 if (ret) {
237 BT_OBJECT_PUT(copy_obj);
238 goto end;
239 }
240 }
241
242 end:
243 return copy_obj;
244 }
245
246 static
247 struct bt_object *(* const copy_funcs[])(const struct bt_object *) = {
248 [BT_OBJECT_TYPE_NULL] = bt_object_null_copy,
249 [BT_OBJECT_TYPE_BOOL] = bt_object_bool_copy,
250 [BT_OBJECT_TYPE_INTEGER] = bt_object_integer_copy,
251 [BT_OBJECT_TYPE_FLOAT] = bt_object_float_copy,
252 [BT_OBJECT_TYPE_STRING] = bt_object_string_copy,
253 [BT_OBJECT_TYPE_ARRAY] = bt_object_array_copy,
254 [BT_OBJECT_TYPE_MAP] = bt_object_map_copy,
255 };
256
257 static
258 bool bt_object_null_compare(const struct bt_object *object_a,
259 const struct bt_object *object_b)
260 {
261 /*
262 * Always true since bt_object_compare() already checks if both
263 * object_a and object_b have the same type, and in the case of
264 * null objects, they're always the same if it is so.
265 */
266 return true;
267 }
268
269 static
270 bool bt_object_bool_compare(const struct bt_object *object_a,
271 const struct bt_object *object_b)
272 {
273 return BT_OBJECT_TO_BOOL(object_a)->value ==
274 BT_OBJECT_TO_BOOL(object_b)->value;
275 }
276
277 static
278 bool bt_object_integer_compare(const struct bt_object *object_a,
279 const struct bt_object *object_b)
280 {
281 return BT_OBJECT_TO_INTEGER(object_a)->value ==
282 BT_OBJECT_TO_INTEGER(object_b)->value;
283 }
284
285 static
286 bool bt_object_float_compare(const struct bt_object *object_a,
287 const struct bt_object *object_b)
288 {
289 return BT_OBJECT_TO_FLOAT(object_a)->value ==
290 BT_OBJECT_TO_FLOAT(object_b)->value;
291 }
292
293 static
294 bool bt_object_string_compare(const struct bt_object *object_a,
295 const struct bt_object *object_b)
296 {
297 return !strcmp(BT_OBJECT_TO_STRING(object_a)->gstr->str,
298 BT_OBJECT_TO_STRING(object_b)->gstr->str);
299 }
300
301 static
302 bool bt_object_array_compare(const struct bt_object *object_a,
303 const struct bt_object *object_b)
304 {
305 int x;
306 bool ret = true;
307 const struct bt_object_array *array_obj_a =
308 BT_OBJECT_TO_ARRAY(object_a);
309
310 if (bt_object_array_size(object_a) != bt_object_array_size(object_b)) {
311 ret = false;
312 goto end;
313 }
314
315 for (x = 0; x < array_obj_a->garray->len; ++x) {
316 struct bt_object *element_obj_a;
317 struct bt_object *element_obj_b;
318
319 element_obj_a = bt_object_array_get(object_a, x);
320 element_obj_b = bt_object_array_get(object_b, x);
321
322 if (!bt_object_compare(element_obj_a, element_obj_b)) {
323 BT_OBJECT_PUT(element_obj_a);
324 BT_OBJECT_PUT(element_obj_b);
325 ret = false;
326 goto end;
327 }
328
329 BT_OBJECT_PUT(element_obj_a);
330 BT_OBJECT_PUT(element_obj_b);
331 }
332
333 end:
334 return ret;
335 }
336
337 static
338 bool bt_object_map_compare(const struct bt_object *object_a,
339 const struct bt_object *object_b)
340 {
341 bool ret = true;
342 GHashTableIter iter;
343 gpointer key, element_obj_a;
344 const struct bt_object_map *map_obj_a = BT_OBJECT_TO_MAP(object_a);
345
346 if (bt_object_map_size(object_a) != bt_object_map_size(object_b)) {
347 ret = false;
348 goto end;
349 }
350
351 g_hash_table_iter_init(&iter, map_obj_a->ght);
352
353 while (g_hash_table_iter_next(&iter, &key, &element_obj_a)) {
354 struct bt_object *element_obj_b;
355 const char *key_str = g_quark_to_string((unsigned long) key);
356
357 element_obj_b = bt_object_map_get(object_b, key_str);
358
359 if (!bt_object_compare(element_obj_a, element_obj_b)) {
360 BT_OBJECT_PUT(element_obj_b);
361 ret = false;
362 goto end;
363 }
364
365 BT_OBJECT_PUT(element_obj_b);
366 }
367
368 end:
369 return ret;
370 }
371
372 static
373 bool (* const compare_funcs[])(const struct bt_object *,
374 const struct bt_object *) = {
375 [BT_OBJECT_TYPE_NULL] = bt_object_null_compare,
376 [BT_OBJECT_TYPE_BOOL] = bt_object_bool_compare,
377 [BT_OBJECT_TYPE_INTEGER] = bt_object_integer_compare,
378 [BT_OBJECT_TYPE_FLOAT] = bt_object_float_compare,
379 [BT_OBJECT_TYPE_STRING] = bt_object_string_compare,
380 [BT_OBJECT_TYPE_ARRAY] = bt_object_array_compare,
381 [BT_OBJECT_TYPE_MAP] = bt_object_map_compare,
382 };
383
384 static
385 void bt_object_destroy(struct bt_ctf_ref *ref_count)
386 {
387 struct bt_object *object;
388
389 object = container_of(ref_count, struct bt_object, ref_count);
390 assert(object->type != BT_OBJECT_TYPE_UNKNOWN);
391
392 if (bt_object_is_null(object)) {
393 return;
394 }
395
396 if (destroy_funcs[object->type]) {
397 destroy_funcs[object->type](object);
398 }
399
400 g_free(object);
401 }
402
403 void bt_object_get(struct bt_object *object)
404 {
405 if (!object) {
406 goto skip;
407 }
408
409 bt_ctf_ref_get(&object->ref_count);
410
411 skip:
412 return;
413 }
414
415 void bt_object_put(struct bt_object *object)
416 {
417 if (!object) {
418 goto skip;
419 }
420
421 bt_ctf_ref_put(&object->ref_count, bt_object_destroy);
422
423 skip:
424 return;
425 }
426
427 enum bt_object_type bt_object_get_type(const struct bt_object *object)
428 {
429 if (!object) {
430 return BT_OBJECT_TYPE_UNKNOWN;
431 }
432
433 return object->type;
434 }
435
436 static
437 struct bt_object bt_object_create_base(enum bt_object_type type)
438 {
439 struct bt_object base;
440
441 base.type = type;
442 bt_ctf_ref_init(&base.ref_count);
443
444 return base;
445 }
446
447 struct bt_object *bt_object_bool_create_init(bool val)
448 {
449 struct bt_object_bool *bool_obj;
450
451 bool_obj = g_new0(struct bt_object_bool, 1);
452
453 if (!bool_obj) {
454 goto end;
455 }
456
457 bool_obj->base = bt_object_create_base(BT_OBJECT_TYPE_BOOL);
458 bool_obj->value = val;
459
460 end:
461 return BT_OBJECT_FROM_CONCRETE(bool_obj);
462 }
463
464 struct bt_object *bt_object_bool_create(void)
465 {
466 return bt_object_bool_create_init(false);
467 }
468
469 struct bt_object *bt_object_integer_create_init(int64_t val)
470 {
471 struct bt_object_integer *integer_obj;
472
473 integer_obj = g_new0(struct bt_object_integer, 1);
474
475 if (!integer_obj) {
476 goto end;
477 }
478
479 integer_obj->base = bt_object_create_base(BT_OBJECT_TYPE_INTEGER);
480 integer_obj->value = val;
481
482 end:
483 return BT_OBJECT_FROM_CONCRETE(integer_obj);
484 }
485
486 struct bt_object *bt_object_integer_create(void)
487 {
488 return bt_object_integer_create_init(0);
489 }
490
491 struct bt_object *bt_object_float_create_init(double val)
492 {
493 struct bt_object_float *float_obj;
494
495 float_obj = g_new0(struct bt_object_float, 1);
496
497 if (!float_obj) {
498 goto end;
499 }
500
501 float_obj->base = bt_object_create_base(BT_OBJECT_TYPE_FLOAT);
502 float_obj->value = val;
503
504 end:
505 return BT_OBJECT_FROM_CONCRETE(float_obj);
506 }
507
508 struct bt_object *bt_object_float_create(void)
509 {
510 return bt_object_float_create_init(0.);
511 }
512
513 struct bt_object *bt_object_string_create_init(const char *val)
514 {
515 struct bt_object_string *string_obj = NULL;
516
517 if (!val) {
518 goto end;
519 }
520
521 string_obj = g_new0(struct bt_object_string, 1);
522
523 if (!string_obj) {
524 goto end;
525 }
526
527 string_obj->base = bt_object_create_base(BT_OBJECT_TYPE_STRING);
528 string_obj->gstr = g_string_new(val);
529
530 if (!string_obj->gstr) {
531 g_free(string_obj);
532 string_obj = NULL;
533 goto end;
534 }
535
536 end:
537 return BT_OBJECT_FROM_CONCRETE(string_obj);
538 }
539
540 struct bt_object *bt_object_string_create(void)
541 {
542 return bt_object_string_create_init("");
543 }
544
545 struct bt_object *bt_object_array_create(void)
546 {
547 struct bt_object_array *array_obj;
548
549 array_obj = g_new0(struct bt_object_array, 1);
550
551 if (!array_obj) {
552 goto end;
553 }
554
555 array_obj->base = bt_object_create_base(BT_OBJECT_TYPE_ARRAY);
556 array_obj->garray = g_ptr_array_new_full(0,
557 (GDestroyNotify) bt_object_put);
558
559 if (!array_obj->garray) {
560 g_free(array_obj);
561 array_obj = NULL;
562 goto end;
563 }
564
565 end:
566 return BT_OBJECT_FROM_CONCRETE(array_obj);
567 }
568
569 struct bt_object *bt_object_map_create(void)
570 {
571 struct bt_object_map *map_obj;
572
573 map_obj = g_new0(struct bt_object_map, 1);
574
575 if (!map_obj) {
576 goto end;
577 }
578
579 map_obj->base = bt_object_create_base(BT_OBJECT_TYPE_MAP);
580 map_obj->ght = g_hash_table_new_full(g_direct_hash, g_direct_equal,
581 NULL, (GDestroyNotify) bt_object_put);
582
583 if (!map_obj->ght) {
584 g_free(map_obj);
585 map_obj = NULL;
586 goto end;
587 }
588
589 end:
590 return BT_OBJECT_FROM_CONCRETE(map_obj);
591 }
592
593 int bt_object_bool_get(const struct bt_object *bool_obj, bool *val)
594 {
595 int ret = 0;
596 struct bt_object_bool *typed_bool_obj = BT_OBJECT_TO_BOOL(bool_obj);
597
598 if (!bool_obj || !bt_object_is_bool(bool_obj)) {
599 ret = -1;
600 goto end;
601 }
602
603 *val = typed_bool_obj->value;
604
605 end:
606 return ret;
607 }
608
609 int bt_object_bool_set(struct bt_object *bool_obj, bool val)
610 {
611 int ret = 0;
612 struct bt_object_bool *typed_bool_obj = BT_OBJECT_TO_BOOL(bool_obj);
613
614 if (!bool_obj || !bt_object_is_bool(bool_obj)) {
615 ret = -1;
616 goto end;
617 }
618
619 typed_bool_obj->value = val;
620
621 end:
622 return ret;
623 }
624
625 int bt_object_integer_get(const struct bt_object *integer_obj, int64_t *val)
626 {
627 int ret = 0;
628 struct bt_object_integer *typed_integer_obj =
629 BT_OBJECT_TO_INTEGER(integer_obj);
630
631 if (!integer_obj || !bt_object_is_integer(integer_obj)) {
632 ret = -1;
633 goto end;
634 }
635
636 *val = typed_integer_obj->value;
637
638 end:
639 return ret;
640 }
641
642 int bt_object_integer_set(struct bt_object *integer_obj, int64_t val)
643 {
644 int ret = 0;
645 struct bt_object_integer *typed_integer_obj =
646 BT_OBJECT_TO_INTEGER(integer_obj);
647
648 if (!integer_obj || !bt_object_is_integer(integer_obj)) {
649 ret = -1;
650 goto end;
651 }
652
653 typed_integer_obj->value = val;
654
655 end:
656 return ret;
657 }
658
659 int bt_object_float_get(const struct bt_object *float_obj, double *val)
660 {
661 int ret = 0;
662 struct bt_object_float *typed_float_obj =
663 BT_OBJECT_TO_FLOAT(float_obj);
664
665 if (!float_obj || !bt_object_is_float(float_obj)) {
666 ret = -1;
667 goto end;
668 }
669
670 *val = typed_float_obj->value;
671
672 end:
673 return ret;
674 }
675
676 int bt_object_float_set(struct bt_object *float_obj, double val)
677 {
678 int ret = 0;
679 struct bt_object_float *typed_float_obj =
680 BT_OBJECT_TO_FLOAT(float_obj);
681
682 if (!float_obj || !bt_object_is_float(float_obj)) {
683 ret = -1;
684 goto end;
685 }
686
687 typed_float_obj->value = val;
688
689 end:
690 return ret;
691 }
692
693 const char *bt_object_string_get(const struct bt_object *string_obj)
694 {
695 const char *ret;
696 struct bt_object_string *typed_string_obj =
697 BT_OBJECT_TO_STRING(string_obj);
698
699 if (!string_obj || !bt_object_is_string(string_obj)) {
700 ret = NULL;
701 goto end;
702 }
703
704 ret = typed_string_obj->gstr->str;
705
706 end:
707 return ret;
708 }
709
710 int bt_object_string_set(struct bt_object *string_obj, const char *val)
711 {
712 int ret = 0;
713 struct bt_object_string *typed_string_obj =
714 BT_OBJECT_TO_STRING(string_obj);
715
716 if (!string_obj || !bt_object_is_string(string_obj) || !val) {
717 ret = -1;
718 goto end;
719 }
720
721 g_string_assign(typed_string_obj->gstr, val);
722
723 end:
724 return ret;
725 }
726
727 int bt_object_array_size(const struct bt_object *array_obj)
728 {
729 int ret = 0;
730 struct bt_object_array *typed_array_obj =
731 BT_OBJECT_TO_ARRAY(array_obj);
732
733 if (!array_obj || !bt_object_is_array(array_obj)) {
734 ret = -1;
735 goto end;
736 }
737
738 ret = (int) typed_array_obj->garray->len;
739
740 end:
741 return ret;
742 }
743
744 bool bt_object_array_is_empty(const struct bt_object *array_obj)
745 {
746 return bt_object_array_size(array_obj) == 0;
747 }
748
749 struct bt_object *bt_object_array_get(const struct bt_object *array_obj,
750 size_t index)
751 {
752 struct bt_object *ret;
753 struct bt_object_array *typed_array_obj =
754 BT_OBJECT_TO_ARRAY(array_obj);
755
756 if (!array_obj || !bt_object_is_array(array_obj) ||
757 index >= typed_array_obj->garray->len) {
758 ret = NULL;
759 goto end;
760 }
761
762 ret = g_ptr_array_index(typed_array_obj->garray, index);
763 bt_object_get(ret);
764
765 end:
766 return ret;
767 }
768
769 int bt_object_array_append(struct bt_object *array_obj,
770 struct bt_object *element_obj)
771 {
772 int ret = 0;
773 struct bt_object_array *typed_array_obj =
774 BT_OBJECT_TO_ARRAY(array_obj);
775
776 if (!array_obj || !bt_object_is_array(array_obj) || !element_obj) {
777 ret = -1;
778 goto end;
779 }
780
781 g_ptr_array_add(typed_array_obj->garray, element_obj);
782 bt_object_get(element_obj);
783
784 end:
785 return ret;
786 }
787
788 int bt_object_array_append_bool(struct bt_object *array_obj, bool val)
789 {
790 int ret;
791 struct bt_object *bool_obj = NULL;
792
793 bool_obj = bt_object_bool_create_init(val);
794 ret = bt_object_array_append(array_obj, bool_obj);
795 bt_object_put(bool_obj);
796
797 return ret;
798 }
799
800 int bt_object_array_append_integer(struct bt_object *array_obj, int64_t val)
801 {
802 int ret;
803 struct bt_object *integer_obj = NULL;
804
805 integer_obj = bt_object_integer_create_init(val);
806 ret = bt_object_array_append(array_obj, integer_obj);
807 bt_object_put(integer_obj);
808
809 return ret;
810 }
811
812 int bt_object_array_append_float(struct bt_object *array_obj, double val)
813 {
814 int ret;
815 struct bt_object *float_obj = NULL;
816
817 float_obj = bt_object_float_create_init(val);
818 ret = bt_object_array_append(array_obj, float_obj);
819 bt_object_put(float_obj);
820
821 return ret;
822 }
823
824 int bt_object_array_append_string(struct bt_object *array_obj, const char *val)
825 {
826 int ret;
827 struct bt_object *string_obj = NULL;
828
829 string_obj = bt_object_string_create_init(val);
830 ret = bt_object_array_append(array_obj, string_obj);
831 bt_object_put(string_obj);
832
833 return ret;
834 }
835
836 int bt_object_array_append_array(struct bt_object *array_obj)
837 {
838 int ret;
839 struct bt_object *empty_array_obj = NULL;
840
841 empty_array_obj = bt_object_array_create();
842 ret = bt_object_array_append(array_obj, empty_array_obj);
843 bt_object_put(empty_array_obj);
844
845 return ret;
846 }
847
848 int bt_object_array_append_map(struct bt_object *array_obj)
849 {
850 int ret;
851 struct bt_object *map_obj = NULL;
852
853 map_obj = bt_object_map_create();
854 ret = bt_object_array_append(array_obj, map_obj);
855 bt_object_put(map_obj);
856
857 return ret;
858 }
859
860 int bt_object_map_size(const struct bt_object *map_obj)
861 {
862 int ret;
863 struct bt_object_map *typed_map_obj = BT_OBJECT_TO_MAP(map_obj);
864
865 if (!map_obj || !bt_object_is_map(map_obj)) {
866 ret = -1;
867 goto end;
868 }
869
870 ret = (int) g_hash_table_size(typed_map_obj->ght);
871
872 end:
873 return ret;
874 }
875
876 bool bt_object_map_is_empty(const struct bt_object *map_obj)
877 {
878 return bt_object_map_size(map_obj) == 0;
879 }
880
881 struct bt_object *bt_object_map_get(const struct bt_object *map_obj,
882 const char *key)
883 {
884 GQuark quark;
885 struct bt_object *ret;
886 struct bt_object_map *typed_map_obj = BT_OBJECT_TO_MAP(map_obj);
887
888 if (!map_obj || !bt_object_is_map(map_obj) || !key) {
889 ret = NULL;
890 goto end;
891 }
892
893 quark = g_quark_from_string(key);
894 ret = g_hash_table_lookup(typed_map_obj->ght, GUINT_TO_POINTER(quark));
895
896 if (ret) {
897 bt_object_get(ret);
898 }
899
900 end:
901 return ret;
902 }
903
904 bool bt_object_map_has_key(const struct bt_object *map_obj, const char *key)
905 {
906 bool ret;
907 GQuark quark;
908 struct bt_object_map *typed_map_obj = BT_OBJECT_TO_MAP(map_obj);
909
910 if (!map_obj || !bt_object_is_map(map_obj) || !key) {
911 ret = false;
912 goto end;
913 }
914
915 quark = g_quark_from_string(key);
916 ret = g_hash_table_contains(typed_map_obj->ght,
917 GUINT_TO_POINTER(quark));
918
919 end:
920 return ret;
921 }
922
923 int bt_object_map_insert(struct bt_object *map_obj, const char *key,
924 struct bt_object *element_obj)
925 {
926 int ret = 0;
927 GQuark quark;
928 struct bt_object_map *typed_map_obj = BT_OBJECT_TO_MAP(map_obj);
929
930 if (!map_obj || !bt_object_is_map(map_obj) || !key || !element_obj) {
931 ret = -1;
932 goto end;
933 }
934
935 quark = g_quark_from_string(key);
936 g_hash_table_insert(typed_map_obj->ght,
937 GUINT_TO_POINTER(quark), element_obj);
938 bt_object_get(element_obj);
939
940 end:
941 return ret;
942 }
943
944 int bt_object_map_insert_bool(struct bt_object *map_obj,
945 const char *key, bool val)
946 {
947 int ret;
948 struct bt_object *bool_obj = NULL;
949
950 bool_obj = bt_object_bool_create_init(val);
951 ret = bt_object_map_insert(map_obj, key, bool_obj);
952 bt_object_put(bool_obj);
953
954 return ret;
955 }
956
957 int bt_object_map_insert_integer(struct bt_object *map_obj,
958 const char *key, int64_t val)
959 {
960 int ret;
961 struct bt_object *integer_obj = NULL;
962
963 integer_obj = bt_object_integer_create_init(val);
964 ret = bt_object_map_insert(map_obj, key, integer_obj);
965 bt_object_put(integer_obj);
966
967 return ret;
968 }
969
970 int bt_object_map_insert_float(struct bt_object *map_obj,
971 const char *key, double val)
972 {
973 int ret;
974 struct bt_object *float_obj = NULL;
975
976 float_obj = bt_object_float_create_init(val);
977 ret = bt_object_map_insert(map_obj, key, float_obj);
978 bt_object_put(float_obj);
979
980 return ret;
981 }
982
983 int bt_object_map_insert_string(struct bt_object *map_obj,
984 const char *key, const char *val)
985 {
986 int ret;
987 struct bt_object *string_obj = NULL;
988
989 string_obj = bt_object_string_create_init(val);
990 ret = bt_object_map_insert(map_obj, key, string_obj);
991 bt_object_put(string_obj);
992
993 return ret;
994 }
995
996 int bt_object_map_insert_array(struct bt_object *map_obj,
997 const char *key)
998 {
999 int ret;
1000 struct bt_object *array_obj = NULL;
1001
1002 array_obj = bt_object_array_create();
1003 ret = bt_object_map_insert(map_obj, key, array_obj);
1004 bt_object_put(array_obj);
1005
1006 return ret;
1007 }
1008
1009 int bt_object_map_insert_map(struct bt_object *map_obj,
1010 const char *key)
1011 {
1012 int ret;
1013 struct bt_object *empty_map_obj = NULL;
1014
1015 empty_map_obj = bt_object_map_create();
1016 ret = bt_object_map_insert(map_obj, key, empty_map_obj);
1017 bt_object_put(empty_map_obj);
1018
1019 return ret;
1020 }
1021
1022 int bt_object_map_foreach(const struct bt_object *map_obj,
1023 bt_object_map_foreach_cb cb, void *data)
1024 {
1025 int ret = 0;
1026 gpointer key, element_obj;
1027 GHashTableIter iter;
1028 struct bt_object_map *typed_map_obj = BT_OBJECT_TO_MAP(map_obj);
1029
1030 if (!map_obj || !bt_object_is_map(map_obj) || !cb) {
1031 ret = -1;
1032 goto end;
1033 }
1034
1035 g_hash_table_iter_init(&iter, typed_map_obj->ght);
1036
1037 while (g_hash_table_iter_next(&iter, &key, &element_obj)) {
1038 const char *key_str = g_quark_to_string((unsigned long) key);
1039
1040 if (!cb(key_str, element_obj, data)) {
1041 break;
1042 }
1043 }
1044
1045 end:
1046 return ret;
1047 }
1048
1049 struct bt_object *bt_object_copy(const struct bt_object *object)
1050 {
1051 struct bt_object *copy_obj = NULL;
1052
1053 if (!object) {
1054 goto end;
1055 }
1056
1057 copy_obj = copy_funcs[object->type](object);
1058
1059 end:
1060 return copy_obj;
1061 }
1062
1063 bool bt_object_compare(const struct bt_object *object_a,
1064 const struct bt_object *object_b)
1065 {
1066 bool ret = false;
1067
1068 if (!object_a || !object_b) {
1069 goto end;
1070 }
1071
1072 if (object_a->type != object_b->type) {
1073 goto end;
1074 }
1075
1076 ret = compare_funcs[object_a->type](object_a, object_b);
1077
1078 end:
1079 return ret;
1080 }
This page took 0.054641 seconds and 5 git commands to generate.