1 /*
2  * Copyright (C) 2019-2021 Alexandros Theodotou <alex at zrythm dot org>
3  *
4  * This file is part of Zrythm
5  *
6  * Zrythm is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Affero General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Zrythm is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Affero General Public License for more details.
15  *
16  * You should have received a copy of the GNU Affero General Public License
17  * along with Zrythm.  If not, see <https://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef __UTILS_OBJECTS_H__
21 #define __UTILS_OBJECTS_H__
22 
23 #include <stddef.h>
24 
25 /**
26  * @addtogroup utils
27  *
28  * @{
29  */
30 
31 /**
32  * Allocates memory for an object of type \ref type.
33  */
34 #define object_new(type) \
35   g_malloc0 (sizeof (type))
36 
37 /**
38  * Calloc equivalent.
39  */
40 #define object_new_n_sizeof(n,sz) \
41   g_malloc0_n (n, sz)
42 
43 /**
44  * Calloc \ref n blocks for type \ref type.
45  */
46 #define object_new_n(n,type) \
47   object_new_n_sizeof (n, sizeof (type))
48 
49 #define object_realloc_n_sizeof(obj,prev_sz,sz) \
50   realloc_zero (obj, prev_sz, sz)
51 
52 /**
53  * Reallocate memory for \ref obj.
54  *
55  * @param prev_n Previous number of blocks.
56  * @param n New number of blocks.
57  */
58 #define object_realloc_n(obj,prev_n,n,type) \
59   object_realloc_n_sizeof ( \
60     obj, prev_n * sizeof (type), n * sizeof (type))
61 
62 /**
63  * Zero's out the struct pointed to by \ref ptr.
64  *
65  * @param ptr A pointer to a struct.
66  */
67 #define object_set_to_zero(ptr) \
68  memset (ptr, 0, sizeof (*(ptr)))
69 
70 NONNULL
71 void
72 _object_zero_and_free (
73   void ** ptr,
74   size_t  sz);
75 
76 /**
77  * Zero's out a struct pointed to by \ref ptr and
78  * frees the object.
79  */
80 #define object_zero_and_free(ptr) \
81   _object_zero_and_free ( \
82     (void **) &(ptr), sizeof (*(ptr)))
83 
84 /**
85  * Call the function \ref _func to free \ref _obj
86  * and set \ref _obj to NULL.
87  */
88 #define object_free_w_func_and_null(_func,_obj) \
89   if (_obj) { _func (_obj); _obj = NULL; }
90 
91 #define object_zero_and_free_if_nonnull(ptr) \
92   object_free_w_func_and_null ( \
93     object_zero_and_free, ptr)
94 
95 /** Convenience wrapper. */
96 #define g_object_unref_and_null(ptr) \
97   object_free_w_func_and_null (g_object_unref, ptr)
98 
99 /** Convenience wrapper. */
100 #define g_free_and_null(ptr) \
101   object_free_w_func_and_null (g_free, ptr)
102 
103 /** Convenience wrapper. */
104 #define g_error_free_and_null(ptr) \
105   object_free_w_func_and_null (g_error_free, ptr)
106 
107 /** Convenience wrapper. */
108 #define object_free_w_func_and_null_cast(\
109   _func,_cast,_obj) \
110   if (_obj) { _func ((_cast)_obj); _obj = NULL; }
111 
112 #define g_source_remove_and_zero(src_id) \
113   { g_source_remove (src_id); src_id = 0; }
114 
115 /**
116  * @}
117  */
118 
119 #endif
120