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/properties.h" | ||
30 | #include "gate/utilities.h" | ||
31 | #include "gate/comparers.h" | ||
32 | #include "gate/results.h" | ||
33 | #include "gate/times.h" | ||
34 | #include "gate/guids.h" | ||
35 | #include "gate/mathematics.h" | ||
36 | #include "gate/structs.h" | ||
37 | |||
38 | |||
39 | 7 | gate_property_t* gate_property_create_empty(gate_property_t* obj) | |
40 | { | ||
41 | 7 | obj->value_type = GATE_PROPERTY_TYPE_EMPTY; | |
42 | 7 | gate_mem_clear(&obj->data, sizeof(obj->data)); | |
43 | 7 | return obj; | |
44 | } | ||
45 | 2 | gate_property_t* gate_property_create_bool(gate_property_t* obj, gate_bool_t value) | |
46 | { | ||
47 | 2 | obj->value_type = GATE_PROPERTY_TYPE_BOOL; | |
48 | 2 | obj->data.bool_value = value; | |
49 | 2 | return obj; | |
50 | } | ||
51 | 16 | gate_property_t* gate_property_create_int(gate_property_t* obj, gate_int64_t value) | |
52 | { | ||
53 | 16 | obj->value_type = GATE_PROPERTY_TYPE_INT; | |
54 | 16 | obj->data.int_value = value; | |
55 | 16 | return obj; | |
56 | } | ||
57 | 10 | gate_property_t* gate_property_create_real(gate_property_t* obj, gate_real64_t value) | |
58 | { | ||
59 | 10 | obj->value_type = GATE_PROPERTY_TYPE_REAL; | |
60 | 10 | obj->data.real_value = value; | |
61 | 10 | return obj; | |
62 | } | ||
63 | 152 | gate_property_t* gate_property_create_string(gate_property_t* obj, gate_string_t const* value) | |
64 | { | ||
65 | 152 | obj->value_type = GATE_PROPERTY_TYPE_STRING; | |
66 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 152 times.
|
152 | if (NULL == gate_string_duplicate(&obj->data.string_value, value)) |
67 | { | ||
68 | ✗ | obj = NULL; | |
69 | } | ||
70 | 152 | return obj; | |
71 | } | ||
72 | 2 | gate_property_t* gate_property_create_text(gate_property_t* obj, char const* value) | |
73 | { | ||
74 | 2 | obj->value_type = GATE_PROPERTY_TYPE_STRING; | |
75 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
|
2 | if (NULL == gate_string_create(&obj->data.string_value, value, gate_str_length(value))) |
76 | { | ||
77 | ✗ | obj = NULL; | |
78 | } | ||
79 | 2 | return obj; | |
80 | } | ||
81 | 12 | gate_property_t* gate_property_create_array(gate_property_t* obj, gate_property_t const* items, gate_size_t item_count) | |
82 | { | ||
83 | 12 | obj->value_type = GATE_PROPERTY_TYPE_ARRAY; | |
84 | 12 | obj->data.array_value = gate_arraylist_create(sizeof(gate_property_t), items, item_count, | |
85 | &gate_property_copy_constructor, &gate_property_destructor); | ||
86 |
1/2✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
|
12 | return (obj->data.array_value != NULL) ? obj : NULL; |
87 | } | ||
88 | 84 | gate_property_t* gate_property_create_object(gate_property_t* obj) | |
89 | { | ||
90 | 84 | gate_flatmap_t* ptr_map = gate_flatmap_create(&obj->data.object_value, &gate_compare_string, | |
91 | sizeof(gate_string_t), &gate_string_copy_constructor, &gate_string_destructor, | ||
92 | sizeof(gate_property_t), &gate_property_copy_constructor, &gate_property_destructor); | ||
93 | 84 | obj->value_type = GATE_PROPERTY_TYPE_OBJECT; | |
94 |
1/2✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
|
84 | return (ptr_map ? obj : NULL); |
95 | } | ||
96 | |||
97 | ✗ | gate_property_t* gate_property_create(gate_property_t* obj, gate_property_typeid_t value_type, void const* ptr_value) | |
98 | { | ||
99 | ✗ | gate_property_t* ret = NULL; | |
100 | ✗ | switch (value_type) | |
101 | { | ||
102 | ✗ | case GATE_PROPERTY_TYPE_EMPTY: | |
103 | { | ||
104 | ✗ | ret = gate_property_create_empty(obj); | |
105 | ✗ | break; | |
106 | } | ||
107 | ✗ | case GATE_PROPERTY_TYPE_BOOL: | |
108 | { | ||
109 | ✗ | ret = gate_property_create_bool(obj, *(gate_bool_t const*)ptr_value); | |
110 | ✗ | break; | |
111 | } | ||
112 | ✗ | case GATE_PROPERTY_TYPE_INT: | |
113 | { | ||
114 | ✗ | ret = gate_property_create_int(obj, *(gate_int64_t const*)ptr_value); | |
115 | ✗ | break; | |
116 | } | ||
117 | ✗ | case GATE_PROPERTY_TYPE_REAL: | |
118 | { | ||
119 | ✗ | ret = gate_property_create_real(obj, *(gate_real64_t const*)ptr_value); | |
120 | ✗ | break; | |
121 | } | ||
122 | ✗ | case GATE_PROPERTY_TYPE_STRING: | |
123 | { | ||
124 | ✗ | ret = gate_property_create_string(obj, (gate_string_t const*)ptr_value); | |
125 | ✗ | break; | |
126 | } | ||
127 | ✗ | case GATE_PROPERTY_TYPE_ARRAY: | |
128 | { | ||
129 | ✗ | ret = gate_property_create_array(obj, NULL, 0); | |
130 | ✗ | break; | |
131 | } | ||
132 | ✗ | case GATE_PROPERTY_TYPE_OBJECT: | |
133 | { | ||
134 | ✗ | ret = gate_property_create_object(obj); | |
135 | ✗ | break; | |
136 | } | ||
137 | } | ||
138 | ✗ | return ret; | |
139 | } | ||
140 | |||
141 | 1711 | gate_property_t* gate_property_copy(gate_property_t* dest, gate_property_t const* src) | |
142 | { | ||
143 | 1711 | gate_property_t* ret = NULL; | |
144 | 1711 | dest->value_type = src->value_type; | |
145 | |||
146 |
6/8✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 88 times.
✓ Branch 3 taken 26 times.
✓ Branch 4 taken 1073 times.
✓ Branch 5 taken 31 times.
✓ Branch 6 taken 473 times.
✗ Branch 7 not taken.
|
1711 | switch (src->value_type) |
147 | { | ||
148 | ✗ | case GATE_PROPERTY_TYPE_EMPTY: | |
149 | { | ||
150 | ✗ | ret = dest; | |
151 | ✗ | break; | |
152 | } | ||
153 | 20 | case GATE_PROPERTY_TYPE_BOOL: | |
154 | { | ||
155 | 20 | dest->data.bool_value = src->data.bool_value; | |
156 | 20 | ret = dest; | |
157 | 20 | break; | |
158 | } | ||
159 | 88 | case GATE_PROPERTY_TYPE_INT: | |
160 | { | ||
161 | 88 | dest->data.int_value = src->data.int_value; | |
162 | 88 | ret = dest; | |
163 | 88 | break; | |
164 | } | ||
165 | 26 | case GATE_PROPERTY_TYPE_REAL: | |
166 | { | ||
167 | 26 | dest->data.real_value = src->data.real_value; | |
168 | 26 | ret = dest; | |
169 | 26 | break; | |
170 | } | ||
171 | 1073 | case GATE_PROPERTY_TYPE_STRING: | |
172 | { | ||
173 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1073 times.
|
1073 | if (NULL == gate_string_duplicate(&dest->data.string_value, &src->data.string_value)) |
174 | { | ||
175 | ✗ | break; | |
176 | } | ||
177 | 1073 | ret = dest; | |
178 | 1073 | break; | |
179 | } | ||
180 | 31 | case GATE_PROPERTY_TYPE_ARRAY: | |
181 | { | ||
182 | 31 | dest->data.array_value = gate_arraylist_copy(src->data.array_value); | |
183 |
1/2✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
|
31 | if (dest->data.array_value != NULL) |
184 | { | ||
185 | 31 | ret = dest; | |
186 | } | ||
187 | 31 | break; | |
188 | } | ||
189 | 473 | case GATE_PROPERTY_TYPE_OBJECT: | |
190 | { | ||
191 |
1/2✓ Branch 1 taken 473 times.
✗ Branch 2 not taken.
|
473 | if (NULL != gate_flatmap_copy(&dest->data.object_value, &src->data.object_value)) |
192 | { | ||
193 | 473 | ret = dest; | |
194 | } | ||
195 | 473 | break; | |
196 | } | ||
197 | } | ||
198 | 1711 | return ret; | |
199 | } | ||
200 | |||
201 | 2075 | void gate_property_destroy(gate_property_t* obj) | |
202 | { | ||
203 |
4/4✓ Branch 0 taken 1227 times.
✓ Branch 1 taken 43 times.
✓ Branch 2 taken 557 times.
✓ Branch 3 taken 248 times.
|
2075 | switch (obj->value_type) |
204 | { | ||
205 | 1227 | case GATE_PROPERTY_TYPE_STRING: | |
206 | { | ||
207 | 1227 | gate_string_release(&obj->data.string_value); | |
208 | 1227 | break; | |
209 | } | ||
210 | 43 | case GATE_PROPERTY_TYPE_ARRAY: | |
211 | { | ||
212 | 43 | gate_arraylist_release(obj->data.array_value); | |
213 | 43 | break; | |
214 | } | ||
215 | 557 | case GATE_PROPERTY_TYPE_OBJECT: | |
216 | { | ||
217 | 557 | gate_flatmap_destroy(&obj->data.object_value); | |
218 | 557 | break; | |
219 | } | ||
220 | } | ||
221 | 2075 | gate_mem_clear(obj, sizeof(gate_property_t)); | |
222 | 2075 | obj->value_type = GATE_PROPERTY_TYPE_EMPTY; | |
223 | 2075 | } | |
224 | |||
225 | 1630 | gate_result_t gate_property_copy_constructor(void* dest, void const* src) | |
226 | { | ||
227 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1630 times.
|
1630 | if (NULL == gate_property_copy((gate_property_t*)dest, (gate_property_t const*)src)) |
228 | { | ||
229 | ✗ | return GATE_RESULT_OUTOFMEMORY; | |
230 | } | ||
231 | else | ||
232 | { | ||
233 | 1630 | return GATE_RESULT_OK; | |
234 | } | ||
235 | } | ||
236 | 1630 | void gate_property_destructor(void* dest) | |
237 | { | ||
238 | 1630 | gate_property_destroy(dest); | |
239 | 1630 | } | |
240 | 16 | gate_property_typeid_t gate_property_get_type(gate_property_t const* obj) | |
241 | { | ||
242 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
|
16 | if (obj == NULL) |
243 | { | ||
244 | ✗ | return GATE_PROPERTY_TYPE_EMPTY; | |
245 | } | ||
246 | else | ||
247 | { | ||
248 | 16 | return obj->value_type; | |
249 | } | ||
250 | } | ||
251 | |||
252 | 1 | gate_result_t gate_property_get_bool(gate_property_t const* obj, gate_bool_t* value) | |
253 | { | ||
254 | 1 | gate_result_t ret = GATE_RESULT_INVALIDARG; | |
255 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (value != NULL) |
256 | { | ||
257 | 1 | ret = GATE_RESULT_OK; | |
258 |
1/8✗ Branch 0 not taken.
✓ Branch 1 taken 1 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.
|
1 | switch (obj->value_type) |
259 | { | ||
260 | ✗ | case GATE_PROPERTY_TYPE_EMPTY: *value = false; break; | |
261 | 1 | case GATE_PROPERTY_TYPE_BOOL: *value = obj->data.bool_value; break; | |
262 | ✗ | case GATE_PROPERTY_TYPE_INT: *value = (obj->data.int_value != 0); break; | |
263 | ✗ | case GATE_PROPERTY_TYPE_REAL: *value = (obj->data.real_value != 0.0); break; | |
264 | ✗ | case GATE_PROPERTY_TYPE_STRING: *value = !gate_string_is_empty(&obj->data.string_value); break; | |
265 | ✗ | case GATE_PROPERTY_TYPE_ARRAY: *value = (gate_arraylist_length(obj->data.array_value) != 0); break; | |
266 | ✗ | case GATE_PROPERTY_TYPE_OBJECT: *value = (gate_flatmap_count(&obj->data.object_value) != 0); break; | |
267 | ✗ | default: *value = false; ret = GATE_RESULT_FAILED; break; | |
268 | } | ||
269 | ✗ | } | |
270 | 1 | return ret; | |
271 | } | ||
272 | 9 | gate_result_t gate_property_get_int(gate_property_t const* obj, gate_int64_t* value) | |
273 | { | ||
274 | 9 | gate_result_t ret = GATE_RESULT_INVALIDARG; | |
275 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
|
9 | if (value != NULL) |
276 | { | ||
277 | 9 | ret = GATE_RESULT_OK; | |
278 |
1/8✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
9 | switch (obj->value_type) |
279 | { | ||
280 | ✗ | case GATE_PROPERTY_TYPE_EMPTY: *value = 0; break; | |
281 | ✗ | case GATE_PROPERTY_TYPE_BOOL: *value = (obj->data.bool_value ? 1 : 0); break; | |
282 | 9 | case GATE_PROPERTY_TYPE_INT: *value = obj->data.int_value; break; | |
283 | ✗ | case GATE_PROPERTY_TYPE_REAL: *value = (gate_int64_t)obj->data.real_value; break; | |
284 | ✗ | case GATE_PROPERTY_TYPE_STRING: *value = (gate_int64_t)gate_string_length(&obj->data.string_value); break; | |
285 | ✗ | case GATE_PROPERTY_TYPE_ARRAY: *value = (gate_int64_t)gate_arraylist_length(obj->data.array_value); break; | |
286 | ✗ | case GATE_PROPERTY_TYPE_OBJECT: *value = (gate_int64_t)gate_flatmap_count(&obj->data.object_value); break; | |
287 | ✗ | default: *value = 0; ret = GATE_RESULT_FAILED; break; | |
288 | } | ||
289 | ✗ | } | |
290 | 9 | return ret; | |
291 | } | ||
292 | 5 | gate_result_t gate_property_get_real(gate_property_t const* obj, gate_real64_t* value) | |
293 | { | ||
294 | 5 | gate_result_t ret = GATE_RESULT_INVALIDARG; | |
295 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
|
5 | if (value != NULL) |
296 | { | ||
297 | 5 | ret = GATE_RESULT_OK; | |
298 |
2/8✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
5 | switch (obj->value_type) |
299 | { | ||
300 | ✗ | case GATE_PROPERTY_TYPE_EMPTY: *value = 0.0; break; | |
301 | ✗ | case GATE_PROPERTY_TYPE_BOOL: *value = (obj->data.bool_value ? 1.0 : 0.0); break; | |
302 | 1 | case GATE_PROPERTY_TYPE_INT: *value = (gate_real64_t)obj->data.int_value; break; | |
303 | 4 | case GATE_PROPERTY_TYPE_REAL: *value = (gate_real64_t)obj->data.real_value; break; | |
304 | ✗ | case GATE_PROPERTY_TYPE_STRING: *value = (gate_real64_t)gate_string_length(&obj->data.string_value); break; | |
305 | ✗ | case GATE_PROPERTY_TYPE_ARRAY: *value = (gate_real64_t)gate_arraylist_length(obj->data.array_value); break; | |
306 | ✗ | case GATE_PROPERTY_TYPE_OBJECT: *value = (gate_real64_t)gate_flatmap_count(&obj->data.object_value); break; | |
307 | ✗ | default: *value = 0; ret = GATE_RESULT_FAILED; break; | |
308 | } | ||
309 | ✗ | } | |
310 | 5 | return ret; | |
311 | } | ||
312 | 9 | gate_result_t gate_property_get_string(gate_property_t const* obj, gate_string_t* value) | |
313 | { | ||
314 | 9 | gate_result_t ret = GATE_RESULT_INVALIDARG; | |
315 | char buffer[64]; | ||
316 | 9 | gate_size_t buffer_used = 0; | |
317 | |||
318 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
|
9 | if (value != NULL) |
319 | { | ||
320 | 9 | ret = GATE_RESULT_OK; | |
321 |
1/8✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
9 | switch (obj->value_type) |
322 | { | ||
323 | ✗ | case GATE_PROPERTY_TYPE_EMPTY: | |
324 | { | ||
325 | ✗ | gate_string_create_empty(value); | |
326 | ✗ | break; | |
327 | } | ||
328 | ✗ | case GATE_PROPERTY_TYPE_BOOL: | |
329 | { | ||
330 | ✗ | if (obj->data.bool_value) | |
331 | { | ||
332 | ✗ | gate_string_create_static_len(value, "true", 4); | |
333 | } | ||
334 | else | ||
335 | { | ||
336 | ✗ | gate_string_create_static_len(value, "false", 5); | |
337 | } | ||
338 | ✗ | break; | |
339 | } | ||
340 | ✗ | case GATE_PROPERTY_TYPE_INT: | |
341 | { | ||
342 | ✗ | buffer_used = gate_str_print_int64(buffer, sizeof(buffer), obj->data.int_value); | |
343 | ✗ | if (NULL == gate_string_create(value, buffer, buffer_used)) | |
344 | { | ||
345 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
346 | } | ||
347 | ✗ | break; | |
348 | } | ||
349 | ✗ | case GATE_PROPERTY_TYPE_REAL: | |
350 | { | ||
351 | ✗ | buffer_used = gate_str_print_real(buffer, sizeof(buffer), obj->data.real_value, 0, 6, 0); | |
352 | ✗ | if (NULL == gate_string_create(value, buffer, buffer_used)) | |
353 | { | ||
354 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
355 | } | ||
356 | ✗ | break; | |
357 | } | ||
358 | 9 | case GATE_PROPERTY_TYPE_STRING: | |
359 | { | ||
360 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
|
9 | if (NULL == gate_string_clone(value, &obj->data.string_value)) |
361 | { | ||
362 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
363 | } | ||
364 | 9 | break; | |
365 | } | ||
366 | ✗ | case GATE_PROPERTY_TYPE_ARRAY: | |
367 | { | ||
368 | ✗ | gate_string_create_static_len(value, "array", 5); | |
369 | ✗ | break; | |
370 | } | ||
371 | ✗ | case GATE_PROPERTY_TYPE_OBJECT: | |
372 | { | ||
373 | ✗ | gate_string_create_static_len(value, "object", 6); | |
374 | ✗ | break; | |
375 | } | ||
376 | ✗ | default: | |
377 | { | ||
378 | ✗ | gate_string_create_empty(value); | |
379 | ✗ | ret = GATE_RESULT_FAILED; | |
380 | ✗ | break; | |
381 | } | ||
382 | } | ||
383 | ✗ | } | |
384 | 9 | return ret; | |
385 | } | ||
386 | |||
387 | ✗ | gate_result_t gate_property_set_bool(gate_property_t* obj, gate_bool_t value) | |
388 | { | ||
389 | ✗ | gate_property_destroy(obj); | |
390 | ✗ | gate_property_create_bool(obj, value); | |
391 | ✗ | return GATE_RESULT_OK; | |
392 | } | ||
393 | ✗ | gate_result_t gate_property_set_int(gate_property_t* obj, gate_int64_t value) | |
394 | { | ||
395 | ✗ | gate_property_destroy(obj); | |
396 | ✗ | gate_property_create_int(obj, value); | |
397 | ✗ | return GATE_RESULT_OK; | |
398 | } | ||
399 | ✗ | gate_result_t gate_property_set_real(gate_property_t* obj, gate_real64_t value) | |
400 | { | ||
401 | ✗ | gate_property_destroy(obj); | |
402 | ✗ | gate_property_create_real(obj, value); | |
403 | ✗ | return GATE_RESULT_OK; | |
404 | } | ||
405 | ✗ | gate_result_t gate_property_set_string(gate_property_t* obj, gate_string_t const* value) | |
406 | { | ||
407 | gate_property_t tmp; | ||
408 | ✗ | if (NULL == gate_property_create_string(&tmp, value)) | |
409 | { | ||
410 | ✗ | return GATE_RESULT_OUTOFMEMORY; | |
411 | } | ||
412 | else | ||
413 | { | ||
414 | ✗ | gate_property_destroy(obj); | |
415 | ✗ | gate_mem_copy(obj, &tmp, sizeof(tmp)); | |
416 | ✗ | return GATE_RESULT_OK; | |
417 | } | ||
418 | } | ||
419 | |||
420 | |||
421 | 61 | gate_property_t* gate_property_array_add(gate_property_t* array_obj, gate_property_t const* item) | |
422 | { | ||
423 | 61 | gate_property_t* ret = NULL; | |
424 |
1/2✓ Branch 0 taken 61 times.
✗ Branch 1 not taken.
|
61 | if (array_obj->value_type == GATE_PROPERTY_TYPE_ARRAY) |
425 | { | ||
426 | 61 | ret = (gate_property_t*)gate_arraylist_add(array_obj->data.array_value, item); | |
427 | } | ||
428 | 61 | return ret; | |
429 | } | ||
430 | 251 | gate_property_t const* gate_property_array_get(gate_property_t const* array_obj, gate_size_t index) | |
431 | { | ||
432 | 251 | gate_property_t const* ret = NULL; | |
433 |
1/2✓ Branch 0 taken 251 times.
✗ Branch 1 not taken.
|
251 | if (array_obj->value_type == GATE_PROPERTY_TYPE_ARRAY) |
434 | { | ||
435 | 251 | ret = (gate_property_t const*)gate_arraylist_get(array_obj->data.array_value, index); | |
436 | } | ||
437 | 251 | return ret; | |
438 | } | ||
439 | 20 | gate_size_t gate_property_array_length(gate_property_t const* array_obj) | |
440 | { | ||
441 | 20 | gate_size_t ret = 0; | |
442 |
1/2✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
|
20 | if (array_obj->value_type == GATE_PROPERTY_TYPE_ARRAY) |
443 | { | ||
444 | 20 | ret = gate_arraylist_length(array_obj->data.array_value); | |
445 | } | ||
446 | 20 | return ret; | |
447 | } | ||
448 | 1 | gate_bool_t gate_property_array_remove(gate_property_t* array_obj, gate_size_t index) | |
449 | { | ||
450 | 1 | gate_bool_t ret = false; | |
451 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (array_obj->value_type == GATE_PROPERTY_TYPE_ARRAY) |
452 | { | ||
453 | 1 | ret = GATE_SUCCEEDED(gate_arraylist_remove(array_obj->data.array_value, index, 1)); | |
454 | } | ||
455 | 1 | return ret; | |
456 | } | ||
457 | |||
458 | 209 | gate_property_t* gate_property_member_add(gate_property_t* obj, gate_string_t const* name, gate_property_t const* item) | |
459 | { | ||
460 | 209 | gate_property_t* ret = NULL; | |
461 | gate_flatmap_iterator_t iter; | ||
462 | |||
463 |
1/2✓ Branch 0 taken 209 times.
✗ Branch 1 not taken.
|
209 | if (obj->value_type == GATE_PROPERTY_TYPE_OBJECT) |
464 | { | ||
465 | 209 | iter = gate_flatmap_add(&obj->data.object_value, name, item); | |
466 |
1/2✓ Branch 1 taken 209 times.
✗ Branch 2 not taken.
|
209 | if (gate_flatmap_iterator_valid(&obj->data.object_value, iter)) |
467 | { | ||
468 | 209 | ret = (gate_property_t*)gate_flatmap_iterator_value(iter); | |
469 | } | ||
470 | } | ||
471 | 209 | return ret; | |
472 | } | ||
473 | 495 | gate_property_t const* gate_property_member_get(gate_property_t const* obj, gate_string_t const* name) | |
474 | { | ||
475 | 495 | gate_property_t const* ret = NULL; | |
476 | gate_flatmap_iterator_t iter; | ||
477 | |||
478 |
1/2✓ Branch 0 taken 495 times.
✗ Branch 1 not taken.
|
495 | if (obj->value_type == GATE_PROPERTY_TYPE_OBJECT) |
479 | { | ||
480 | 495 | iter = gate_flatmap_get(&obj->data.object_value, name); | |
481 |
1/2✓ Branch 1 taken 495 times.
✗ Branch 2 not taken.
|
495 | if (gate_flatmap_iterator_valid(&obj->data.object_value, iter)) |
482 | { | ||
483 | 495 | ret = (gate_property_t const*)gate_flatmap_iterator_value(iter); | |
484 | } | ||
485 | } | ||
486 | 495 | return ret; | |
487 | } | ||
488 | 7 | gate_array_t* gate_property_member_names(gate_property_t const* obj, gate_array_t* new_string_array) | |
489 | { | ||
490 | 7 | gate_array_t* ret = NULL; | |
491 | 7 | gate_flatmap_iterator_t iter = NULL; | |
492 | 7 | gate_arraylist_t name_list = NULL; | |
493 | gate_string_t const* ptr_key; | ||
494 | |||
495 | do | ||
496 | { | ||
497 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
|
7 | if (obj == NULL) break; |
498 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
|
7 | if (obj->value_type != GATE_PROPERTY_TYPE_OBJECT) break; |
499 | |||
500 | 7 | name_list = gate_arraylist_create(sizeof(gate_string_t), NULL, 0, | |
501 | &gate_string_copy_constructor, &gate_string_destructor); | ||
502 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
|
7 | if (name_list == NULL) |
503 | { | ||
504 | ✗ | break; | |
505 | } | ||
506 | |||
507 | 7 | iter = gate_flatmap_first(&obj->data.object_value); | |
508 |
2/2✓ Branch 1 taken 29 times.
✓ Branch 2 taken 7 times.
|
36 | while (gate_flatmap_iterator_valid(&obj->data.object_value, iter)) |
509 | { | ||
510 | 29 | ptr_key = (gate_string_t const*)gate_flatmap_iterator_key(iter); | |
511 |
1/2✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
|
29 | if (ptr_key) |
512 | { | ||
513 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 29 times.
|
29 | if (NULL == gate_arraylist_add(name_list, ptr_key)) |
514 | { | ||
515 | ✗ | break; | |
516 | } | ||
517 | } | ||
518 | 29 | iter = gate_flatmap_iterator_next(iter); | |
519 | } | ||
520 | |||
521 |
1/2✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
|
7 | if (NULL != gate_array_create(new_string_array, name_list)) |
522 | { | ||
523 | 7 | ret = new_string_array; | |
524 | } | ||
525 | } while (0); | ||
526 | |||
527 | 7 | gate_arraylist_release(name_list); | |
528 | 7 | return ret; | |
529 | } | ||
530 | ✗ | gate_size_t gate_property_member_count(gate_property_t const* obj) | |
531 | { | ||
532 | ✗ | gate_size_t ret = 0; | |
533 | ✗ | if (obj->value_type == GATE_PROPERTY_TYPE_OBJECT) | |
534 | { | ||
535 | ✗ | ret = gate_flatmap_count(&obj->data.object_value); | |
536 | } | ||
537 | ✗ | return ret; | |
538 | } | ||
539 | 2 | gate_bool_t gate_property_member_remove(gate_property_t* obj, gate_string_t const* name) | |
540 | { | ||
541 | 2 | gate_bool_t ret = false; | |
542 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if (obj->value_type == GATE_PROPERTY_TYPE_OBJECT) |
543 | { | ||
544 | 2 | ret = gate_flatmap_remove(&obj->data.object_value, name); | |
545 | } | ||
546 | 2 | return ret; | |
547 | } | ||
548 | |||
549 | |||
550 | |||
551 | |||
552 | |||
553 | |||
554 | ✗ | gate_result_t gate_property_import(gate_property_t* target, gate_type_id_t type, void const* source) | |
555 | { | ||
556 | ✗ | gate_result_t ret = GATE_RESULT_OK; | |
557 | char tmp[1024]; | ||
558 | gate_size_t sz; | ||
559 | gate_size_t index; | ||
560 | gate_datetime_t dt; | ||
561 | ✗ | gate_property_t* ptr = NULL; | |
562 | ✗ | gate_bool_t is_bool = false; | |
563 | ✗ | gate_bool_t b = false; | |
564 | ✗ | gate_bool_t is_int = false; | |
565 | ✗ | gate_int64_t i64 = 0; | |
566 | ✗ | gate_bool_t is_real = false; | |
567 | ✗ | gate_real64_t r64 = 0.0; | |
568 | ✗ | gate_bool_t is_string = false; | |
569 | ✗ | gate_string_t str = GATE_STRING_INIT_EMPTY; | |
570 | ✗ | gate_bool_t is_prop = false; | |
571 | ✗ | gate_property_t prop = GATE_INIT_EMPTY; | |
572 | char const* member_name; | ||
573 | gate_string_t member_string; | ||
574 | gate_uint16_t member_type; | ||
575 | void const* member_ptr; | ||
576 | gate_property_t member_prop; | ||
577 | gate_bool_t partial_failed; | ||
578 | |||
579 | ✗ | switch (type) | |
580 | { | ||
581 | ✗ | case GATE_TYPE_EMPTY: ptr = gate_property_create_empty(target); break; | |
582 | |||
583 | ✗ | case GATE_TYPE_BOOL: b = *(gate_bool_t const*)source; is_bool = true; break; | |
584 | ✗ | case GATE_TYPE_I8: i64 = *(gate_int8_t const*)source; is_int = true; break; | |
585 | ✗ | case GATE_TYPE_UI8: i64 = *(gate_uint8_t const*)source; is_int = true; break; | |
586 | ✗ | case GATE_TYPE_I16: i64 = *(gate_int16_t const*)source; is_int = true; break; | |
587 | ✗ | case GATE_TYPE_UI16: i64 = *(gate_uint16_t const*)source; is_int = true; break; | |
588 | ✗ | case GATE_TYPE_I32: i64 = *(gate_int32_t const*)source; is_int = true; break; | |
589 | ✗ | case GATE_TYPE_UI32: i64 = *(gate_uint32_t const*)source; is_int = true; break; | |
590 | ✗ | case GATE_TYPE_I64: i64 = *(gate_int64_t const*)source; is_int = true; break; | |
591 | ✗ | case GATE_TYPE_UI64: i64 = (gate_int64_t)(*(gate_uint64_t const*)source); is_int = true; break; | |
592 | ✗ | case GATE_TYPE_R32: r64 = *(gate_real32_t const*)source; is_real = true; break; | |
593 | ✗ | case GATE_TYPE_R64: r64 = *(gate_real64_t const*)source; is_real = true; break; | |
594 | ✗ | case GATE_TYPE_ADDRESS: i64 = (gate_int64_t)(*(gate_uintptr_t const*)source); is_int = true; break; | |
595 | |||
596 | ✗ | case GATE_TYPE_DATAPTR: i64 = (gate_int64_t)(gate_intptr_t)(*(gate_dataptr_t const*)source); is_int = true; break; | |
597 | ✗ | case GATE_TYPE_FUNCPTR: i64 = (gate_int64_t)(gate_intptr_t)(*(gate_funcptr_t const*)source); is_int = true; break; | |
598 | ✗ | case GATE_TYPE_CSTR: ret = GATE_RESULT_NOTSUPPORTED; break; | |
599 | ✗ | case GATE_TYPE_WSTR: ret = GATE_RESULT_NOTSUPPORTED; break; | |
600 | ✗ | case GATE_TYPE_GUID: | |
601 | { | ||
602 | ✗ | ret = gate_guid_to_string((gate_guid_t const*)source, tmp); | |
603 | ✗ | if (GATE_SUCCEEDED(ret)) | |
604 | { | ||
605 | ✗ | if (NULL == gate_string_create(&str, tmp, gate_str_length(tmp))) | |
606 | { | ||
607 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
608 | } | ||
609 | else | ||
610 | { | ||
611 | ✗ | is_string = true; | |
612 | } | ||
613 | } | ||
614 | ✗ | break; | |
615 | } | ||
616 | ✗ | case GATE_TYPE_DATE: | |
617 | { | ||
618 | ✗ | gate_mem_clear(&dt, sizeof(dt)); | |
619 | ✗ | gate_mem_copy(&dt.date, (gate_date_t const*)source, sizeof(gate_date_t)); | |
620 | ✗ | sz = sizeof(tmp); | |
621 | ✗ | ret = gate_date_to_string(&dt, 0, NULL, tmp, &sz); | |
622 | ✗ | if (GATE_SUCCEEDED(ret)) | |
623 | { | ||
624 | ✗ | if (NULL == gate_string_create(&str, tmp, sz)) | |
625 | { | ||
626 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
627 | } | ||
628 | else | ||
629 | { | ||
630 | ✗ | is_string = true; | |
631 | } | ||
632 | } | ||
633 | ✗ | break; | |
634 | } | ||
635 | ✗ | case GATE_TYPE_DAYTIME: | |
636 | { | ||
637 | ✗ | gate_mem_clear(&dt, sizeof(dt)); | |
638 | ✗ | gate_mem_copy(&dt.time, (gate_daytime_t const*)source, sizeof(gate_daytime_t)); | |
639 | ✗ | sz = sizeof(tmp); | |
640 | ✗ | ret = gate_date_to_string(&dt, 0, NULL, tmp, &sz); | |
641 | ✗ | if (GATE_SUCCEEDED(ret)) | |
642 | { | ||
643 | ✗ | if (NULL == gate_string_create(&str, tmp, sz)) | |
644 | { | ||
645 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
646 | } | ||
647 | else | ||
648 | { | ||
649 | ✗ | is_string = true; | |
650 | } | ||
651 | } | ||
652 | ✗ | break; | |
653 | } | ||
654 | ✗ | case GATE_TYPE_DATETIME: | |
655 | { | ||
656 | ✗ | sz = sizeof(tmp); | |
657 | ✗ | ret = gate_date_to_string((gate_datetime_t const*)source, 0, NULL, tmp, &sz); | |
658 | ✗ | if (GATE_SUCCEEDED(ret)) | |
659 | { | ||
660 | ✗ | if (NULL == gate_string_create(&str, tmp, sz)) | |
661 | { | ||
662 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
663 | } | ||
664 | else | ||
665 | { | ||
666 | ✗ | is_string = true; | |
667 | } | ||
668 | } | ||
669 | ✗ | break; | |
670 | } | ||
671 | ✗ | case GATE_TYPE_TIME: | |
672 | { | ||
673 | ✗ | sz = sizeof(tmp); | |
674 | ✗ | ret = gate_time_to_string((gate_time_t const*)source, NULL, tmp, &sz); | |
675 | ✗ | if (GATE_SUCCEEDED(ret)) | |
676 | { | ||
677 | ✗ | if (NULL == gate_string_create(&str, tmp, sz)) | |
678 | { | ||
679 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
680 | } | ||
681 | else | ||
682 | { | ||
683 | ✗ | is_string = true; | |
684 | } | ||
685 | } | ||
686 | ✗ | break; | |
687 | } | ||
688 | |||
689 | ✗ | case GATE_TYPE_STRING: | |
690 | { | ||
691 | ✗ | if (NULL == gate_string_clone(&str, (gate_string_t const*)source)) | |
692 | { | ||
693 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
694 | } | ||
695 | else | ||
696 | { | ||
697 | ✗ | is_string = true; | |
698 | } | ||
699 | ✗ | break; | |
700 | } | ||
701 | ✗ | case GATE_TYPE_ARRAY: | |
702 | { | ||
703 | ✗ | ret = GATE_RESULT_NOTSUPPORTED; | |
704 | ✗ | break; | |
705 | } | ||
706 | |||
707 | ✗ | case GATE_TYPE_STRUCT: | |
708 | { | ||
709 | ✗ | if (NULL == gate_property_create_object(&prop)) | |
710 | { | ||
711 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
712 | } | ||
713 | else | ||
714 | { | ||
715 | ✗ | partial_failed = false; | |
716 | ✗ | sz = gate_struct_get_member_count((gate_struct_t const*)source); | |
717 | ✗ | for (index = 0; index != sz; ++index) | |
718 | { | ||
719 | ✗ | member_name = gate_struct_get_member_name((gate_struct_t const*)source, index); | |
720 | ✗ | member_type = gate_struct_get_member_type((gate_struct_t const*)source, index); | |
721 | ✗ | member_ptr = gate_struct_get_member((gate_struct_t const*)source, index); | |
722 | ✗ | if (member_name && member_type && member_ptr) | |
723 | { | ||
724 | ✗ | ret = gate_property_import(&member_prop, member_type, member_ptr); | |
725 | ✗ | if (GATE_SUCCEEDED(ret)) | |
726 | { | ||
727 | ✗ | if (NULL != gate_string_create(&member_string, member_name, gate_str_length(member_name))) | |
728 | { | ||
729 | ✗ | gate_property_member_add(&prop, &member_string, &member_prop); | |
730 | ✗ | gate_string_release(&member_string); | |
731 | } | ||
732 | ✗ | gate_property_destroy(&member_prop); | |
733 | } | ||
734 | else | ||
735 | { | ||
736 | ✗ | partial_failed = true; | |
737 | } | ||
738 | } | ||
739 | } | ||
740 | ✗ | is_prop = true; | |
741 | ✗ | ret = partial_failed ? GATE_RESULT_OK_PARTIAL : GATE_RESULT_OK; | |
742 | } | ||
743 | ✗ | break; | |
744 | } | ||
745 | ✗ | case GATE_TYPE_OBJECT: | |
746 | { | ||
747 | ✗ | ret = GATE_RESULT_NOTSUPPORTED; | |
748 | ✗ | break; | |
749 | } | ||
750 | ✗ | case GATE_TYPE_PROPERTY: | |
751 | { | ||
752 | ✗ | if (NULL == gate_property_copy(&prop, (gate_property_t const*)source)) | |
753 | { | ||
754 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
755 | ✗ | break; | |
756 | } | ||
757 | else | ||
758 | { | ||
759 | ✗ | is_prop = true; | |
760 | } | ||
761 | ✗ | break; | |
762 | } | ||
763 | |||
764 | ✗ | case GATE_TYPE_ARRAYLIST: | |
765 | case GATE_TYPE_ARRAYLIST_BOOL: | ||
766 | case GATE_TYPE_ARRAYLIST_I8: | ||
767 | case GATE_TYPE_ARRAYLIST_UI8: | ||
768 | case GATE_TYPE_ARRAYLIST_I16: | ||
769 | case GATE_TYPE_ARRAYLIST_UI16: | ||
770 | case GATE_TYPE_ARRAYLIST_I32: | ||
771 | case GATE_TYPE_ARRAYLIST_UI32: | ||
772 | case GATE_TYPE_ARRAYLIST_I64: | ||
773 | case GATE_TYPE_ARRAYLIST_UI64: | ||
774 | case GATE_TYPE_ARRAYLIST_R32: | ||
775 | case GATE_TYPE_ARRAYLIST_R64: | ||
776 | case GATE_TYPE_ARRAYLIST_ADDRESS: | ||
777 | |||
778 | case GATE_TYPE_ARRAYLIST_DATAPTR: | ||
779 | case GATE_TYPE_ARRAYLIST_FUNCPTR: | ||
780 | case GATE_TYPE_ARRAYLIST_CSTR: | ||
781 | case GATE_TYPE_ARRAYLIST_WSTR: | ||
782 | case GATE_TYPE_ARRAYLIST_GUID: | ||
783 | case GATE_TYPE_ARRAYLIST_DATE: | ||
784 | case GATE_TYPE_ARRAYLIST_DAYTIME: | ||
785 | case GATE_TYPE_ARRAYLIST_DATETIME: | ||
786 | case GATE_TYPE_ARRAYLIST_TIME: | ||
787 | |||
788 | case GATE_TYPE_ARRAYLIST_STRING: | ||
789 | case GATE_TYPE_ARRAYLIST_ARRAY: | ||
790 | |||
791 | case GATE_TYPE_ARRAYLIST_STRUCT: | ||
792 | case GATE_TYPE_ARRAYLIST_OBJECT: | ||
793 | case GATE_TYPE_ARRAYLIST_PROPERTY: | ||
794 | { | ||
795 | gate_arraylist_t list; | ||
796 | void const* arr_ptr; | ||
797 | gate_property_t item; | ||
798 | |||
799 | ✗ | if (NULL == gate_property_create_array(&prop, NULL, 0)) | |
800 | { | ||
801 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
802 | } | ||
803 | else | ||
804 | { | ||
805 | ✗ | ret = GATE_RESULT_OK; | |
806 | ✗ | list = *(gate_arraylist_t const*)source; | |
807 | ✗ | sz = gate_arraylist_length(list); | |
808 | ✗ | is_prop = true; | |
809 | ✗ | for (index = 0; index != sz; ++index) | |
810 | { | ||
811 | ✗ | arr_ptr = gate_arraylist_get(list, index); | |
812 | ✗ | if (arr_ptr) | |
813 | { | ||
814 | ✗ | if (GATE_SUCCEEDED(gate_property_import(&item, (gate_uint16_t)(type & ~GATE_TYPE_ARRAYLIST), arr_ptr))) | |
815 | { | ||
816 | ✗ | if (NULL == gate_property_array_add(&prop, &item)) | |
817 | { | ||
818 | ✗ | ret = GATE_RESULT_OK_PARTIAL; | |
819 | } | ||
820 | ✗ | gate_property_destroy(&item); | |
821 | } | ||
822 | else | ||
823 | { | ||
824 | ✗ | ret = GATE_RESULT_OK_PARTIAL; | |
825 | } | ||
826 | } | ||
827 | } | ||
828 | } | ||
829 | ✗ | break; | |
830 | } | ||
831 | } | ||
832 | |||
833 | ✗ | if (GATE_SUCCEEDED(ret)) | |
834 | { | ||
835 | ✗ | if (is_prop) | |
836 | { | ||
837 | ✗ | gate_mem_copy(target, &prop, sizeof(prop)); | |
838 | } | ||
839 | ✗ | else if (is_string) | |
840 | { | ||
841 | ✗ | gate_property_create_string(target, &str); | |
842 | ✗ | gate_string_release(&str); | |
843 | } | ||
844 | ✗ | else if (is_real) | |
845 | { | ||
846 | ✗ | gate_property_create_real(target, r64); | |
847 | } | ||
848 | ✗ | else if (is_int) | |
849 | { | ||
850 | ✗ | gate_property_create_int(target, i64); | |
851 | } | ||
852 | ✗ | else if (is_bool) | |
853 | { | ||
854 | ✗ | gate_property_create_bool(target, b); | |
855 | } | ||
856 | else | ||
857 | { | ||
858 | ✗ | gate_property_create_empty(target); | |
859 | } | ||
860 | } | ||
861 | ✗ | return ret; | |
862 | } | ||
863 | |||
864 | union local_generic_item | ||
865 | { | ||
866 | gate_c_maxalign_t aligner; | ||
867 | char buffer[8192]; | ||
868 | }; | ||
869 | |||
870 | ✗ | gate_result_t gate_property_export(gate_property_t const* source, gate_type_id_t type_id, void* target) | |
871 | { | ||
872 | ✗ | gate_result_t ret = GATE_RESULT_FAILED; | |
873 | ✗ | gate_bool_t b = false; | |
874 | ✗ | gate_int64_t i64 = 0; | |
875 | ✗ | gate_real64_t r64 = 0.0; | |
876 | ✗ | gate_string_t str = GATE_STRING_INIT_EMPTY; | |
877 | ✗ | gate_datetime_t dt = GATE_INIT_EMPTY; | |
878 | ✗ | gate_int16_t bias = 0; | |
879 | |||
880 | ✗ | switch (type_id) | |
881 | { | ||
882 | ✗ | case GATE_TYPE_EMPTY: | |
883 | ✗ | ret = GATE_RESULT_NOTSUPPORTED; | |
884 | ✗ | break; | |
885 | |||
886 | ✗ | case GATE_TYPE_BOOL: ret = gate_property_get_bool(source, &b); *(gate_bool_t*)target = b; break; | |
887 | ✗ | case GATE_TYPE_I8: ret = gate_property_get_int(source, &i64); *(gate_int8_t*)target = (gate_int8_t)i64; break; | |
888 | ✗ | case GATE_TYPE_UI8: ret = gate_property_get_int(source, &i64); *(gate_uint8_t*)target = (gate_uint8_t)i64; break; | |
889 | ✗ | case GATE_TYPE_I16: ret = gate_property_get_int(source, &i64); *(gate_int16_t*)target = (gate_int16_t)i64; break; | |
890 | ✗ | case GATE_TYPE_UI16: ret = gate_property_get_int(source, &i64); *(gate_uint16_t*)target = (gate_uint16_t)i64; break; | |
891 | ✗ | case GATE_TYPE_I32: ret = gate_property_get_int(source, &i64); *(gate_int32_t*)target = (gate_int32_t)i64; break; | |
892 | ✗ | case GATE_TYPE_UI32: ret = gate_property_get_int(source, &i64); *(gate_uint32_t*)target = (gate_uint32_t)i64; break; | |
893 | ✗ | case GATE_TYPE_I64: ret = gate_property_get_int(source, &i64); *(gate_int64_t*)target = (gate_int64_t)i64; break; | |
894 | ✗ | case GATE_TYPE_UI64: ret = gate_property_get_int(source, &i64); *(gate_uint64_t*)target = (gate_uint64_t)i64; break; | |
895 | ✗ | case GATE_TYPE_R32: ret = gate_property_get_real(source, &r64); *(gate_real32_t*)target = (gate_real32_t)r64; break; | |
896 | ✗ | case GATE_TYPE_R64: ret = gate_property_get_real(source, &r64); *(gate_real64_t*)target = (gate_real64_t)r64; break; | |
897 | ✗ | case GATE_TYPE_ADDRESS: ret = gate_property_get_int(source, &i64); *(gate_uintptr_t*)target = (gate_uintptr_t)i64; break; | |
898 | |||
899 | ✗ | case GATE_TYPE_DATAPTR: ret = gate_property_get_int(source, &i64); *(gate_dataptr_t*)target = (gate_dataptr_t)(gate_intptr_t)i64; break; | |
900 | ✗ | case GATE_TYPE_FUNCPTR: ret = gate_property_get_int(source, &i64); *(gate_funcptr_t*)target = (gate_funcptr_t)(gate_intptr_t)i64; break; | |
901 | ✗ | case GATE_TYPE_CSTR: ret = GATE_RESULT_NOTSUPPORTED; break; | |
902 | ✗ | case GATE_TYPE_WSTR: ret = GATE_RESULT_NOTSUPPORTED; break; | |
903 | ✗ | case GATE_TYPE_GUID: | |
904 | { | ||
905 | ✗ | ret = gate_property_get_string(source, &str); | |
906 | ✗ | GATE_BREAK_IF_FAILED(ret); | |
907 | ✗ | ret = gate_guid_parse_string(str.str, str.length, (gate_guid_t*)target); | |
908 | ✗ | break; | |
909 | } | ||
910 | ✗ | case GATE_TYPE_DATE: | |
911 | { | ||
912 | ✗ | ret = gate_property_get_string(source, &str); | |
913 | ✗ | GATE_BREAK_IF_FAILED(ret); | |
914 | ✗ | if (0 == gate_date_parse_string(str.str, str.length, &dt, &bias)) | |
915 | { | ||
916 | ✗ | ret = GATE_RESULT_FAILED; | |
917 | } | ||
918 | else | ||
919 | { | ||
920 | ✗ | *((gate_date_t*)target) = dt.date; | |
921 | } | ||
922 | ✗ | break; | |
923 | } | ||
924 | ✗ | case GATE_TYPE_DAYTIME: | |
925 | { | ||
926 | ✗ | ret = gate_property_get_string(source, &str); | |
927 | ✗ | GATE_BREAK_IF_FAILED(ret); | |
928 | ✗ | if (0 == gate_date_parse_string(str.str, str.length, &dt, &bias)) | |
929 | { | ||
930 | ✗ | ret = GATE_RESULT_FAILED; | |
931 | } | ||
932 | else | ||
933 | { | ||
934 | ✗ | *((gate_daytime_t*)target) = dt.time; | |
935 | } | ||
936 | ✗ | break; | |
937 | } | ||
938 | ✗ | case GATE_TYPE_DATETIME: | |
939 | { | ||
940 | ✗ | ret = gate_property_get_string(source, &str); | |
941 | ✗ | GATE_BREAK_IF_FAILED(ret); | |
942 | ✗ | if (0 == gate_date_parse_string(str.str, str.length, (gate_datetime_t*)target, &bias)) | |
943 | { | ||
944 | ✗ | ret = GATE_RESULT_FAILED; | |
945 | } | ||
946 | ✗ | break; | |
947 | } | ||
948 | ✗ | case GATE_TYPE_TIME: | |
949 | { | ||
950 | ✗ | ret = gate_property_get_string(source, &str); | |
951 | ✗ | GATE_BREAK_IF_FAILED(ret); | |
952 | ✗ | ret = gate_time_parse_string(str.str, str.length, (gate_time_t*)target); | |
953 | ✗ | break; | |
954 | } | ||
955 | |||
956 | ✗ | case GATE_TYPE_STRING: | |
957 | { | ||
958 | ✗ | ret = gate_property_get_string(source, &str); | |
959 | ✗ | GATE_BREAK_IF_FAILED(ret); | |
960 | ✗ | if (NULL == gate_string_clone((gate_string_t*)target, &str)) | |
961 | { | ||
962 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
963 | } | ||
964 | ✗ | break; | |
965 | } | ||
966 | ✗ | case GATE_TYPE_ARRAY: | |
967 | { | ||
968 | ✗ | ret = GATE_RESULT_NOTSUPPORTED; | |
969 | ✗ | break; | |
970 | } | ||
971 | |||
972 | ✗ | case GATE_TYPE_STRUCT: | |
973 | { | ||
974 | ✗ | gate_struct_t* ptr_struct = (gate_struct_t*)target; | |
975 | ✗ | gate_size_t cnt = gate_struct_get_member_count(ptr_struct); | |
976 | gate_size_t index; | ||
977 | char const* member_name; | ||
978 | gate_uint16_t member_type; | ||
979 | void const* ptr_member; | ||
980 | gate_property_t const* member_prop; | ||
981 | gate_result_t member_result; | ||
982 | |||
983 | ✗ | ret = GATE_RESULT_OK; | |
984 | |||
985 | ✗ | for (index = 0; index != cnt; ++index) | |
986 | { | ||
987 | ✗ | member_name = gate_struct_get_member_name(ptr_struct, index); | |
988 | ✗ | member_type = gate_struct_get_member_type(ptr_struct, index); | |
989 | ✗ | ptr_member = gate_struct_get_member(ptr_struct, index); | |
990 | ✗ | if (member_name && member_type && ptr_member) | |
991 | { | ||
992 | ✗ | gate_string_create_static(&str, member_name); | |
993 | ✗ | member_prop = gate_property_member_get(source, &str); | |
994 | ✗ | if (member_prop) | |
995 | { | ||
996 | ✗ | member_result = gate_property_export(member_prop, member_type, (void*)ptr_member); | |
997 | ✗ | if (GATE_FAILED(member_result)) | |
998 | { | ||
999 | ✗ | ret = GATE_RESULT_OK_PARTIAL; | |
1000 | } | ||
1001 | } | ||
1002 | } | ||
1003 | } | ||
1004 | ✗ | break; | |
1005 | } | ||
1006 | ✗ | case GATE_TYPE_OBJECT: | |
1007 | { | ||
1008 | ✗ | ret = GATE_RESULT_NOTSUPPORTED; | |
1009 | ✗ | break; | |
1010 | } | ||
1011 | ✗ | case GATE_TYPE_PROPERTY: | |
1012 | { | ||
1013 | ✗ | if (NULL == gate_property_copy((gate_property_t*)target, source)) | |
1014 | { | ||
1015 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
1016 | } | ||
1017 | else | ||
1018 | { | ||
1019 | ✗ | ret = GATE_RESULT_OK; | |
1020 | } | ||
1021 | ✗ | break; | |
1022 | } | ||
1023 | |||
1024 | ✗ | case GATE_TYPE_ARRAYLIST: | |
1025 | case GATE_TYPE_ARRAYLIST_BOOL: | ||
1026 | case GATE_TYPE_ARRAYLIST_I8: | ||
1027 | case GATE_TYPE_ARRAYLIST_UI8: | ||
1028 | case GATE_TYPE_ARRAYLIST_I16: | ||
1029 | case GATE_TYPE_ARRAYLIST_UI16: | ||
1030 | case GATE_TYPE_ARRAYLIST_I32: | ||
1031 | case GATE_TYPE_ARRAYLIST_UI32: | ||
1032 | case GATE_TYPE_ARRAYLIST_I64: | ||
1033 | case GATE_TYPE_ARRAYLIST_UI64: | ||
1034 | case GATE_TYPE_ARRAYLIST_R32: | ||
1035 | case GATE_TYPE_ARRAYLIST_R64: | ||
1036 | case GATE_TYPE_ARRAYLIST_ADDRESS: | ||
1037 | |||
1038 | case GATE_TYPE_ARRAYLIST_DATAPTR: | ||
1039 | case GATE_TYPE_ARRAYLIST_FUNCPTR: | ||
1040 | case GATE_TYPE_ARRAYLIST_CSTR: | ||
1041 | case GATE_TYPE_ARRAYLIST_WSTR: | ||
1042 | case GATE_TYPE_ARRAYLIST_GUID: | ||
1043 | case GATE_TYPE_ARRAYLIST_DATE: | ||
1044 | case GATE_TYPE_ARRAYLIST_DAYTIME: | ||
1045 | case GATE_TYPE_ARRAYLIST_DATETIME: | ||
1046 | case GATE_TYPE_ARRAYLIST_TIME: | ||
1047 | |||
1048 | case GATE_TYPE_ARRAYLIST_STRING: | ||
1049 | case GATE_TYPE_ARRAYLIST_ARRAY: | ||
1050 | |||
1051 | case GATE_TYPE_ARRAYLIST_STRUCT: | ||
1052 | case GATE_TYPE_ARRAYLIST_OBJECT: | ||
1053 | case GATE_TYPE_ARRAYLIST_PROPERTY: | ||
1054 | { | ||
1055 | ✗ | gate_size_t cnt = gate_property_array_length(source); | |
1056 | gate_size_t index; | ||
1057 | gate_property_t const* item; | ||
1058 | gate_result_t item_result; | ||
1059 | union local_generic_item local_item; | ||
1060 | ✗ | ret = GATE_RESULT_OK; | |
1061 | ✗ | for (index = 0; index != cnt; ++index) | |
1062 | { | ||
1063 | ✗ | item = gate_property_array_get(source, index); | |
1064 | ✗ | if (!item) | |
1065 | { | ||
1066 | ✗ | continue; | |
1067 | } | ||
1068 | ✗ | gate_mem_clear(&local_item, sizeof(local_item)); | |
1069 | ✗ | if (0 != gate_arraylist_create_item(*(gate_arraylist_t*)target, &local_item, sizeof(local_item))) | |
1070 | { | ||
1071 | ✗ | item_result = gate_property_export(item, (gate_uint16_t)(type_id & ~GATE_TYPE_ARRAYLIST), &local_item); | |
1072 | ✗ | if (GATE_SUCCEEDED(item_result)) | |
1073 | { | ||
1074 | ✗ | if (NULL == gate_arraylist_add(*(gate_arraylist_t*)target, &local_item)) | |
1075 | { | ||
1076 | ✗ | ret = GATE_RESULT_OK_PARTIAL; | |
1077 | } | ||
1078 | } | ||
1079 | else | ||
1080 | { | ||
1081 | ✗ | ret = GATE_RESULT_OK_PARTIAL; | |
1082 | } | ||
1083 | ✗ | gate_arraylist_destroy_item(*(gate_arraylist_t*)target, &local_item); | |
1084 | } | ||
1085 | else | ||
1086 | { | ||
1087 | ✗ | ret = GATE_RESULT_OK_PARTIAL; | |
1088 | } | ||
1089 | } | ||
1090 | ✗ | break; | |
1091 | } | ||
1092 | ✗ | default: | |
1093 | ✗ | ret = GATE_RESULT_NOTSUPPORTED; | |
1094 | ✗ | break; | |
1095 | } | ||
1096 | |||
1097 | ✗ | gate_string_release(&str); | |
1098 | |||
1099 | ✗ | return ret; | |
1100 | } | ||
1101 | |||
1102 | 455 | gate_property_t const* gate_property_resolve_path(gate_property_t const* source, gate_string_t const* path) | |
1103 | { | ||
1104 | 455 | gate_property_t const* ret = NULL; | |
1105 | 455 | gate_string_t str_path = GATE_STRING_INIT_EMPTY; | |
1106 | 455 | gate_string_t name = GATE_STRING_INIT_EMPTY; | |
1107 | gate_size_t pos; | ||
1108 | |||
1109 | 455 | gate_string_duplicate(&str_path, path); | |
1110 | |||
1111 | for (;;) | ||
1112 | { | ||
1113 | 458 | pos = gate_string_char_pos(&str_path, '.', 0); | |
1114 |
2/2✓ Branch 0 taken 455 times.
✓ Branch 1 taken 3 times.
|
458 | if (GATE_STR_NPOS == pos) |
1115 | { | ||
1116 | 455 | ret = gate_property_member_get(source, &str_path); | |
1117 | 455 | break; | |
1118 | } | ||
1119 | else | ||
1120 | { | ||
1121 | 3 | gate_string_substr(&name, &str_path, 0, pos); | |
1122 | 3 | source = gate_property_member_get(source, &name); | |
1123 | 3 | gate_string_release(&name); | |
1124 | 3 | gate_string_substr(&str_path, &str_path, pos + 1, GATE_STR_NPOS); | |
1125 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | if (source == NULL) |
1126 | { | ||
1127 | ✗ | ret = NULL; | |
1128 | ✗ | break; | |
1129 | } | ||
1130 | } | ||
1131 | } | ||
1132 | |||
1133 | 455 | gate_string_release(&name); | |
1134 | 455 | gate_string_release(&str_path); | |
1135 | 455 | return ret; | |
1136 | } | ||
1137 | 2 | gate_property_t const* gate_property_resolve_path_str(gate_property_t const* source, char const* path) | |
1138 | { | ||
1139 | 2 | gate_string_t str = GATE_STRING_INIT_EMPTY; | |
1140 | 2 | gate_string_create_static(&str, path); | |
1141 | 2 | return gate_property_resolve_path(source, &str); | |
1142 | } | ||
1143 | |||
1144 | 235 | gate_bool_t gate_property_equals_string(gate_property_t const* obj, gate_string_t const* text) | |
1145 | { | ||
1146 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 235 times.
|
235 | if (!obj) |
1147 | { | ||
1148 | ✗ | return gate_string_is_empty(text); | |
1149 | } | ||
1150 | else | ||
1151 | { | ||
1152 |
1/8✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 235 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
235 | switch (obj->value_type) |
1153 | { | ||
1154 | ✗ | case GATE_PROPERTY_TYPE_EMPTY: return gate_string_is_empty(text); | |
1155 | ✗ | case GATE_PROPERTY_TYPE_BOOL: return obj->data.bool_value == gate_util_string_eval_bool(text); | |
1156 | ✗ | case GATE_PROPERTY_TYPE_INT: return obj->data.int_value == gate_util_string_to_int(text); | |
1157 | ✗ | case GATE_PROPERTY_TYPE_REAL: return gate_math_iszero(obj->data.real_value - gate_util_string_to_real(text)); | |
1158 | 235 | case GATE_PROPERTY_TYPE_STRING: return gate_string_equals(&obj->data.string_value, text); | |
1159 | ✗ | case GATE_PROPERTY_TYPE_ARRAY: return false; | |
1160 | ✗ | case GATE_PROPERTY_TYPE_OBJECT: return false; | |
1161 | ✗ | default: return false; | |
1162 | } | ||
1163 | } | ||
1164 | } | ||
1165 | |||
1166 | 235 | gate_bool_t gate_property_equals_str(gate_property_t const* obj, char const* text) | |
1167 | { | ||
1168 | gate_result_t ret; | ||
1169 | 235 | gate_string_t str = GATE_STRING_INIT_EMPTY; | |
1170 | 235 | gate_string_create_static(&str, text); | |
1171 | 235 | ret = gate_property_equals_string(obj, &str); | |
1172 | 235 | gate_string_release(&str); | |
1173 | 235 | return ret; | |
1174 | } | ||
1175 | |||
1176 | |||
1177 | |||
1178 | |||
1179 | |||
1180 | /***********************************/ | ||
1181 | /* property-table implementation */ | ||
1182 | /***********************************/ | ||
1183 | |||
1184 | static gate_property_t const gate_proptable_empty_prop = GATE_INIT_EMPTY; | ||
1185 | |||
1186 | |||
1187 | 1 | gate_proptable_t* gate_proptable_create(gate_proptable_t* table) | |
1188 | { | ||
1189 | 1 | gate_proptable_t* ret = NULL; | |
1190 | 1 | gate_mem_clear(table, sizeof(gate_proptable_t)); | |
1191 | |||
1192 | do | ||
1193 | { | ||
1194 | 1 | table->column_types = gate_arraylist_create(sizeof(gate_property_typeid_t), NULL, 0, NULL, NULL); | |
1195 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (NULL == table->column_types) break; |
1196 | |||
1197 | 1 | table->column_names = gate_util_stringarray_create(); | |
1198 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (NULL == table->column_names) break; |
1199 | |||
1200 | 1 | table->rows = gate_arraylist_create(sizeof(gate_arraylist_t), NULL, 0, NULL, NULL); | |
1201 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (NULL == table->rows) break; |
1202 | |||
1203 | 1 | ret = table; | |
1204 | 1 | table = NULL; | |
1205 | } while (0); | ||
1206 | |||
1207 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (table) |
1208 | { | ||
1209 | ✗ | gate_proptable_destroy(table); | |
1210 | } | ||
1211 | 1 | return ret; | |
1212 | } | ||
1213 | |||
1214 | ✗ | gate_proptable_t* gate_proptable_copy(gate_proptable_t* table, gate_proptable_t const* src_table) | |
1215 | { | ||
1216 | ✗ | gate_proptable_t* ret = NULL; | |
1217 | gate_size_t row_count; | ||
1218 | gate_size_t col_count; | ||
1219 | gate_size_t row; | ||
1220 | gate_size_t col; | ||
1221 | gate_property_t const* ptr_src; | ||
1222 | gate_result_t result; | ||
1223 | |||
1224 | do | ||
1225 | { | ||
1226 | ✗ | gate_mem_clear(table, sizeof(gate_proptable_t)); | |
1227 | |||
1228 | ✗ | row_count = gate_arraylist_length(table->rows); | |
1229 | ✗ | col_count = gate_arraylist_length(table->column_names); | |
1230 | |||
1231 | ✗ | table->column_types = gate_arraylist_copy(src_table->column_types); | |
1232 | ✗ | if (NULL == table->column_types) | |
1233 | { | ||
1234 | ✗ | break; | |
1235 | } | ||
1236 | |||
1237 | ✗ | table->column_names = gate_arraylist_copy(src_table->column_names); | |
1238 | ✗ | if (NULL == table->column_names) | |
1239 | { | ||
1240 | ✗ | break; | |
1241 | } | ||
1242 | |||
1243 | ✗ | table->rows = gate_arraylist_create(sizeof(gate_arraylist_t), NULL, row_count, NULL, NULL); | |
1244 | ✗ | if (NULL == table->rows) | |
1245 | { | ||
1246 | ✗ | break; | |
1247 | } | ||
1248 | |||
1249 | ✗ | result = GATE_RESULT_OK; | |
1250 | ✗ | for (row = 0; row != row_count; ++row) | |
1251 | { | ||
1252 | ✗ | result = gate_proptable_insert_row(table, row); | |
1253 | ✗ | GATE_BREAK_IF_FAILED(result); | |
1254 | ✗ | for (col = 0; col != col_count; ++col) | |
1255 | { | ||
1256 | ✗ | ptr_src = gate_proptable_get_item_at(src_table, row, col); | |
1257 | ✗ | if (ptr_src) | |
1258 | { | ||
1259 | ✗ | gate_proptable_set_item_at(table, row, col, ptr_src); | |
1260 | } | ||
1261 | } | ||
1262 | } | ||
1263 | ✗ | GATE_BREAK_IF_FAILED(result); | |
1264 | |||
1265 | ✗ | ret = table; | |
1266 | ✗ | table = NULL; | |
1267 | } while (0); | ||
1268 | |||
1269 | ✗ | if (table) | |
1270 | { | ||
1271 | ✗ | gate_proptable_destroy(table); | |
1272 | } | ||
1273 | ✗ | return ret; | |
1274 | } | ||
1275 | |||
1276 | 1 | void gate_proptable_destroy(gate_proptable_t* table) | |
1277 | { | ||
1278 | gate_size_t row_count; | ||
1279 | gate_size_t col_count; | ||
1280 | gate_size_t row; | ||
1281 | gate_size_t col; | ||
1282 | gate_arraylist_t* ptr_cols; | ||
1283 | gate_property_t* ptr_prop; | ||
1284 | |||
1285 | 1 | row_count = gate_arraylist_length(table->rows); | |
1286 | |||
1287 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
|
2 | for (row = 0; row < row_count; ++row) |
1288 | { | ||
1289 | 1 | ptr_cols = (gate_arraylist_t*)gate_arraylist_get(table->rows, row); | |
1290 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (ptr_cols) |
1291 | { | ||
1292 | 1 | col_count = gate_arraylist_length(*ptr_cols); | |
1293 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
|
3 | for (col = 0; col < col_count; ++col) |
1294 | { | ||
1295 | 2 | ptr_prop = (gate_property_t*)gate_arraylist_get(*ptr_cols, col); | |
1296 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if (ptr_prop) |
1297 | { | ||
1298 | 2 | gate_property_destroy(ptr_prop); | |
1299 | } | ||
1300 | } | ||
1301 | 1 | gate_arraylist_release(*ptr_cols); | |
1302 | } | ||
1303 | } | ||
1304 | 1 | gate_arraylist_release(table->rows); | |
1305 | 1 | gate_arraylist_release(table->column_names); | |
1306 | 1 | gate_arraylist_release(table->column_types); | |
1307 | 1 | gate_mem_clear(table, sizeof(gate_proptable_t)); | |
1308 | 1 | } | |
1309 | |||
1310 | 4 | gate_result_t gate_proptable_insert_column(gate_proptable_t* table, gate_string_t const* column_name, | |
1311 | gate_property_typeid_t prop_type, gate_size_t insert_at) | ||
1312 | { | ||
1313 | 4 | gate_result_t ret = GATE_RESULT_FAILED; | |
1314 | gate_size_t length; | ||
1315 | gate_size_t index; | ||
1316 | gate_arraylist_t* ptr_cols; | ||
1317 | |||
1318 | do | ||
1319 | { | ||
1320 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
|
4 | if (gate_string_is_empty(column_name)) |
1321 | { | ||
1322 | ✗ | ret = GATE_RESULT_INVALIDARG; | |
1323 | ✗ | break; | |
1324 | } | ||
1325 | 4 | ret = gate_proptable_resolve_column(table, column_name, NULL); | |
1326 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (GATE_SUCCEEDED(ret)) |
1327 | { | ||
1328 | ✗ | ret = GATE_RESULT_ALREADYEXISTS; | |
1329 | ✗ | break; | |
1330 | } | ||
1331 | |||
1332 | 4 | length = gate_arraylist_length(table->column_names); | |
1333 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | if (insert_at > length) |
1334 | { | ||
1335 | 4 | insert_at = length; | |
1336 | } | ||
1337 | |||
1338 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
|
4 | if (NULL == gate_arraylist_insert(table->column_names, insert_at, column_name, 1)) |
1339 | { | ||
1340 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
1341 | ✗ | break; | |
1342 | } | ||
1343 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
|
4 | if (NULL == gate_arraylist_insert(table->column_types, insert_at, &prop_type, 1)) |
1344 | { | ||
1345 | ✗ | gate_arraylist_remove(table->column_names, insert_at, 1); | |
1346 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
1347 | ✗ | break; | |
1348 | } | ||
1349 | |||
1350 | 4 | length = gate_arraylist_length(table->rows); | |
1351 | 4 | ret = GATE_RESULT_OK; | |
1352 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
|
5 | for (index = 0; index != length; ++index) |
1353 | { | ||
1354 | 1 | ptr_cols = (gate_arraylist_t*)gate_arraylist_get(table->rows, index); | |
1355 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (ptr_cols) |
1356 | { | ||
1357 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | if (NULL == gate_arraylist_insert(*ptr_cols, insert_at, &gate_proptable_empty_prop, 1)) |
1358 | { | ||
1359 | /* error case, remove all previously inserted entries */ | ||
1360 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
1361 | ✗ | while (index > 0) | |
1362 | { | ||
1363 | ✗ | --index; | |
1364 | ✗ | ptr_cols = (gate_arraylist_t*)gate_arraylist_get(table->rows, index); | |
1365 | ✗ | if (ptr_cols) | |
1366 | { | ||
1367 | ✗ | gate_arraylist_remove(*ptr_cols, insert_at, 1); | |
1368 | } | ||
1369 | } | ||
1370 | ✗ | gate_arraylist_remove(table->column_types, insert_at, 1); | |
1371 | ✗ | gate_arraylist_remove(table->column_names, insert_at, 1); | |
1372 | ✗ | break; | |
1373 | } | ||
1374 | } | ||
1375 | } | ||
1376 | 4 | ret = GATE_RESULT_OK; | |
1377 | } while (0); | ||
1378 | 4 | return ret; | |
1379 | } | ||
1380 | |||
1381 | 1 | gate_result_t gate_proptable_remove_column(gate_proptable_t* table, gate_string_t const* column_name) | |
1382 | { | ||
1383 | gate_size_t match_index; | ||
1384 | 1 | gate_result_t ret = gate_proptable_resolve_column(table, column_name, &match_index); | |
1385 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (GATE_SUCCEEDED(ret)) |
1386 | { | ||
1387 | 1 | ret = gate_proptable_remove_column_at(table, match_index); | |
1388 | } | ||
1389 | 1 | return ret; | |
1390 | } | ||
1391 | |||
1392 | 2 | gate_result_t gate_proptable_remove_column_at(gate_proptable_t* table, gate_size_t index) | |
1393 | { | ||
1394 | gate_size_t row; | ||
1395 | 2 | gate_size_t length = gate_arraylist_length(table->column_names); | |
1396 | gate_arraylist_t* ptr_columns; | ||
1397 | |||
1398 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (index >= length) |
1399 | { | ||
1400 | ✗ | return GATE_RESULT_OUTOFBOUNDS; | |
1401 | } | ||
1402 | 2 | gate_arraylist_remove(table->column_names, index, 1); | |
1403 | 2 | gate_arraylist_remove(table->column_types, index, 1); | |
1404 | |||
1405 | 2 | length = gate_arraylist_length(table->rows); | |
1406 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | for (row = 0; row != length; ++row) |
1407 | { | ||
1408 | ✗ | ptr_columns = (gate_arraylist_t*)gate_arraylist_get(table->rows, row); | |
1409 | ✗ | if (ptr_columns) | |
1410 | { | ||
1411 | ✗ | gate_arraylist_remove(*ptr_columns, index, 1); | |
1412 | } | ||
1413 | } | ||
1414 | 2 | return GATE_RESULT_OK; | |
1415 | } | ||
1416 | |||
1417 | 2 | gate_result_t gate_proptable_set_column_name(gate_proptable_t* table, gate_size_t index, gate_string_t const* new_name) | |
1418 | { | ||
1419 | 2 | gate_result_t ret = GATE_RESULT_FAILED; | |
1420 | gate_string_t* ptr_name; | ||
1421 | 2 | gate_string_t tmp = GATE_STRING_INIT_EMPTY; | |
1422 | do | ||
1423 | { | ||
1424 | 2 | ret = gate_proptable_resolve_column(table, new_name, NULL); | |
1425 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (GATE_SUCCEEDED(ret)) |
1426 | { | ||
1427 | ✗ | ret = GATE_RESULT_ALREADYEXISTS; | |
1428 | ✗ | break; | |
1429 | } | ||
1430 | 2 | ptr_name = (gate_string_t*)gate_arraylist_get(table->column_names, index); | |
1431 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (ptr_name == NULL) |
1432 | { | ||
1433 | ✗ | ret = GATE_RESULT_OUTOFBOUNDS; | |
1434 | ✗ | break; | |
1435 | } | ||
1436 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | if (NULL == gate_string_duplicate(&tmp, new_name)) |
1437 | { | ||
1438 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
1439 | ✗ | break; | |
1440 | } | ||
1441 | 2 | gate_string_release(ptr_name); | |
1442 | 2 | gate_mem_copy(ptr_name, &tmp, sizeof(gate_string_t)); | |
1443 | 2 | ret = GATE_RESULT_OK; | |
1444 | } while (0); | ||
1445 | |||
1446 | 2 | return ret; | |
1447 | } | ||
1448 | |||
1449 | 14 | gate_result_t gate_proptable_resolve_column(gate_proptable_t const* table, gate_string_t const* name, gate_size_t* match_index) | |
1450 | { | ||
1451 | gate_size_t index; | ||
1452 | 14 | gate_size_t length = gate_arraylist_length(table->column_names); | |
1453 | gate_string_t const* ptr_name; | ||
1454 | |||
1455 |
2/2✓ Branch 0 taken 13 times.
✓ Branch 1 taken 6 times.
|
19 | for (index = 0; index != length; ++index) |
1456 | { | ||
1457 | 13 | ptr_name = (gate_string_t const*)gate_arraylist_get(table->column_names, index); | |
1458 |
1/2✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
|
13 | if (ptr_name) |
1459 | { | ||
1460 |
2/2✓ Branch 1 taken 8 times.
✓ Branch 2 taken 5 times.
|
13 | if (gate_string_equals(ptr_name, name)) |
1461 | { | ||
1462 |
1/2✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
|
8 | if (match_index) |
1463 | { | ||
1464 | 8 | *match_index = index; | |
1465 | } | ||
1466 | 8 | return GATE_RESULT_OK; | |
1467 | } | ||
1468 | } | ||
1469 | } | ||
1470 | 6 | return GATE_RESULT_NOMATCH; | |
1471 | } | ||
1472 | |||
1473 | |||
1474 | 12 | gate_size_t gate_proptable_get_column_count(gate_proptable_t const* table) | |
1475 | { | ||
1476 | 12 | return gate_arraylist_length(table->column_names); | |
1477 | } | ||
1478 | |||
1479 | 1 | gate_result_t gate_proptable_get_column_name(gate_proptable_t const* table, gate_size_t index, gate_string_t* ptr_name) | |
1480 | { | ||
1481 | 1 | gate_string_t const* name = (gate_string_t const*)gate_arraylist_get(table->column_names, index); | |
1482 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (name) |
1483 | { | ||
1484 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (ptr_name) |
1485 | { | ||
1486 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | if (NULL == gate_string_duplicate(ptr_name, name)) |
1487 | { | ||
1488 | ✗ | return GATE_RESULT_OUTOFMEMORY; | |
1489 | } | ||
1490 | } | ||
1491 | 1 | return GATE_RESULT_OK; | |
1492 | } | ||
1493 | ✗ | return GATE_RESULT_OUTOFBOUNDS; | |
1494 | } | ||
1495 | ✗ | gate_property_typeid_t gate_proptable_get_column_type(gate_proptable_t const* table, gate_size_t index) | |
1496 | { | ||
1497 | ✗ | gate_property_typeid_t const* ptr_type = (gate_property_typeid_t const*)gate_arraylist_get(table->column_types, index); | |
1498 | ✗ | if (ptr_type) | |
1499 | { | ||
1500 | ✗ | return *ptr_type; | |
1501 | } | ||
1502 | ✗ | return GATE_PROPERTY_TYPE_EMPTY; | |
1503 | } | ||
1504 | |||
1505 | 7 | gate_size_t gate_proptable_get_row_count(gate_proptable_t const* table) | |
1506 | { | ||
1507 | 7 | return gate_arraylist_length(table->rows); | |
1508 | } | ||
1509 | |||
1510 | 4 | gate_property_t const* gate_proptable_get_item(gate_proptable_t const* table, gate_size_t row, gate_string_t const* column) | |
1511 | { | ||
1512 | gate_size_t column_index; | ||
1513 | 4 | gate_result_t result = gate_proptable_resolve_column(table, column, &column_index); | |
1514 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | if (GATE_SUCCEEDED(result)) |
1515 | { | ||
1516 | 4 | return gate_proptable_get_item_at(table, row, column_index); | |
1517 | } | ||
1518 | ✗ | return NULL; | |
1519 | } | ||
1520 | |||
1521 | 7 | gate_property_t const* gate_proptable_get_item_at(gate_proptable_t const* table, gate_size_t row, gate_size_t column) | |
1522 | { | ||
1523 | 7 | gate_property_t const* ret = NULL; | |
1524 | gate_arraylist_t const* ptr_row; | ||
1525 | do | ||
1526 | { | ||
1527 | 7 | ptr_row = (gate_arraylist_t const*)gate_arraylist_get(table->rows, row); | |
1528 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
|
7 | if (!ptr_row) |
1529 | { | ||
1530 | ✗ | break; | |
1531 | } | ||
1532 | 7 | ret = (gate_property_t const*)gate_arraylist_get(*ptr_row, column); | |
1533 | } while (0); | ||
1534 | 7 | return ret; | |
1535 | } | ||
1536 | ✗ | gate_result_t gate_proptable_get_row(gate_proptable_t const* table, gate_size_t row, gate_property_t* prop) | |
1537 | { | ||
1538 | ✗ | gate_result_t ret = GATE_RESULT_FAILED; | |
1539 | gate_arraylist_t const* ptr_row; | ||
1540 | ✗ | gate_property_t* ptr_cleanup = NULL; | |
1541 | gate_size_t count; | ||
1542 | gate_size_t index; | ||
1543 | ✗ | gate_string_t colname = GATE_STRING_INIT_EMPTY; | |
1544 | gate_property_t const* ptr_prop; | ||
1545 | |||
1546 | do | ||
1547 | { | ||
1548 | ✗ | ptr_row = (gate_arraylist_t const*)gate_arraylist_get(table->rows, row); | |
1549 | ✗ | if (!ptr_row) | |
1550 | { | ||
1551 | ✗ | ret = GATE_RESULT_OUTOFBOUNDS; | |
1552 | ✗ | break; | |
1553 | } | ||
1554 | |||
1555 | ✗ | if (NULL == gate_property_create_object(prop)) | |
1556 | { | ||
1557 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
1558 | ✗ | break; | |
1559 | } | ||
1560 | ✗ | ptr_cleanup = prop; | |
1561 | |||
1562 | ✗ | count = gate_proptable_get_column_count(table); | |
1563 | ✗ | ret = GATE_RESULT_OK; | |
1564 | ✗ | for (index = 0; index != count; ++index) | |
1565 | { | ||
1566 | ✗ | ptr_prop = gate_proptable_get_item_at(table, row, index); | |
1567 | ✗ | if (!ptr_prop) | |
1568 | { | ||
1569 | ✗ | continue; | |
1570 | } | ||
1571 | |||
1572 | ✗ | ret = gate_proptable_get_column_name(table, index, &colname); | |
1573 | ✗ | GATE_BREAK_IF_FAILED(ret); | |
1574 | ✗ | if (NULL == gate_property_member_add(prop, &colname, ptr_prop)) | |
1575 | { | ||
1576 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
1577 | } | ||
1578 | ✗ | gate_string_release(&colname); | |
1579 | ✗ | GATE_BREAK_IF_FAILED(ret); | |
1580 | } | ||
1581 | ✗ | GATE_BREAK_IF_FAILED(ret); | |
1582 | ✗ | ptr_cleanup = NULL; | |
1583 | ✗ | ret = GATE_RESULT_OK; | |
1584 | |||
1585 | } while (0); | ||
1586 | |||
1587 | ✗ | if (ptr_cleanup) | |
1588 | { | ||
1589 | ✗ | gate_property_destroy(ptr_cleanup); | |
1590 | } | ||
1591 | ✗ | return ret; | |
1592 | } | ||
1593 | |||
1594 | 2 | gate_result_t gate_proptable_insert_row(gate_proptable_t* table, gate_size_t row) | |
1595 | { | ||
1596 | 2 | gate_result_t ret = GATE_RESULT_FAILED; | |
1597 | 2 | gate_size_t row_count = gate_proptable_get_row_count(table); | |
1598 | 2 | gate_size_t column_count = gate_proptable_get_column_count(table); | |
1599 | 2 | gate_arraylist_t new_row = NULL; | |
1600 | |||
1601 | do | ||
1602 | { | ||
1603 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if (row > row_count) |
1604 | { | ||
1605 | 2 | row = row_count; | |
1606 | } | ||
1607 | |||
1608 | 2 | new_row = gate_arraylist_create(sizeof(gate_property_t), NULL, column_count, NULL, NULL); | |
1609 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (NULL == new_row) |
1610 | { | ||
1611 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
1612 | ✗ | break; | |
1613 | } | ||
1614 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | if (NULL == gate_arraylist_add_n(new_row, &gate_proptable_empty_prop, column_count)) |
1615 | { | ||
1616 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
1617 | ✗ | break; | |
1618 | } | ||
1619 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | if (NULL == gate_arraylist_insert(table->rows, row, &new_row, 1)) |
1620 | { | ||
1621 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
1622 | } | ||
1623 | |||
1624 | 2 | ret = GATE_RESULT_OK; | |
1625 | 2 | new_row = NULL; | |
1626 | } while (0); | ||
1627 | |||
1628 | 2 | gate_arraylist_release(new_row); | |
1629 | 2 | return ret; | |
1630 | } | ||
1631 | |||
1632 | 1 | gate_result_t gate_proptable_remove_row(gate_proptable_t* table, gate_size_t row) | |
1633 | { | ||
1634 | 1 | gate_arraylist_t* ptr_colarray = (gate_arraylist_t*)gate_arraylist_get(table->rows, row); | |
1635 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | gate_arraylist_t colarray = ptr_colarray ? *ptr_colarray : NULL; |
1636 | 1 | gate_result_t result = gate_arraylist_remove(table->rows, row, 1); | |
1637 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | if (GATE_SUCCEEDED(result) && (colarray != NULL)) |
1638 | { | ||
1639 | /* the column-array was removed from rows, now release the column array manually */ | ||
1640 | 1 | gate_size_t entries_count = gate_arraylist_length(colarray); | |
1641 | gate_size_t ndx; | ||
1642 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
|
2 | for (ndx = 0; ndx != entries_count; ++ndx) |
1643 | { | ||
1644 | 1 | gate_property_t* ptr_entry = gate_arraylist_get(colarray, ndx); | |
1645 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (ptr_entry) |
1646 | { | ||
1647 | 1 | gate_property_destroy(ptr_entry); | |
1648 | } | ||
1649 | } | ||
1650 | 1 | gate_arraylist_release(colarray); | |
1651 | } | ||
1652 | 1 | return result; | |
1653 | } | ||
1654 | |||
1655 | 2 | gate_result_t gate_proptable_set_item(gate_proptable_t* table, gate_size_t row, gate_string_t const* column, gate_property_t const* prop) | |
1656 | { | ||
1657 | 2 | gate_size_t match_index = 0; | |
1658 | 2 | gate_result_t ret = gate_proptable_resolve_column(table, column, &match_index); | |
1659 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if (GATE_SUCCEEDED(ret)) |
1660 | { | ||
1661 | 2 | ret = gate_proptable_set_item_at(table, row, match_index, prop); | |
1662 | } | ||
1663 | 2 | return ret; | |
1664 | } | ||
1665 | |||
1666 | 3 | gate_result_t gate_proptable_set_item_at(gate_proptable_t* table, gate_size_t row, gate_size_t column, gate_property_t const* prop) | |
1667 | { | ||
1668 | 3 | gate_result_t ret = GATE_RESULT_FAILED; | |
1669 | gate_arraylist_t* ptr_row; | ||
1670 | gate_property_t* ptr_prop; | ||
1671 | |||
1672 | do | ||
1673 | { | ||
1674 | 3 | ptr_row = (gate_arraylist_t*)gate_arraylist_get(table->rows, row); | |
1675 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | if (!ptr_row) |
1676 | { | ||
1677 | ✗ | ret = GATE_RESULT_OUTOFBOUNDS; | |
1678 | ✗ | break; | |
1679 | } | ||
1680 | |||
1681 | 3 | ptr_prop = gate_arraylist_get(*ptr_row, column); | |
1682 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | if (!ptr_prop) |
1683 | { | ||
1684 | ✗ | ret = GATE_RESULT_OUTOFBOUNDS; | |
1685 | ✗ | break; | |
1686 | } | ||
1687 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
|
3 | if (NULL == gate_property_copy(ptr_prop, prop)) |
1688 | { | ||
1689 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
1690 | ✗ | break; | |
1691 | } | ||
1692 | 3 | ret = GATE_RESULT_OK; | |
1693 | } while (0); | ||
1694 | |||
1695 | 3 | return ret; | |
1696 | } | ||
1697 |