GCC Code Coverage Report


Directory: src/gate/
File: src/gate/properties.c
Date: 2026-10-19 17:06:30
Exec Total Coverage
Lines: 518 803 64.5%
Functions: 50 55 90.9%
Branches: 184 424 43.4%

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