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 |