GCC Code Coverage Report


Directory: src/gate/
File: src/gate/wrappers.c
Date: 2025-09-14 13:10:38
Exec Total Coverage
Lines: 111 167 66.5%
Functions: 15 22 68.2%
Branches: 31 65 47.7%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 #include "gate/wrappers.h"
30 #include "gate/memalloc.h"
31 #include "gate/results.h"
32 #include "gate/atomics.h"
33 #include "gate/typeids.h"
34 #include "gate/strings.h"
35 #include "gate/arrays.h"
36 #include "gate/blobs.h"
37 #include "gate/structs.h"
38 #include "gate/objects.h"
39 #include "gate/properties.h"
40
41
42 12 gate_bool_t gate_wrapper_type_info_init(gate_wrapper_type_info_t* ptr_info, gate_type_id_t from_type_id)
43 {
44
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (!ptr_info)
45 {
46 return false;
47 }
48
49 12 ptr_info->size = gate_type_length(from_type_id);
50 12 ptr_info->type_descriptor = gate_type_signature(from_type_id);
51 12 ptr_info->cctor = NULL;
52 12 ptr_info->dtor = NULL;
53
54
2/7
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 11 times.
12 switch (from_type_id)
55 {
56 1 case GATE_TYPE_STRING:
57 1 ptr_info->cctor = &gate_string_copy_constructor;
58 1 ptr_info->dtor = &gate_string_destructor;
59 1 break;
60 case GATE_TYPE_ARRAY:
61 ptr_info->cctor = &gate_array_copy_constructor;
62 ptr_info->dtor = &gate_array_destructor;
63 break;
64 case GATE_TYPE_BLOB:
65 ptr_info->cctor = &gate_blob_copy_constructor;
66 ptr_info->dtor = &gate_blob_destructor;
67 break;
68 case GATE_TYPE_STRUCT:
69 ptr_info->cctor = &gate_struct_copy_constructor;
70 ptr_info->dtor = &gate_struct_destructor;
71 break;
72 case GATE_TYPE_OBJECT:
73 ptr_info->cctor = &gate_object_ptr_copyctor;
74 ptr_info->dtor = &gate_object_ptr_dtor;
75 break;
76 case GATE_TYPE_PROPERTY:
77 ptr_info->cctor = &gate_property_copy_constructor;
78 ptr_info->dtor = &gate_property_destructor;
79 break;
80 11 default:
81 {
82
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (from_type_id & GATE_TYPE_ARRAYLIST)
83 {
84 ptr_info->cctor = &gate_arraylist_copy_constructor;
85 ptr_info->dtor = &gate_arraylist_destructor;
86 break;
87 }
88 }
89 }
90
91
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
12 return (ptr_info->type_descriptor || ptr_info->size || ptr_info->cctor || ptr_info->dtor);
92 }
93
94 typedef struct gate_wrapper_impl_class
95 {
96 GATE_INTERFACE_VTBL(gate_wrapper) const* vtbl;
97 gate_atomic_int_t ref_counter;
98 gate_mem_dtor_t dtor; /* destructor of object content */
99 gate_mem_dtor_t dtor_mem; /* destructor of object memory ('free'-function) */
100 gate_size_t sz;
101 void const* type;
102 void* ptr;
103 gate_c_maxalign_t obj;
104 } gate_wrapper_impl_t;
105
106 static char const* gate_wrapper_get_interface_name_impl(void* obj)
107 {
108 (void)obj;
109 return GATE_INTERFACE_NAME_WRAPPER;
110 }
111 7 static void gate_wrapper_release_impl(void* obj)
112 {
113 7 gate_wrapper_impl_t* wrapper = (gate_wrapper_impl_t*)obj;
114
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 5 times.
7 if (0 == gate_atomic_int_dec(&wrapper->ref_counter))
115 {
116 2 gate_mem_destruct(wrapper->ptr, wrapper->dtor);
117
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (wrapper->dtor_mem)
118 {
119 wrapper->dtor_mem(wrapper->ptr);
120 }
121 2 gate_mem_dealloc(wrapper);
122 }
123 7 }
124 5 static int gate_wrapper_retain_impl(void* obj)
125 {
126 5 gate_wrapper_impl_t* wrapper = (gate_wrapper_impl_t*)obj;
127 5 return gate_atomic_int_inc(&wrapper->ref_counter);
128 }
129
130 static gate_size_t gate_wrapper_get_size_impl(void* obj)
131 {
132 gate_wrapper_impl_t* wrapper = (gate_wrapper_impl_t*)obj;
133 return wrapper->sz;
134 }
135
136 2 static void* gate_wrapper_get_content_impl(void* obj)
137 {
138 2 gate_wrapper_impl_t* wrapper = (gate_wrapper_impl_t*)obj;
139 2 return wrapper->ptr;
140 }
141
142
143 static void const* gate_wrapper_get_type_impl(void* obj)
144 {
145 gate_wrapper_impl_t* wrapper = (gate_wrapper_impl_t*)obj;
146 return wrapper->type;
147 }
148 static gate_bool_t gate_wrapper_is_type_impl(void* obj, void const* compare_with)
149 {
150 gate_wrapper_impl_t* wrapper = (gate_wrapper_impl_t*)obj;
151 return wrapper->type == compare_with;
152 }
153
154 static GATE_INTERFACE_VTBL(gate_wrapper) gate_wrapper_vtbl;
155 2 static void gate_init_wrapper_vtbl()
156 {
157
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (!gate_wrapper_vtbl.get_interface_name)
158 {
159 GATE_INTERFACE_VTBL(gate_wrapper) const local_vtbl =
160 {
161 &gate_wrapper_get_interface_name_impl,
162 &gate_wrapper_release_impl,
163 &gate_wrapper_retain_impl,
164
165 &gate_wrapper_get_size_impl,
166 &gate_wrapper_get_content_impl,
167
168 &gate_wrapper_get_type_impl,
169 &gate_wrapper_is_type_impl
170 };
171 2 gate_wrapper_vtbl = local_vtbl;
172 }
173 2 }
174
175
176 2 gate_wrapper_t* gate_wrapper_create_new(gate_size_t obj_size, void const* type, gate_mem_dtor_t dtor)
177 {
178 2 gate_wrapper_impl_t* wrapper = (gate_wrapper_impl_t*)gate_mem_alloc(sizeof(gate_wrapper_impl_t) + obj_size);
179
180
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (wrapper)
181 {
182 2 gate_mem_clear(wrapper, sizeof(gate_wrapper_impl_t) + obj_size);
183 2 gate_init_wrapper_vtbl();
184 2 wrapper->vtbl = &gate_wrapper_vtbl;
185 2 gate_atomic_int_init(&wrapper->ref_counter, 1);
186 2 wrapper->sz = obj_size;
187 2 wrapper->type = type;
188 2 wrapper->dtor = dtor;
189 2 wrapper->dtor_mem = NULL; /* object is part of wrapper, no external mem-free */
190 2 wrapper->ptr = &wrapper->obj; /* object is part of wrapper */
191 }
192
193 2 return (gate_wrapper_t*)wrapper;
194 }
195 2 gate_wrapper_t* gate_wrapper_create(void* obj, gate_size_t obj_size, void const* type, gate_mem_dtor_t dtor_obj, gate_mem_dtor_t dtor_mem)
196 {
197 2 gate_wrapper_impl_t* wrapper = (gate_wrapper_impl_t*)gate_wrapper_create_new(0, type, dtor_obj);
198
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (wrapper)
199 {
200 2 wrapper->ptr = obj; /* object is referenced by external pointer */
201 2 wrapper->sz = obj_size;
202 2 wrapper->dtor_mem = dtor_mem; /* external mem-free required */
203 }
204 2 return (gate_wrapper_t*)wrapper;
205 }
206
207 gate_wrapper_t* gate_wrapper_create_type(gate_wrapper_type_info_t const* type_info, void const* src)
208 {
209 gate_wrapper_impl_t* wrapper = (gate_wrapper_impl_t*)gate_wrapper_create_new(type_info->size, type_info->type_descriptor, type_info->dtor);
210 gate_result_t result;
211 if (wrapper != NULL)
212 {
213 result = gate_mem_copy_construct(wrapper->ptr, src, type_info->size, type_info->cctor);
214 if (GATE_FAILED(result))
215 {
216 gate_mem_dealloc(wrapper);
217 wrapper = NULL;
218 }
219 }
220 return (gate_wrapper_t*)wrapper;
221 }
222
223
224
225
226
227 typedef struct gate_variant_impl_class
228 {
229 GATE_INTERFACE_VTBL(gate_variant) const* vtbl;
230 gate_atomic_int_t ref_counter;
231 void* ptr_content;
232 gate_wrapper_type_info_t* ptr_type;
233 gate_size_t type_infos_count;
234 gate_wrapper_type_info_t type_infos[1];
235 } gate_variant_impl_t;
236
237 static char const* gate_variant_get_interface_name_impl(void* obj)
238 {
239 (void)obj;
240 return GATE_INTERFACE_NAME_VARIANT;
241 }
242 2 static void gate_variant_release_impl(void* obj)
243 {
244 2 gate_variant_impl_t* self = (gate_variant_impl_t*)obj;
245
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
2 if (0 == gate_atomic_int_dec(&self->ref_counter))
246 {
247
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 if (self->ptr_type && self->ptr_type->dtor)
248 {
249 1 self->ptr_type->dtor(self->ptr_content);
250 }
251 1 gate_mem_dealloc(self);
252 }
253 2 }
254 1 static int gate_variant_retain_impl(void* obj)
255 {
256 1 gate_variant_impl_t* self = (gate_variant_impl_t*)obj;
257 1 return gate_atomic_int_inc(&self->ref_counter);
258 }
259
260 12 static gate_size_t gate_variant_get_size_impl(void* obj)
261 {
262 12 gate_variant_impl_t* self = (gate_variant_impl_t*)obj;
263
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (self->ptr_type)
264 {
265 12 return self->ptr_type->size;
266 }
267 return 0;
268 }
269 12 static void* gate_variant_get_content_impl(void* obj)
270 {
271 12 gate_variant_impl_t* self = (gate_variant_impl_t*)obj;
272 12 return self->ptr_content;
273 }
274
275 12 static void const* gate_variant_get_type_impl(void* obj)
276 {
277 12 gate_variant_impl_t* self = (gate_variant_impl_t*)obj;
278
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (self->ptr_type)
279 {
280 12 return self->ptr_type->type_descriptor;
281 }
282 return NULL;
283 }
284 static gate_bool_t gate_variant_is_type_impl(void* obj, void const* compare_with)
285 {
286 gate_variant_impl_t* self = (gate_variant_impl_t*)obj;
287 if (self->ptr_type)
288 {
289 return compare_with == self->ptr_type->type_descriptor;
290 }
291 return false;
292 }
293
294 12 static gate_result_t gate_variant_set_content_impl(void* obj, void const* ptr_content, gate_size_t size, void const* ptr_type)
295 {
296 12 gate_variant_impl_t* self = (gate_variant_impl_t*)obj;
297 12 gate_result_t ret = GATE_RESULT_INCORRECTTYPE;
298 gate_size_t ndx;
299 gate_wrapper_type_info_t* ptr_type_info;
300
301
1/2
✓ Branch 0 taken 78 times.
✗ Branch 1 not taken.
78 for (ndx = 0; ndx != self->type_infos_count; ++ndx)
302 {
303 78 ptr_type_info = &self->type_infos[ndx];
304
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 56 times.
78 if ((ptr_type_info->size == size)
305
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 10 times.
22 && (ptr_type_info->type_descriptor == ptr_type))
306 {
307
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (self->ptr_type)
308 {
309 12 gate_mem_destruct(self->ptr_content, self->ptr_type->dtor);
310 }
311 12 ret = gate_mem_copy_construct(self->ptr_content, ptr_content, ptr_type_info->size, ptr_type_info->cctor);
312
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (GATE_FAILED(ret))
313 {
314 self->ptr_type = NULL;
315 }
316 else
317 {
318 12 self->ptr_type = ptr_type_info;
319 }
320 12 break;
321 }
322 }
323 12 return ret;
324 }
325
326
327 static GATE_INTERFACE_VTBL(gate_variant) gate_variant_vtbl;
328 1 static void gate_init_variant_vtbl()
329 {
330
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (!gate_variant_vtbl.get_interface_name)
331 {
332 GATE_INTERFACE_VTBL(gate_variant) const local_vtbl =
333 {
334 &gate_variant_get_interface_name_impl,
335 &gate_variant_release_impl,
336 &gate_variant_retain_impl,
337
338 &gate_variant_get_size_impl,
339 &gate_variant_get_content_impl,
340
341 &gate_variant_get_type_impl,
342 &gate_variant_is_type_impl,
343
344 &gate_variant_set_content_impl
345 };
346 1 gate_variant_vtbl = local_vtbl;
347 }
348 1 }
349
350
351 1 gate_variant_t* gate_variant_create(gate_wrapper_type_info_t const* ptr_types, gate_size_t types_count)
352 {
353 gate_size_t ndx;
354 1 gate_size_t max_content_size = 0;
355 1 gate_variant_impl_t* impl = NULL;
356 1 gate_variant_t* ret = NULL;
357
358 do
359 {
360
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 1 times.
13 for (ndx = 0; ndx != types_count; ++ndx)
361 {
362
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 7 times.
12 if (ptr_types[ndx].size > max_content_size)
363 {
364 5 max_content_size = ptr_types[ndx].size;
365 }
366 }
367
368 1 impl = (gate_variant_impl_t*)gate_mem_alloc(sizeof(gate_variant_impl_t) + sizeof(gate_wrapper_type_info_t) * types_count + max_content_size);
369
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!impl)
370 {
371 break;
372 }
373 1 gate_mem_clear(impl, sizeof(gate_variant_impl_t));
374 1 gate_init_variant_vtbl();
375 1 impl->vtbl = &gate_variant_vtbl;
376 1 gate_atomic_int_init(&impl->ref_counter, 1);
377 1 gate_mem_copy(&impl->type_infos[0], ptr_types, sizeof(gate_wrapper_type_info_t) * types_count);
378 1 impl->ptr_content = &impl->type_infos[types_count];
379 1 impl->ptr_type = &impl->type_infos[0];
380 1 impl->type_infos_count = types_count;
381 1 ret = (gate_variant_t*)impl;
382 1 impl = NULL;
383 } while (0);
384
385
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (impl != NULL)
386 {
387 gate_object_release(impl);
388 }
389 1 return ret;
390 }
391