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