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