GCC Code Coverage Report


Directory: src/gate/
File: src/gate/properties.c
Date: 2025-12-12 23:40:09
Exec Total Coverage
Lines: 393 827 47.5%
Functions: 46 56 82.1%
Branches: 130 432 30.1%

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