GCC Code Coverage Report


Directory: src/gate/
File: src/gate/structs.c
Date: 2025-09-14 13:10:38
Exec Total Coverage
Lines: 57 178 32.0%
Functions: 10 18 55.6%
Branches: 17 87 19.5%

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 #include "gate/structs.h"
29 #include "gate/results.h"
30 #include "gate/objects.h"
31 #include "gate/arrays.h"
32 #include "gate/guids.h"
33 #include "gate/times.h"
34 #include "gate/blobs.h"
35 #include "gate/utilities.h"
36 #include "gate/properties.h"
37
38
39 gate_result_t gate_struct_item_init(gate_uint16_t type, void* ptr)
40 {
41 gate_result_t ret = GATE_RESULT_OK;
42 gate_size_t type_length = gate_type_length(type);
43
44 switch (type)
45 {
46 case GATE_TYPE_ARRAYLIST_BOOL: *((gate_arraylist_t*)(ptr)) = gate_arraylist_create(sizeof(gate_bool_t), NULL, 0, NULL, NULL); break;
47 case GATE_TYPE_ARRAYLIST_I8: *((gate_arraylist_t*)(ptr)) = gate_arraylist_create(sizeof(gate_int8_t), NULL, 0, NULL, NULL); break;
48 case GATE_TYPE_ARRAYLIST_UI8: *((gate_arraylist_t*)(ptr)) = gate_arraylist_create(sizeof(gate_uint8_t), NULL, 0, NULL, NULL); break;
49 case GATE_TYPE_ARRAYLIST_I16: *((gate_arraylist_t*)(ptr)) = gate_arraylist_create(sizeof(gate_int16_t), NULL, 0, NULL, NULL); break;
50 case GATE_TYPE_ARRAYLIST_UI16: *((gate_arraylist_t*)(ptr)) = gate_arraylist_create(sizeof(gate_uint16_t), NULL, 0, NULL, NULL); break;
51 case GATE_TYPE_ARRAYLIST_I32: *((gate_arraylist_t*)(ptr)) = gate_arraylist_create(sizeof(gate_int32_t), NULL, 0, NULL, NULL); break;
52 case GATE_TYPE_ARRAYLIST_UI32: *((gate_arraylist_t*)(ptr)) = gate_arraylist_create(sizeof(gate_uint32_t), NULL, 0, NULL, NULL); break;
53 case GATE_TYPE_ARRAYLIST_I64: *((gate_arraylist_t*)(ptr)) = gate_arraylist_create(sizeof(gate_int64_t), NULL, 0, NULL, NULL); break;
54 case GATE_TYPE_ARRAYLIST_UI64: *((gate_arraylist_t*)(ptr)) = gate_arraylist_create(sizeof(gate_uint64_t), NULL, 0, NULL, NULL); break;
55 case GATE_TYPE_ARRAYLIST_R32: *((gate_arraylist_t*)(ptr)) = gate_arraylist_create(sizeof(gate_real32_t), NULL, 0, NULL, NULL); break;
56 case GATE_TYPE_ARRAYLIST_R64: *((gate_arraylist_t*)(ptr)) = gate_arraylist_create(sizeof(gate_real64_t), NULL, 0, NULL, NULL); break;
57 case GATE_TYPE_ARRAYLIST_ADDRESS: *((gate_arraylist_t*)(ptr)) = gate_arraylist_create(sizeof(gate_uintptr_t), NULL, 0, NULL, NULL); break;
58
59 /* arraylist of basic gate structures (POD) */
60 case GATE_TYPE_ARRAYLIST_DATAPTR: *((gate_arraylist_t*)(ptr)) = gate_arraylist_create(sizeof(gate_dataptr_t), NULL, 0, NULL, NULL); break;
61 case GATE_TYPE_ARRAYLIST_FUNCPTR: *((gate_arraylist_t*)(ptr)) = gate_arraylist_create(sizeof(gate_funcptr_t), NULL, 0, NULL, NULL); break;
62 case GATE_TYPE_ARRAYLIST_CSTR: *((gate_arraylist_t*)(ptr)) = gate_arraylist_create(sizeof(char const*), NULL, 0, NULL, NULL); break;
63 case GATE_TYPE_ARRAYLIST_WSTR: *((gate_arraylist_t*)(ptr)) = gate_arraylist_create(sizeof(wchar_t const*), NULL, 0, NULL, NULL); break;
64 case GATE_TYPE_ARRAYLIST_GUID: *((gate_arraylist_t*)(ptr)) = gate_arraylist_create(sizeof(gate_guid_t), NULL, 0, NULL, NULL); break;
65 case GATE_TYPE_ARRAYLIST_DATE: *((gate_arraylist_t*)(ptr)) = gate_arraylist_create(sizeof(gate_date_t), NULL, 0, NULL, NULL); break;
66 case GATE_TYPE_ARRAYLIST_DAYTIME: *((gate_arraylist_t*)(ptr)) = gate_arraylist_create(sizeof(gate_daytime_t), NULL, 0, NULL, NULL); break;
67 case GATE_TYPE_ARRAYLIST_DATETIME: *((gate_arraylist_t*)(ptr)) = gate_arraylist_create(sizeof(gate_datetime_t), NULL, 0, NULL, NULL); break;
68 case GATE_TYPE_ARRAYLIST_TIME: *((gate_arraylist_t*)(ptr)) = gate_arraylist_create(sizeof(gate_time_t), NULL, 0, NULL, NULL); break;
69
70 /* arraylist of basic generic types */
71 case GATE_TYPE_ARRAYLIST_STRING: *((gate_arraylist_t*)(ptr)) = gate_util_stringarray_create(); break;
72 case GATE_TYPE_ARRAYLIST_ARRAY: *((gate_arraylist_t*)(ptr)) = NULL; break; /* must be initialized individually */
73 case GATE_TYPE_ARRAYLIST_BLOB: *((gate_arraylist_t*)(ptr)) = gate_util_blobarray_create(); break;
74
75 /* arraylist of basic reference types */
76 case GATE_TYPE_ARRAYLIST_STRUCT: *((gate_arraylist_t*)(ptr)) = NULL; break; /* must be initialized individually */
77 case GATE_TYPE_ARRAYLIST_OBJECT: *((gate_object_ptr_t*)(ptr)) = NULL; break; /* must be initialized individually */
78 case GATE_TYPE_ARRAYLIST_PROPERTY: gate_property_create_empty((gate_property_t*)(ptr)); break;
79 case GATE_TYPE_STRUCT: ((gate_struct_t*)(ptr))->struct_descriptor = NULL; break; /* must be initialized individually */
80 default:
81 {
82 gate_mem_clear(ptr, type_length);
83 break;
84 }
85 }
86 return ret;
87 }
88
89 1209 gate_result_t gate_struct_item_release(gate_uint16_t type, void* ptr)
90 {
91 1209 gate_result_t ret = GATE_RESULT_OK;
92 1209 gate_size_t type_length = gate_type_length(type);
93 gate_struct_ptr_t struct_ptr;
94
95
2/8
✗ Branch 0 not taken.
✓ Branch 1 taken 1032 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 177 times.
1209 switch (type)
96 {
97 case GATE_TYPE_STRUCT:
98 {
99 struct_ptr = *((gate_struct_ptr_t*)ptr);
100 ret = gate_struct_release(struct_ptr);
101 break;
102 }
103 1032 case GATE_TYPE_STRING:
104 {
105 1032 gate_string_release((gate_string_t*)ptr);
106 1032 break;
107 }
108 case GATE_TYPE_BLOB:
109 {
110 gate_blob_release((gate_blob_t*)ptr);
111 break;
112 }
113 case GATE_TYPE_OBJECT:
114 {
115 gate_object_release(*((gate_object_ptr_t*)ptr));
116 break;
117 }
118 case GATE_TYPE_PROPERTY:
119 {
120 gate_property_destroy((gate_property_t*)ptr);
121 break;
122 }
123 case GATE_TYPE_ARRAY:
124 {
125 gate_array_release((gate_array_t*)ptr);
126 break;
127 }
128 case GATE_TYPE_EMPTY:
129 {
130 break;
131 }
132 177 default:
133 {
134
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 175 times.
177 if (GATE_FLAG_ENABLED(type, GATE_TYPE_ARRAYLIST))
135 {
136 2 gate_arraylist_release(*(gate_arraylist_t*)ptr);
137 2 *((gate_arraylist_t*)ptr) = NULL;
138 }
139
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 175 times.
175 else if (type_length == 0)
140 {
141 ret = GATE_RESULT_FAILED;
142 }
143 else
144 {
145 175 gate_mem_clear(ptr, type_length);
146 }
147 177 break;
148 }
149 }
150 1209 return ret;
151 }
152
153
154
155 gate_result_t gate_struct_init(gate_struct_t* obj, gate_struct_descriptor_t const* descriptor)
156 {
157 gate_result_t ret = GATE_RESULT_FAILED;
158 char* obj_ptr = (char*)obj;
159 char* data_ptr;
160 size_t index;
161
162 do
163 {
164 if (obj == NULL)
165 {
166 ret = GATE_RESULT_INVALIDARG;
167 break;
168 }
169
170 if (descriptor != NULL)
171 {
172 obj->struct_descriptor = descriptor;
173 }
174 else
175 {
176 descriptor = obj->struct_descriptor;
177 }
178
179 if (obj->struct_descriptor == NULL)
180 {
181 ret = GATE_RESULT_INVALIDARG;
182 break;
183 }
184
185 ret = GATE_RESULT_OK;
186 for (index = 0; index != descriptor->item_count; ++index)
187 {
188 data_ptr = obj_ptr + descriptor->items[index].offset;
189 ret = gate_struct_item_init(descriptor->items[index].type, data_ptr);
190 if (GATE_FAILED(ret))
191 {
192 /* release all previous created data */
193 while (index != 0)
194 {
195 --index;
196 data_ptr = obj_ptr + descriptor->items[index].offset;
197 gate_struct_item_release(descriptor->items[index].type, data_ptr);
198 }
199 break;
200 }
201 }
202 } while (0);
203
204 return ret;
205 }
206
207 122 gate_result_t gate_struct_copy(gate_struct_t* dst, gate_struct_t const* src)
208 {
209 122 gate_result_t ret = GATE_RESULT_FAILED;
210 122 char* ptr_dst = (char*)dst;
211 122 char const* ptr_src = (char const*)src;
212 gate_size_t index;
213
214
1/2
✓ Branch 0 taken 122 times.
✗ Branch 1 not taken.
122 if (dst->struct_descriptor == NULL)
215 {
216 122 dst->struct_descriptor = src->struct_descriptor;
217 }
218
219 do
220 {
221
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 122 times.
122 if (dst->struct_descriptor->item_count != src->struct_descriptor->item_count)
222 {
223 ret = GATE_RESULT_INCORRECTTYPE;
224 break;
225 }
226
227 122 ret = GATE_RESULT_OK;
228
229
2/2
✓ Branch 0 taken 976 times.
✓ Branch 1 taken 122 times.
1098 for (index = 0; index != src->struct_descriptor->item_count; ++index)
230 {
231
1/2
✓ Branch 0 taken 976 times.
✗ Branch 1 not taken.
976 if (dst->struct_descriptor->items[index].type == src->struct_descriptor->items[index].type)
232 {
233 976 ret = gate_type_copy(dst->struct_descriptor->items[index].type,
234 976 ptr_dst + dst->struct_descriptor->items[index].offset,
235 976 ptr_src + src->struct_descriptor->items[index].offset);
236
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 976 times.
976 if (GATE_FAILED(ret))
237 {
238 while (index-- != 0)
239 {
240 gate_type_release(dst->struct_descriptor->items[index].type, ptr_dst + dst->struct_descriptor->items[index].offset);
241 }
242 break;
243 }
244 }
245 else
246 {
247 ret = GATE_RESULT_INCORRECTTYPE;
248 break;
249 }
250 }
251
252 } while (0);
253
254
255 122 return ret;
256 }
257
258 1 gate_size_t gate_struct_length(gate_struct_t const* src)
259 {
260 1 return src->struct_descriptor->struct_length;
261 }
262
263 1 char const* gate_struct_get_name(gate_struct_t const* src)
264 {
265 1 return src->struct_descriptor->name;
266 }
267
268 7 gate_size_t gate_struct_get_member_count(gate_struct_t const* src)
269 {
270 7 return src->struct_descriptor->item_count;
271 }
272
273 12 gate_uint16_t gate_struct_get_member_type(gate_struct_t const* src, gate_size_t index)
274 {
275
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (index >= src->struct_descriptor->item_count)
276 {
277 return 0;
278 }
279 12 return src->struct_descriptor->items[index].type;
280 }
281 gate_uint16_t gate_struct_get_member_type_by_string(gate_struct_t const* src, gate_string_t const* name)
282 {
283 gate_size_t index;
284 gate_size_t len;
285 for (index = 0; index != src->struct_descriptor->item_count; ++index)
286 {
287 len = gate_str_length(src->struct_descriptor->items[index].name);
288 if (0 == gate_str_compare(src->struct_descriptor->items[index].name, len, name->str, name->length))
289 {
290 return src->struct_descriptor->items[index].type;
291 }
292 }
293 return GATE_TYPE_EMPTY;
294 }
295 gate_uint16_t gate_struct_get_member_type_by_name(gate_struct_t const* src, char const* name)
296 {
297 gate_uint16_t type = GATE_TYPE_EMPTY;
298 gate_string_t str_name = GATE_STRING_INIT_EMPTY;
299 gate_string_create_static(&str_name, name);
300 type = gate_struct_get_member_type_by_string(src, &str_name);
301 gate_string_release(&str_name);
302 return type;
303 }
304
305
306 21 char const* gate_struct_get_member_name(gate_struct_t const* src, gate_size_t index)
307 {
308
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (index >= src->struct_descriptor->item_count)
309 {
310 return NULL;
311 }
312 21 return src->struct_descriptor->items[index].name;
313 }
314
315 12 void const* gate_struct_get_member(gate_struct_t const* src, gate_size_t index)
316 {
317
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (index >= src->struct_descriptor->item_count)
318 {
319 return NULL;
320 }
321 12 return (void const*)(((char const*)src) + src->struct_descriptor->items[index].offset);
322 }
323
324 void const* gate_struct_get_member_by_string(gate_struct_t const* src, gate_string_t const* name)
325 {
326 gate_size_t index;
327 gate_size_t len;
328 for (index = 0; index != src->struct_descriptor->item_count; ++index)
329 {
330 len = gate_str_length(src->struct_descriptor->items[index].name);
331 if (0 == gate_str_compare(src->struct_descriptor->items[index].name, len, name->str, name->length))
332 {
333 return (void const*)(((char const*)src) + src->struct_descriptor->items[index].offset);
334 }
335 }
336 return NULL;
337 }
338
339 void const* gate_struct_get_member_by_name(gate_struct_t const* src, char const* name)
340 {
341 void const* ret = NULL;
342 gate_string_t str_name = GATE_STRING_INIT_EMPTY;
343 if (NULL != gate_string_create_static(&str_name, name))
344 {
345 ret = gate_struct_get_member_by_string(src, &str_name);
346 gate_string_release(&str_name);
347 }
348 return ret;
349 }
350
351 void* gate_struct_get_mutable_member(gate_struct_t* src, gate_size_t index)
352 {
353 if (index >= src->struct_descriptor->item_count)
354 {
355 return NULL;
356 }
357 return (void*)(((char*)src) + src->struct_descriptor->items[index].offset);
358 }
359
360
361 154 gate_result_t gate_struct_release(gate_struct_ptr_t obj)
362 {
363 154 gate_result_t ret = GATE_RESULT_OK;
364 char* data_ptr;
365 154 char* obj_ptr = (char*)obj;
366 154 gate_size_t index = 0;
367
1/2
✓ Branch 0 taken 154 times.
✗ Branch 1 not taken.
154 if (obj->struct_descriptor)
368 {
369
2/2
✓ Branch 0 taken 1209 times.
✓ Branch 1 taken 154 times.
1363 for (index = 0; index != obj->struct_descriptor->item_count; ++index)
370 {
371 1209 data_ptr = obj_ptr + obj->struct_descriptor->items[index].offset;
372 1209 gate_struct_item_release(obj->struct_descriptor->items[index].type, data_ptr);
373 }
374 }
375 154 return ret;
376 }
377
378 gate_result_t gate_struct_copy_constructor(void* dest, void const* src)
379 {
380 gate_result_t result = gate_struct_copy((gate_struct_t*)dest, (gate_struct_t const*)src);
381 return result;
382 }
383
384 51 void gate_struct_destructor(void* dest)
385 {
386 51 gate_struct_release((gate_struct_ptr_t)dest);
387 51 }
388