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