GCC Code Coverage Report


Directory: src/gate/
File: src/gate/arrays.c
Date: 2025-09-14 13:10:38
Exec Total Coverage
Lines: 699 838 83.4%
Functions: 81 84 96.4%
Branches: 248 392 63.3%

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/arrays.h"
30 #include "gate/results.h"
31 #include "gate/debugging.h"
32 #include "gate/atomics.h"
33
34 struct gate_arraylist_class
35 {
36 char* data_ptr; /* pointer to first item in array */
37 gate_size_t item_size; /* size of one item in bytes */
38 gate_size_t item_offset; /* offset in data_ptr where first item is located */
39 gate_size_t item_count; /* amount of valid items in array */
40 gate_size_t item_capacity; /* amount of possible items in allocated array space */
41 gate_atomic_int_t ref_counter; /* usage reference count of arraylist */
42 gate_mem_copyctor_t construct_item; /* copy-constructor function of a single item */
43 gate_mem_dtor_t destruct_item; /* destructor function of a single item */
44 };
45
46 125 gate_array_t* gate_array_create_static(gate_array_t* arr, void const* data_ptr, gate_size_t item_size, gate_size_t item_count)
47 {
48 125 GATE_DEBUG_ASSERT(arr != NULL);
49
50 125 arr->data_ptr = data_ptr;
51 125 arr->item_size = item_size;
52 125 arr->item_count = item_count;
53 125 arr->array_list = NULL;
54 125 return arr;
55 }
56 780 gate_array_t* gate_array_create_empty(gate_array_t* arr)
57 {
58 780 GATE_DEBUG_ASSERT(arr != NULL);
59
60 780 arr->data_ptr = NULL;
61 780 arr->item_size = 0;
62 780 arr->item_count = 0;
63 780 arr->array_list = NULL;
64 780 return arr;
65 }
66 294 gate_array_t* gate_array_create(gate_array_t* arr, gate_arraylist_t arraylist)
67 {
68 gate_arraylist_t tmp_array_list;
69
70 294 GATE_DEBUG_ASSERT(arr != NULL);
71
72
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 294 times.
294 if (arraylist == NULL)
73 {
74 gate_array_create_empty(arr);
75 }
76 else
77 {
78
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 294 times.
294 if (gate_atomic_int_dec(&arraylist->ref_counter) != 0)
79 {
80 /* array data MUST NOT be used by multiple instances
81 and MUST NOT be shared between threads */
82 arr = NULL;
83 }
84 else
85 {
86 294 tmp_array_list = gate_mem_alloc(sizeof(struct gate_arraylist_class));
87
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 294 times.
294 if (tmp_array_list == NULL)
88 {
89 arr = NULL;
90 }
91 else
92 {
93 /* transferring all arraylist-members into array */
94 294 gate_atomic_int_init(&tmp_array_list->ref_counter, 1);
95 294 tmp_array_list->data_ptr = arraylist->data_ptr;
96 294 tmp_array_list->item_offset = arraylist->item_offset;
97 294 tmp_array_list->item_size = arraylist->item_size;
98 294 tmp_array_list->item_count = arraylist->item_count;
99 294 tmp_array_list->item_capacity = arraylist->item_capacity;
100 294 tmp_array_list->construct_item = arraylist->construct_item;
101 294 tmp_array_list->destruct_item = arraylist->destruct_item;
102
103 294 arr->array_list = tmp_array_list;
104
105 /* cleaning up original arraylist */
106 294 arraylist->data_ptr = NULL;
107 294 arraylist->item_size = 0;
108 294 arraylist->item_offset = 0;
109 294 arraylist->item_count = 0;
110 294 arraylist->item_capacity = 0;
111
112
2/2
✓ Branch 0 taken 185 times.
✓ Branch 1 taken 109 times.
294 if (arr->array_list->data_ptr == NULL)
113 {
114 /* pointer arithmetic on NULL-ptrs is UB */
115 185 arr->data_ptr = NULL;
116 }
117 else
118 {
119 109 arr->data_ptr = arr->array_list->data_ptr + (arr->array_list->item_size * arr->array_list->item_offset);
120 }
121 294 arr->item_size = arr->array_list->item_size;
122 294 arr->item_count = arr->array_list->item_count;
123 }
124 }
125 294 gate_atomic_int_inc(&arraylist->ref_counter);
126 }
127 294 return arr;
128 }
129
130 1 gate_array_t* gate_array_copy(gate_array_t* arr, gate_array_t const* src)
131 {
132 1 gate_array_t* ret = NULL;
133 1 gate_arraylist_t copylist = NULL;
134
135 1 GATE_DEBUG_ASSERT(arr != NULL);
136 1 GATE_DEBUG_ASSERT(src != NULL);
137
138
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (src->array_list == NULL)
139 {
140 copylist = gate_arraylist_create(src->item_size, src->data_ptr, src->item_count, NULL, NULL);
141 }
142 else
143 {
144 2 copylist = gate_arraylist_create(src->item_size, src->data_ptr, src->item_count,
145 1 src->array_list->construct_item, src->array_list->destruct_item);
146 }
147
148
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (copylist == NULL)
149 {
150 return NULL;
151 }
152
153 1 ret = gate_array_create(arr, copylist);
154 1 gate_arraylist_release(copylist);
155 1 return ret;
156 }
157
158 1752 gate_array_t* gate_array_duplicate(gate_array_t* dest, gate_array_t const* src)
159 {
160 1752 GATE_DEBUG_ASSERT(dest != NULL);
161
162
2/2
✓ Branch 0 taken 1353 times.
✓ Branch 1 taken 399 times.
1752 if (src != NULL)
163 {
164
2/2
✓ Branch 0 taken 242 times.
✓ Branch 1 taken 1111 times.
1353 if (src->array_list != NULL)
165 {
166 242 gate_arraylist_retain(src->array_list);
167 }
168 1353 dest->array_list = src->array_list;
169 1353 dest->item_size = src->item_size;
170 1353 dest->item_count = src->item_count;
171 1353 dest->data_ptr = src->data_ptr;
172 }
173 else
174 {
175 399 gate_array_create_empty(dest);
176 }
177 1752 return dest;
178 }
179 1 gate_array_t* gate_array_subset(gate_array_t* dest, gate_array_t const* arr, gate_size_t offset, gate_size_t count)
180 {
181 char const* ptr;
182
183 1 GATE_DEBUG_ASSERT(dest != NULL);
184
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (arr == NULL)
185 {
186 gate_array_create_empty(dest);
187 }
188 else
189 {
190
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (arr->array_list != NULL)
191 {
192 1 gate_arraylist_retain(arr->array_list);
193 }
194 1 dest->array_list = arr->array_list;
195 1 ptr = (char const*)arr->data_ptr;
196
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 if ((ptr != NULL) && (offset < arr->item_count))
197 {
198 1 ptr += arr->item_size * offset;
199
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (count > arr->item_count - offset)
200 {
201 count = arr->item_count - offset;
202 }
203 }
204 else
205 {
206 ptr = NULL;
207 count = 0;
208 }
209 1 dest->item_size = arr->item_size;
210 1 dest->item_count = count;
211 1 dest->data_ptr = ptr;
212
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 if ((count == 0) && (arr->array_list != NULL))
213 {
214 gate_arraylist_release(arr->array_list);
215 }
216 }
217 1 return dest;
218 }
219
220 4051 void gate_array_release(gate_array_t* arr)
221 {
222 4051 GATE_DEBUG_ASSERT(arr != NULL);
223
224
2/2
✓ Branch 0 taken 537 times.
✓ Branch 1 taken 3514 times.
4051 if (arr->array_list != NULL)
225 {
226 537 gate_arraylist_release(arr->array_list);
227 }
228 4051 arr->data_ptr = NULL;
229 4051 arr->item_count = 0;
230 4051 arr->item_size = 0;
231 4051 arr->array_list = NULL;
232 4051 }
233 601 gate_size_t gate_array_length(gate_array_t const* arr)
234 {
235 gate_size_t ret;
236
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 601 times.
601 if (arr == NULL)
237 {
238 ret = 0;
239 }
240 else
241 {
242 601 ret = arr->item_count;
243 }
244 601 return ret;
245 }
246 1536 void const* gate_array_get(gate_array_t const* arr, gate_size_t index)
247 {
248 1536 void const* ret = NULL;
249 char const* ptr;
250
251 1536 GATE_DEBUG_ASSERT(arr != NULL);
252
253
2/4
✓ Branch 0 taken 1536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1536 times.
✗ Branch 3 not taken.
1536 if ((index < arr->item_count) && (arr->data_ptr != NULL))
254 {
255 1536 ptr = (char const*)arr->data_ptr;
256 1536 ptr += (arr->item_size * index);
257 1536 ret = (void const*)ptr;
258 }
259 1536 return ret;
260 }
261
262 1032 static gate_bool_t gate_array_enumerate_is_valid(gate_enumerator_t const* enumerator)
263 {
264 1032 GATE_DEBUG_ASSERT(enumerator != NULL);
265 1032 return enumerator->current_position < enumerator->end_position;
266 }
267 1028 static gate_bool_t gate_array_enumerate_next(gate_enumerator_t* enumerator)
268 {
269 gate_array_t* arr;
270
271 1028 GATE_DEBUG_ASSERT(enumerator != NULL);
272 1028 arr = (gate_array_t*)enumerator->ptr_origin;
273
274
1/2
✓ Branch 0 taken 1028 times.
✗ Branch 1 not taken.
1028 if (enumerator->current_position != NULL)
275 {
276 1028 enumerator->current_position = (void*)((char*)enumerator->current_position + arr->item_size);
277 }
278 1028 return enumerator->current_position < enumerator->end_position;
279 }
280 1028 static void const* gate_array_enumerate_get(gate_enumerator_t const* enumerator)
281 {
282 1028 GATE_DEBUG_ASSERT(enumerator != NULL);
283 1028 return (void const*)enumerator->current_position;
284 }
285
286 4 gate_enumerator_t* gate_array_enumerate(gate_array_t const* arr, gate_enumerator_t* enumerator)
287 {
288 4 GATE_DEBUG_ASSERT(arr != NULL);
289 4 GATE_DEBUG_ASSERT(enumerator != NULL);
290
291 4 enumerator->is_valid = &gate_array_enumerate_is_valid;
292 4 enumerator->next = &gate_array_enumerate_next;
293 4 enumerator->get = &gate_array_enumerate_get;
294 4 enumerator->ptr_origin = arr;
295 4 enumerator->current_position = (void*)arr->data_ptr;
296
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (enumerator->current_position != NULL)
297 {
298 4 enumerator->end_position = (void*)((char*)enumerator->current_position + (arr->item_size * arr->item_count));
299 }
300 else
301 {
302 enumerator->end_position = NULL;
303 }
304 4 return enumerator;
305 }
306
307 1 gate_result_t gate_array_copy_constructor(void* dst, void const* src)
308 {
309 1 gate_array_t const* srcarray = (gate_array_t const*)src;
310 1 gate_array_t* dstarray = (gate_array_t*)dst;
311
312 1 GATE_DEBUG_ASSERT(dst != NULL);
313
314
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (NULL == gate_array_duplicate(dstarray, srcarray))
315 {
316 return GATE_RESULT_OUTOFMEMORY;
317 }
318 1 return GATE_RESULT_OK;
319 }
320 1 void gate_array_destructor(void* dst)
321 {
322 1 gate_array_t* dstarray = (gate_array_t*)dst;
323 1 GATE_DEBUG_ASSERT(dst != NULL);
324 1 gate_array_release(dstarray);
325 1 }
326
327 1 void* gate_array_sort(void* items, gate_size_t item_size, gate_size_t items_count, gate_comparer_t comparer,
328 gate_mem_copyctor_t copy_constructor, gate_mem_dtor_t destructor)
329 {
330 1 char* ptr1 = (char*)items;
331 char* ptr2;
332 char* ptr_end;
333 char* ptr_end1;
334 gate_intptr_t cmp;
335
336 1 GATE_DEBUG_ASSERT(ptr1 != NULL);
337
338 1 ptr_end = ptr1 + items_count * item_size;
339 1 ptr_end1 = ptr_end - item_size;
340
341
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 times.
8 for (; ptr1 != ptr_end1; ptr1 += item_size)
342 {
343
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 7 times.
35 for (ptr2 = ptr1 + item_size; ptr2 != ptr_end; ptr2 += item_size)
344 {
345 28 cmp = gate_compare_types(ptr1, ptr2, item_size, comparer);
346
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 if (cmp > 0)
347 {
348
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
28 if (!gate_mem_swap(ptr1, ptr2, item_size, copy_constructor, destructor))
349 {
350 return NULL;
351 }
352 }
353 }
354 }
355 1 return items;
356 }
357
358 1 void* gate_array_sort_descending(void* items, gate_size_t item_size, gate_size_t items_count, gate_comparer_t comparer,
359 gate_mem_copyctor_t copy_constructor, gate_mem_dtor_t destructor)
360 {
361 1 char* ptr1 = (char*)items;
362 char* ptr2;
363 char* ptr_end;
364 char* ptr_end1;
365
366 1 GATE_DEBUG_ASSERT(ptr1 != NULL);
367
368 1 ptr_end = ptr1 + items_count * item_size;
369 1 ptr_end1 = ptr_end - item_size;
370
371
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 times.
8 for (; ptr1 != ptr_end1; ptr1 += item_size)
372 {
373
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 7 times.
35 for (ptr2 = ptr1 + item_size; ptr2 != ptr_end; ptr2 += item_size)
374 {
375
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 if (comparer(ptr1, ptr2) < 0)
376 {
377
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
28 if (!gate_mem_swap(ptr1, ptr2, item_size, copy_constructor, destructor))
378 {
379 return NULL;
380 }
381 }
382 }
383 }
384
385 1 return items;
386 }
387
388 1 gate_size_t gate_array_remove_if(void* items, gate_size_t item_size, gate_size_t item_count,
389 gate_check_condition_t condition_callback, void* param,
390 gate_mem_copyctor_t copy_constructor, gate_mem_dtor_t destructor)
391 {
392 1 gate_size_t new_item_count = 0;
393 1 char* ptr = (char*)items;
394 1 char* ptrend = ptr;
395
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
9 while (item_count != 0)
396 {
397
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
8 if (condition_callback(ptr, param))
398 {
399 /* to be deleted */
400 4 gate_mem_destruct(ptr, destructor);
401 }
402 else
403 {
404 /* to be preserved -> move it to (new) end */
405
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 if (ptr != ptrend)
406 {
407 3 gate_mem_swap(ptr, ptrend, item_size, copy_constructor, destructor);
408 3 gate_mem_destruct(ptr, destructor);
409 }
410 4 ptrend += item_size;
411 4 ++new_item_count;
412 }
413
414 8 ptr += item_size;
415 8 --item_count;
416 }
417 1 return new_item_count;
418 }
419
420 /*******************************
421 * arraylist implementation **
422 *******************************/
423
424 167 static char* gate_arraylist_copy_items(char* dstptr, char const* srcptr, gate_size_t count, gate_size_t itemsize, gate_mem_copyctor_t ctor, gate_mem_dtor_t dtor)
425 {
426 gate_size_t constructed;
427 gate_result_t result;
428
429
2/4
✓ Branch 0 taken 167 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 167 times.
167 if (!dstptr || !srcptr)
430 {
431 GATE_DEBUG_TRACE("Invalid input");
432 }
433
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 166 times.
167 else if (ctor == NULL)
434 {
435 1 gate_mem_copy(dstptr, srcptr, count * itemsize);
436 }
437 else
438 {
439
2/2
✓ Branch 0 taken 3935 times.
✓ Branch 1 taken 166 times.
4101 for (constructed = 0; constructed != count; ++constructed)
440 {
441 3935 result = ctor(dstptr, srcptr);
442
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3935 times.
3935 if (GATE_FAILED(result))
443 {
444 /* construction failed */
445 if (dtor != NULL)
446 {
447 while (constructed-- != 0)
448 {
449 dstptr -= itemsize;
450 dtor(dstptr);
451 }
452 dstptr = NULL;
453 break;
454 }
455 }
456 3935 srcptr += itemsize;
457 3935 dstptr += itemsize;
458 }
459 }
460 167 return dstptr;
461 }
462
463 static void gate_arraylist_defrag(gate_arraylist_t arr)
464 {
465 char* dst;
466 char* src;
467 gate_size_t count;
468
469 GATE_DEBUG_ASSERT(arr != NULL);
470
471 if ((arr->data_ptr != NULL) && (arr->item_offset > 0))
472 {
473 src = arr->data_ptr + (arr->item_offset * arr->item_size);
474 dst = arr->data_ptr;
475 if (arr->construct_item || arr->destruct_item)
476 {
477 count = arr->item_count;
478 while (count-- > 0)
479 {
480 if (arr->construct_item)
481 {
482 arr->construct_item(dst, src);
483 }
484 else
485 {
486 gate_mem_copy(dst, src, arr->item_size);
487 }
488 if (arr->destruct_item)
489 {
490 arr->destruct_item(src);
491 }
492 src += arr->item_size;
493 dst += arr->item_size;
494 }
495 }
496 else
497 {
498 gate_mem_move(dst, src, (arr->item_size * arr->item_count));
499 }
500 arr->item_offset = 0;
501 }
502 }
503
504 239 static gate_arraylist_t gate_arraylist_reserve(gate_arraylist_t arr, gate_size_t capacity)
505 {
506 char* newbuffer;
507 gate_size_t oldbuffersize;
508 gate_size_t newbuffersize;
509 char* srcptr;
510 char* dstptr;
511 gate_size_t constructed;
512
513 239 GATE_DEBUG_ASSERT(arr != NULL);
514
515
1/2
✓ Branch 0 taken 239 times.
✗ Branch 1 not taken.
239 if (capacity > arr->item_capacity)
516 {
517 239 newbuffersize = arr->item_size * capacity;
518 239 newbuffer = gate_mem_alloc(newbuffersize);
519
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 239 times.
239 if (newbuffer == NULL)
520 {
521 return NULL;
522 }
523
3/4
✓ Branch 0 taken 147 times.
✓ Branch 1 taken 92 times.
✓ Branch 2 taken 147 times.
✗ Branch 3 not taken.
239 if ((arr->item_count != 0) && (arr->data_ptr != NULL))
524 {
525 147 srcptr = arr->data_ptr + (arr->item_offset * arr->item_size);
526
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 122 times.
147 if (arr->construct_item == NULL)
527 {
528 25 oldbuffersize = arr->item_size * arr->item_count;
529 25 gate_mem_copy(newbuffer, srcptr, oldbuffersize);
530 }
531 else
532 {
533
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 122 times.
122 if (gate_arraylist_copy_items(newbuffer, srcptr, arr->item_count, arr->item_size, arr->construct_item, arr->destruct_item) == NULL)
534 {
535 /*failed:*/
536 gate_mem_dealloc(newbuffer);
537 return NULL;
538 }
539 }
540
541
2/2
✓ Branch 0 taken 122 times.
✓ Branch 1 taken 25 times.
147 if (arr->destruct_item != NULL)
542 {
543 122 dstptr = arr->data_ptr + (arr->item_offset * arr->item_size);
544
2/2
✓ Branch 0 taken 2628 times.
✓ Branch 1 taken 122 times.
2750 for (constructed = 0; constructed != arr->item_count; ++constructed)
545 {
546 2628 arr->destruct_item(dstptr);
547 2628 dstptr += arr->item_size;
548 }
549 }
550 }
551
2/2
✓ Branch 0 taken 147 times.
✓ Branch 1 taken 92 times.
239 if (arr->data_ptr)
552 {
553 147 gate_mem_dealloc(arr->data_ptr);
554 }
555
556 239 arr->data_ptr = newbuffer;
557 239 arr->item_capacity = capacity;
558 239 arr->item_offset = 0;
559 }
560 else
561 {
562 gate_arraylist_defrag(arr);
563 }
564 239 return arr;
565 }
566
567 389 gate_arraylist_t gate_arraylist_create(gate_size_t itemsize, void const* source, gate_size_t length, gate_mem_copyctor_t ctor, gate_mem_dtor_t dtor)
568 {
569 389 gate_arraylist_t ret = NULL;
570
571
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 389 times.
389 if (itemsize == 0)
572 {
573 return NULL;
574 }
575
576 389 ret = (gate_arraylist_t)gate_mem_alloc(sizeof(struct gate_arraylist_class));
577
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 389 times.
389 if (ret == NULL)
578 {
579 return NULL;
580 }
581 389 gate_atomic_int_init(&ret->ref_counter, 1);
582 389 ret->item_size = itemsize;
583 389 ret->item_capacity = length;
584 389 ret->item_offset = 0;
585 389 ret->construct_item = ctor;
586 389 ret->destruct_item = dtor;
587
2/2
✓ Branch 0 taken 284 times.
✓ Branch 1 taken 105 times.
389 if (length == 0)
588 {
589 284 ret->item_count = 0;
590 284 ret->data_ptr = NULL;
591 }
592 else
593 {
594 105 ret->data_ptr = gate_mem_alloc(itemsize * length);
595
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 105 times.
105 if (ret->data_ptr == NULL)
596 {
597 gate_mem_dealloc(ret);
598 return NULL;
599 }
600
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 45 times.
105 if (source == NULL)
601 {
602 60 ret->item_count = 0;
603 }
604 else
605 {
606
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 45 times.
45 if (gate_arraylist_copy_items((char*)ret->data_ptr, (char const*)source, length, itemsize, ctor, dtor) == NULL)
607 {
608 gate_mem_dealloc(ret->data_ptr);
609 gate_mem_dealloc(ret);
610 return NULL;
611 }
612 45 ret->item_count = length;
613 }
614 }
615 389 return ret;
616 }
617
618 248 gate_arraylist_t gate_arraylist_retain(gate_arraylist_t arr)
619 {
620 248 GATE_DEBUG_ASSERT(arr != NULL);
621
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 248 times.
248 if (gate_atomic_int_inc(&arr->ref_counter) < 2)
622 {
623 /* error! reference count MUST be greater than 2,
624 otherwise array is in currently in destruction process
625 */
626 arr = NULL;
627 }
628 248 return arr;
629 }
630
631 1952 void gate_arraylist_release(gate_arraylist_t arr)
632 {
633 char* dstptr;
634
2/2
✓ Branch 0 taken 931 times.
✓ Branch 1 taken 1021 times.
1952 if (arr != NULL)
635 {
636
2/2
✓ Branch 1 taken 683 times.
✓ Branch 2 taken 248 times.
931 if (gate_atomic_int_dec(&arr->ref_counter) == 0)
637 {
638
2/2
✓ Branch 0 taken 197 times.
✓ Branch 1 taken 486 times.
683 if (arr->data_ptr != NULL)
639 {
640
4/4
✓ Branch 0 taken 191 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 180 times.
✓ Branch 3 taken 11 times.
197 if ((arr->item_count != 0) && (arr->destruct_item != NULL))
641 {
642 180 dstptr = arr->data_ptr + (arr->item_offset * arr->item_size);
643
2/2
✓ Branch 0 taken 1931 times.
✓ Branch 1 taken 180 times.
2111 while (arr->item_count-- != 0)
644 {
645 1931 arr->destruct_item(dstptr);
646 1931 dstptr += arr->item_size;
647 }
648 }
649 197 gate_mem_dealloc(arr->data_ptr);
650 }
651 683 gate_mem_dealloc(arr);
652 }
653 }
654 1952 }
655
656 37 gate_arraylist_t gate_arraylist_copy(gate_arraylist_t src_arr)
657 {
658 37 GATE_DEBUG_ASSERT(src_arr != NULL);
659 111 return gate_arraylist_create(src_arr->item_size,
660 37 src_arr->data_ptr + (src_arr->item_offset * src_arr->item_size), src_arr->item_count,
661 src_arr->construct_item, src_arr->destruct_item);
662 }
663
664 2962 gate_size_t gate_arraylist_length(gate_arraylist_t arr)
665 {
666 2962 GATE_DEBUG_ASSERT(arr != NULL);
667 2962 return arr->item_count;
668 }
669
670 13 gate_size_t gate_arraylist_itemsize(gate_arraylist_t arr)
671 {
672 13 GATE_DEBUG_ASSERT(arr != NULL);
673 13 return arr->item_size;
674 }
675
676 1972 void* gate_arraylist_get(gate_arraylist_t arr, gate_size_t index)
677 {
678 char* dstptr;
679 1972 GATE_DEBUG_ASSERT(arr != NULL);
680
2/2
✓ Branch 0 taken 1967 times.
✓ Branch 1 taken 5 times.
1972 if (arr->data_ptr != NULL)
681 {
682 1967 dstptr = (char*)arr->data_ptr;
683 1967 dstptr += (arr->item_size * (arr->item_offset + index));
684 1967 return (void*)dstptr;
685 }
686 5 return NULL;
687 }
688
689 162 void* gate_arraylist_insert(gate_arraylist_t arr, gate_size_t index, void const* item, gate_size_t itemcount)
690 {
691 char* movesrc;
692 char* movedst;
693 gate_size_t movecount;
694 char const* srcptr;
695 gate_result_t result;
696
697 162 GATE_DEBUG_ASSERT(arr != NULL);
698
699
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 133 times.
162 if ((arr->item_offset + arr->item_count + itemcount) > arr->item_capacity)
700 {
701
1/2
✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
29 if ((arr->item_count + itemcount) > arr->item_capacity)
702 {
703 29 arr = gate_arraylist_reserve(arr, arr->item_count + itemcount + (arr->item_capacity / 2));
704 }
705 else
706 {
707 gate_arraylist_defrag(arr);
708 }
709 }
710
711
2/2
✓ Branch 0 taken 160 times.
✓ Branch 1 taken 2 times.
162 if (index >= arr->item_count)
712 {
713 /* append */
714 160 index = arr->item_count;
715 160 movedst = arr->data_ptr + ((arr->item_offset + arr->item_count) * arr->item_size);
716
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 155 times.
160 if (arr->construct_item != NULL)
717 {
718 5 srcptr = (char const*)item;
719
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
10 while (itemcount-- != 0)
720 {
721 5 result = arr->construct_item(movedst, srcptr);
722
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (GATE_FAILED(result))
723 {
724 /* construction error */
725 return NULL;
726 }
727 5 movedst += arr->item_size;
728 5 srcptr += arr->item_size;
729 5 ++arr->item_count;
730 }
731 }
732 else
733 {
734 155 gate_mem_copy(movedst, item, itemcount * arr->item_size);
735 155 arr->item_count += itemcount;
736 }
737 }
738 else
739 {
740 2 movecount = arr->item_count - index;
741
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (arr->construct_item != NULL)
742 {
743 2 movesrc = arr->data_ptr + ((arr->item_offset + arr->item_count - 1) * arr->item_size);
744 2 movedst = movesrc + (itemcount * arr->item_size);
745
746
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
5 while (movecount-- != 0)
747 {
748 3 result = arr->construct_item(movedst, movesrc);
749
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (GATE_FAILED(result))
750 {
751 /* construction error */
752 /* TODO */
753 return NULL;
754 }
755
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (arr->destruct_item != NULL)
756 {
757 3 arr->destruct_item(movesrc);
758 }
759 3 movesrc -= arr->item_size;
760 3 movedst -= arr->item_size;
761 }
762
763 2 srcptr = (char const*)item;
764 2 movedst = ((char*)arr->data_ptr) + ((arr->item_offset + index) * arr->item_size);
765
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 while (itemcount-- != 0)
766 {
767 2 result = arr->construct_item(movedst, srcptr);
768
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (GATE_FAILED(result))
769 {
770 /* construction error*/
771 /* TODO */
772 return NULL;
773 }
774 2 srcptr += arr->item_size;
775 2 movedst += arr->item_size;
776 2 ++arr->item_count;
777 }
778 }
779 else
780 {
781 movesrc = arr->data_ptr + ((arr->item_offset + index) * arr->item_size);
782 movedst = movesrc + (itemcount * arr->item_size);
783
784 gate_mem_move(movedst, movesrc, movecount * arr->item_size);
785
786 movedst = (char*)arr->data_ptr + ((arr->item_offset + index) * arr->item_size);
787 gate_mem_copy(movedst, item, itemcount * arr->item_size);
788
789 arr->item_count += itemcount;
790 }
791 }
792 162 return arr->data_ptr + ((arr->item_offset + index) * arr->item_size);
793 }
794
795 1646 void* gate_arraylist_add(gate_arraylist_t arr, void const* item)
796 {
797 char* dstptr;
798 gate_result_t result;
799
800 1646 GATE_DEBUG_ASSERT(arr != NULL);
801
802
2/2
✓ Branch 0 taken 210 times.
✓ Branch 1 taken 1436 times.
1646 if (arr->item_capacity == (arr->item_offset + arr->item_count))
803 {
804
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 210 times.
210 if (arr->item_offset > 0)
805 {
806 gate_arraylist_defrag(arr);
807 }
808 else
809 {
810
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 210 times.
210 if (gate_arraylist_reserve(arr, arr->item_capacity + (arr->item_capacity / 2) + 2) == NULL)
811 {
812 return NULL;
813 }
814 }
815 }
816 1646 dstptr = arr->data_ptr + ((arr->item_offset + arr->item_count) * arr->item_size);
817 1646 result = gate_mem_copy_construct(dstptr, item, arr->item_size, arr->construct_item);
818
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1646 times.
1646 if (GATE_FAILED(result))
819 {
820 return NULL;
821 }
822 1646 ++arr->item_count;
823
824 1646 return ((char*)arr->data_ptr) + ((arr->item_offset + arr->item_count - 1) * arr->item_size);
825 }
826
827 3 void* gate_arraylist_add_n(gate_arraylist_t arr, void const* item, gate_size_t repeat_count)
828 {
829 3 void* ret = NULL;
830 char* dstptr;
831 gate_result_t result;
832
833 3 GATE_DEBUG_ASSERT(arr != NULL);
834
835
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if ((arr->item_offset + arr->item_count + repeat_count) > arr->item_capacity)
836 {
837 if ((arr->item_count + repeat_count) > arr->item_capacity)
838 {
839 if (gate_arraylist_reserve(arr, arr->item_capacity + repeat_count + (arr->item_capacity / 2) + 2) == NULL)
840 {
841 return NULL;
842 }
843 }
844 else
845 {
846 gate_arraylist_defrag(arr);
847 }
848 }
849 3 dstptr = (char*)arr->data_ptr + ((arr->item_offset + arr->item_count) * arr->item_size);
850 3 ret = dstptr;
851
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 3 times.
10 while (repeat_count-- != 0)
852 {
853 7 result = gate_mem_copy_construct(dstptr, item, arr->item_size, arr->construct_item);
854
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (GATE_FAILED(result))
855 {
856 break;
857 }
858 7 dstptr += arr->item_size;
859 7 ++arr->item_count;
860 }
861
862 3 return ret;
863 }
864
865 1019 gate_result_t gate_arraylist_remove(gate_arraylist_t arr, gate_size_t index, gate_size_t count)
866 {
867 char* srcptr;
868 char* dstptr;
869 gate_size_t movecount;
870
871 1019 GATE_DEBUG_ASSERT(arr != NULL);
872
873
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1019 times.
1019 if (index >= arr->item_count)
874 {
875 return GATE_RESULT_OUTOFBOUNDS;
876 }
877
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1019 times.
1019 if (index + count > arr->item_count)
878 {
879 count = arr->item_count - index;
880 }
881
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1019 times.
1019 if (count == 0)
882 {
883 return GATE_RESULT_OK;
884 }
885
886 1019 srcptr = arr->data_ptr + ((arr->item_offset + index) * arr->item_size);
887
2/2
✓ Branch 0 taken 1015 times.
✓ Branch 1 taken 4 times.
1019 if (index == 0)
888 {
889 /* optimization */
890 1015 arr->item_offset += count;
891 1015 arr->item_count -= count;
892
2/2
✓ Branch 0 taken 1015 times.
✓ Branch 1 taken 1015 times.
2030 while (count-- != 0)
893 {
894
2/2
✓ Branch 0 taken 1007 times.
✓ Branch 1 taken 8 times.
1015 if (arr->destruct_item)
895 {
896 1007 arr->destruct_item(srcptr);
897 }
898 1015 srcptr += arr->item_size;
899 }
900
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1006 times.
1015 if (arr->item_count == 0)
901 {
902 9 arr->item_offset = 0;
903 }
904 }
905 else
906 {
907
908 4 dstptr = srcptr;
909 4 movecount = arr->item_count - index - count;
910
911
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 if (arr->destruct_item != NULL)
912 {
913
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 while (count-- != 0)
914 {
915 3 arr->destruct_item(srcptr);
916 3 srcptr += arr->item_size;
917 3 --arr->item_count;
918 }
919 }
920 else
921 {
922 1 srcptr += count * arr->item_size;
923 1 arr->item_count -= count;
924 }
925
926
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (movecount != 0)
927 {
928
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (arr->construct_item != NULL)
929 {
930
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 while (movecount-- != 0)
931 {
932 2 arr->construct_item(dstptr, srcptr);
933
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (arr->destruct_item != NULL)
934 {
935 2 arr->destruct_item(srcptr);
936 }
937 2 srcptr += arr->item_size;
938 2 dstptr += arr->item_size;
939 }
940 }
941 else
942 {
943 1 gate_mem_move(dstptr, srcptr, movecount * arr->item_size);
944 }
945 }
946 }
947 1019 return GATE_RESULT_OK;
948 }
949
950 17 gate_result_t gate_arraylist_remove_if(gate_arraylist_t arr, gate_check_condition_t condition, void* param)
951 {
952 17 gate_result_t ret = GATE_RESULT_OK;
953 char* srcptr;
954 char* dstptr;
955 gate_size_t ndx;
956 17 gate_size_t new_size = 0;
957
958 17 GATE_DEBUG_ASSERT(arr != NULL);
959
960 17 srcptr = arr->data_ptr + (arr->item_offset * arr->item_size);
961 17 dstptr = srcptr;
962
963
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 17 times.
49 for (ndx = 0; ndx != arr->item_count; ++ndx)
964 {
965
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 26 times.
32 if (condition(srcptr, param))
966 {
967 /*remove item*/
968 6 gate_mem_destruct(srcptr, arr->destruct_item);
969 }
970 else
971 {
972 26 ret = gate_mem_move_construct(dstptr, srcptr, arr->item_size, arr->construct_item, arr->destruct_item);
973
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (GATE_FAILED(ret))
974 {
975 /* critical error, now we have a gap in the array */
976 while (ndx != arr->item_count)
977 {
978 gate_mem_destruct(srcptr, arr->destruct_item);
979 srcptr += arr->item_size;
980 ++ndx;
981 }
982 break;
983 }
984 26 dstptr += arr->item_size;
985 26 ++new_size;
986 }
987 32 srcptr += arr->item_size;
988 }
989 17 arr->item_count = new_size;
990 17 return ret;
991 }
992
993 3 void gate_arraylist_clear(gate_arraylist_t arr)
994 {
995 3 GATE_DEBUG_ASSERT(arr != NULL);
996
997
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if (arr->destruct_item != NULL)
998 {
999 gate_size_t ndx;
1000 1 char* ptr = arr->data_ptr + (arr->item_offset * arr->item_size);
1001
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 for (ndx = 0; ndx != arr->item_count; ++ndx)
1002 {
1003 2 arr->destruct_item(ptr);
1004 2 ptr += arr->item_size;
1005 }
1006 }
1007 3 arr->item_count = 0;
1008 3 arr->item_offset = 0;
1009 3 }
1010
1011 1 gate_size_t gate_arraylist_get_value(gate_arraylist_t arr, gate_size_t index, void* dest_buffer, gate_size_t dest_buffer_size)
1012 {
1013 char* itemptr;
1014 gate_result_t result;
1015
1016 1 GATE_DEBUG_ASSERT(arr != NULL);
1017
1018
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if ((dest_buffer_size < arr->item_size) || (index >= arr->item_count))
1019 {
1020 /* invalid arg or index out of bounds */
1021 return 0;
1022 }
1023
1024 1 itemptr = arr->data_ptr + ((arr->item_offset + index) * arr->item_size);
1025
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (arr->construct_item)
1026 {
1027 1 result = arr->construct_item(dest_buffer, itemptr);
1028
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (GATE_FAILED(result))
1029 {
1030 /* copy construction failed */
1031 return 0;
1032 }
1033 }
1034 else
1035 {
1036 gate_mem_copy(dest_buffer, itemptr, arr->item_size);
1037 }
1038 1 return arr->item_size;
1039 }
1040
1041 1 gate_size_t gate_arraylist_create_item(gate_arraylist_t arr, void* dest_buffer, gate_size_t dest_buffer_size)
1042 {
1043 1 gate_size_t ret = 0;
1044 gate_result_t result;
1045
1046 1 GATE_DEBUG_ASSERT(arr != NULL);
1047
1048
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (dest_buffer_size >= arr->item_size)
1049 {
1050
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (arr->construct_item == NULL)
1051 {
1052 gate_mem_clear(dest_buffer, arr->item_size);
1053 ret = arr->item_size;
1054 }
1055 else
1056 {
1057 1 result = arr->construct_item(dest_buffer, NULL);
1058
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (GATE_SUCCEEDED(result))
1059 {
1060 1 ret = arr->item_size;
1061 }
1062 }
1063 }
1064 1 return ret;
1065 }
1066
1067 void gate_arraylist_destroy_item(gate_arraylist_t arr, void* dest_buffer)
1068 {
1069 GATE_DEBUG_ASSERT(arr != NULL);
1070
1071 if (arr->destruct_item != NULL)
1072 {
1073 arr->destruct_item(dest_buffer);
1074 }
1075 }
1076
1077 1023 static gate_bool_t gate_arraylist_enumerate_is_valid(gate_enumerator_t const* enumerator)
1078 {
1079 1023 return enumerator->current_position < enumerator->end_position;
1080 }
1081 1021 static gate_bool_t gate_arraylist_enumerate_next(gate_enumerator_t* enumerator)
1082 {
1083 1021 gate_arraylist_t arr = (gate_arraylist_t)enumerator->ptr_origin;
1084
2/2
✓ Branch 0 taken 1020 times.
✓ Branch 1 taken 1 times.
1021 if (enumerator->current_position)
1085 {
1086 1020 enumerator->current_position = (void*)((char*)enumerator->current_position + arr->item_size);
1087 1020 return enumerator->current_position < enumerator->end_position;
1088 }
1089 else
1090 {
1091 1 return false;
1092 }
1093 }
1094 1020 static void const* gate_arraylist_enumerate_get(gate_enumerator_t const* enumerator)
1095 {
1096 1020 return (void const*)enumerator->current_position;
1097 }
1098
1099 3 gate_enumerator_t* gate_arraylist_enumerate(gate_arraylist_t arr, gate_enumerator_t* enumerator)
1100 {
1101 3 enumerator->is_valid = &gate_arraylist_enumerate_is_valid;
1102 3 enumerator->next = &gate_arraylist_enumerate_next;
1103 3 enumerator->get = &gate_arraylist_enumerate_get;
1104 3 enumerator->ptr_origin = arr;
1105
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if (arr->data_ptr)
1106 {
1107 2 enumerator->current_position = arr->data_ptr + (arr->item_offset * arr->item_size);
1108 2 enumerator->end_position = (char*)enumerator->current_position + ((arr->item_offset + arr->item_count) * arr->item_size);
1109 }
1110 else
1111 {
1112 1 enumerator->current_position = NULL;
1113 1 enumerator->end_position = NULL;
1114 }
1115 3 return enumerator;
1116 }
1117
1118 1 gate_result_t gate_arraylist_copy_constructor(void* dst, void const* src)
1119 {
1120 1 gate_arraylist_t* dstlist = (gate_arraylist_t*)dst;
1121 1 gate_arraylist_t const* srclist = (gate_arraylist_t const*)src;
1122 1 *dstlist = *srclist;
1123
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (*dstlist != NULL)
1124 {
1125 1 *dstlist = gate_arraylist_copy(*srclist);
1126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (*dstlist == NULL)
1127 {
1128 /* error: copying failed*/
1129 return GATE_RESULT_FAILED;
1130 }
1131 }
1132 1 return GATE_RESULT_OK;
1133 }
1134 1 void gate_arraylist_destructor(void* dst)
1135 {
1136 1 gate_arraylist_t* dstlist = (gate_arraylist_t*)dst;
1137 1 gate_arraylist_release(*dstlist);
1138 1 *dstlist = NULL;
1139 1 }
1140
1141 /*****************************
1142 * *
1143 * SlotList implementation *
1144 * *
1145 *****************************/
1146
1147 14 gate_slotlist_t* gate_slotlist_create(gate_slotlist_t* sl, gate_size_t itemsize, gate_mem_copyctor_t ctor, gate_mem_dtor_t dtor)
1148 {
1149 14 sl->data_ptr = NULL;
1150 14 sl->item_size = itemsize;
1151 14 sl->item_count = 0;
1152 14 sl->item_capacity = 0;
1153 14 sl->construct_item = ctor;
1154 14 sl->destruct_item = dtor;
1155 14 return sl;
1156 }
1157 12 static gate_slotlist_t* gate_slotlist_resize_to(gate_slotlist_t* sl, gate_size_t newcapacity)
1158 {
1159 gate_size_t ndx;
1160 gate_size_t newdatasize;
1161 void** newbuffer;
1162
1163
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 11 times.
12 if (newcapacity <= sl->item_capacity)
1164 {
1165 1 newcapacity = sl->item_capacity + (sl->item_capacity / 2) + 16;
1166 }
1167 12 newdatasize = newcapacity * sizeof(void*);
1168 12 newbuffer = (void**)gate_mem_realloc(sl->data_ptr, newdatasize);
1169
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (newbuffer == NULL)
1170 {
1171 return NULL;
1172 }
1173
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 12 times.
72 for (ndx = sl->item_capacity; ndx < newcapacity; ++ndx)
1174 {
1175 60 newbuffer[ndx] = NULL;
1176 }
1177 12 sl->data_ptr = newbuffer;
1178 12 sl->item_capacity = newcapacity;
1179 12 return sl;
1180 }
1181
1182 3 gate_slotlist_t* gate_slotlist_create_copy(gate_slotlist_t* sl, gate_slotlist_t const* src)
1183 {
1184 3 gate_slotlist_t* ret = NULL;
1185 gate_size_t ndx;
1186 void** ptr;
1187 3 gate_slotlist_create(sl, src->item_size, src->construct_item, src->destruct_item);
1188
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 if (NULL != gate_slotlist_resize_to(sl, src->item_count))
1189 {
1190 3 ret = sl;
1191 3 ptr = src->data_ptr;
1192
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if (ptr)
1193 {
1194
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2 times.
10 for (ndx = 0; ndx != src->item_count; ++ndx)
1195 {
1196
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 if (NULL == gate_slotlist_add(sl, *ptr))
1197 {
1198 gate_slotlist_destroy(sl);
1199 ret = NULL;
1200 break;
1201 }
1202 }
1203 }
1204 }
1205 3 return ret;
1206 }
1207
1208 14 void gate_slotlist_destroy(gate_slotlist_t* sl)
1209 {
1210 14 void** ptr = sl->data_ptr;
1211 void** ptrend;
1212
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 2 times.
14 if (ptr)
1213 {
1214 12 ptrend = ptr + sl->item_capacity;
1215
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 12 times.
72 for (; ptr != ptrend; ++ptr)
1216 {
1217
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 42 times.
60 if (*ptr != NULL)
1218 {
1219
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 if (sl->destruct_item != NULL)
1220 {
1221 18 sl->destruct_item(*ptr);
1222 }
1223 18 gate_mem_dealloc(*ptr);
1224 18 *ptr = NULL;
1225 }
1226 }
1227 12 gate_mem_dealloc(sl->data_ptr);
1228 }
1229 14 gate_mem_clear(sl, sizeof(gate_slotlist_t));
1230 14 }
1231
1232 21 static void** gate_slotlist_next_free_slot(gate_slotlist_t* sl)
1233 {
1234 21 void** ptr = sl->data_ptr;
1235
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 void** ptrend = ptr ? (ptr + sl->item_capacity) : NULL;
1236
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 for (; ptr != ptrend; ++ptr)
1237 {
1238
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 18 times.
39 if (*ptr == NULL)
1239 {
1240 21 return ptr;
1241 }
1242 }
1243 return NULL;
1244 }
1245
1246 21 void* gate_slotlist_add(gate_slotlist_t* sl, void const* item)
1247 {
1248 gate_result_t result;
1249 21 void* ret = NULL;
1250 21 void* new_ptr = gate_mem_alloc(sl->item_size);
1251
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (NULL == new_ptr)
1252 {
1253 return NULL;
1254 }
1255 21 result = gate_mem_copy_construct(new_ptr, item, sl->item_size, sl->construct_item);
1256
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (GATE_FAILED(result))
1257 {
1258 gate_mem_dealloc(new_ptr);
1259 return NULL;
1260 }
1261 21 ret = gate_slotlist_import(sl, new_ptr);
1262
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (NULL == ret)
1263 {
1264 gate_mem_destruct(new_ptr, sl->destruct_item);
1265 gate_mem_dealloc(new_ptr);
1266 }
1267 21 return ret;
1268 }
1269 15 void* gate_slotlist_first(gate_slotlist_t const* sl, gate_slotlist_iterator_t* iterator)
1270 {
1271 15 void* ret = NULL;
1272 15 void** ptr = sl->data_ptr;
1273 void** ptrend;
1274 gate_size_t ndx;
1275
1276
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 if (ptr != NULL)
1277 {
1278 15 ptrend = ptr + sl->item_capacity;
1279
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 for (ndx = 0; ptr != ptrend; ++ptr, ++ndx)
1280 {
1281
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 3 times.
18 if (*ptr != NULL)
1282 {
1283 15 *iterator = ndx;
1284 15 ret = *ptr;
1285 15 break;
1286 }
1287 }
1288 }
1289 15 return ret;
1290 }
1291 16 void* gate_slotlist_next(gate_slotlist_t const* sl, gate_slotlist_iterator_t* iterator)
1292 {
1293 16 void* ret = NULL;
1294 16 void** ptr = sl->data_ptr;
1295 void** ptrend;
1296 gate_size_t ndx;
1297
1298
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 if (ptr)
1299 {
1300 16 ptrend = ptr + sl->item_capacity;
1301 16 ndx = *iterator;
1302
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 if (ndx < sl->item_capacity)
1303 {
1304 16 ++ndx;
1305
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 10 times.
40 for (ptr += ndx; ptr < ptrend; ++ptr, ++ndx)
1306 {
1307
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 24 times.
30 if (*ptr != NULL)
1308 {
1309 6 *iterator = ndx;
1310 6 ret = *ptr;
1311 6 break;
1312 }
1313 }
1314 }
1315 }
1316 16 return ret;
1317 }
1318 16 void* gate_slotlist_at(gate_slotlist_t const* sl, gate_size_t index)
1319 {
1320
2/4
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
16 if ((index < sl->item_capacity) && (sl->data_ptr != NULL))
1321 {
1322 16 return sl->data_ptr[index];
1323 }
1324 return NULL;
1325 }
1326
1327 1 void* gate_slotlist_get(gate_slotlist_t const* sl, gate_slotlist_iterator_t const* iterator)
1328 {
1329
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if (!sl || !iterator)
1330 {
1331 return NULL;
1332 }
1333 1 return gate_slotlist_at(sl, *iterator);
1334 }
1335
1336 1 void* gate_slotlist_insert_at(gate_slotlist_t* sl, gate_size_t index, void const* item)
1337 {
1338 gate_result_t result;
1339 1 void* ret = NULL;
1340 1 void* new_ptr = gate_mem_alloc(sl->item_size);
1341
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (NULL == new_ptr)
1342 {
1343 return NULL;
1344 }
1345 1 result = gate_mem_copy_construct(new_ptr, item, sl->item_size, sl->construct_item);
1346
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (GATE_FAILED(result))
1347 {
1348 gate_mem_dealloc(new_ptr);
1349 return NULL;
1350 }
1351 1 ret = gate_slotlist_import_at(sl, index, new_ptr);
1352
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (NULL == ret)
1353 {
1354 gate_mem_destruct(new_ptr, sl->destruct_item);
1355 gate_mem_dealloc(new_ptr);
1356 }
1357 1 return ret;
1358 }
1359
1360 4 gate_bool_t gate_slotlist_remove(gate_slotlist_t* sl, gate_slotlist_iterator_t const* iterator)
1361 {
1362 4 const gate_size_t ndx = *iterator;
1363 4 return gate_slotlist_remove_at(sl, ndx);
1364 }
1365
1366 4 gate_bool_t gate_slotlist_remove_at(gate_slotlist_t* sl, gate_size_t index)
1367 {
1368 4 void* ptr_data = gate_slotlist_export_at(sl, index);
1369
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (ptr_data != NULL)
1370 {
1371 4 gate_mem_destruct(ptr_data, sl->destruct_item);
1372 4 gate_mem_dealloc(ptr_data);
1373 4 return true;
1374 }
1375 return false;
1376 }
1377
1378 2 void gate_slotlist_optimize(gate_slotlist_t* sl)
1379 {
1380 2 void** ptr_in = sl->data_ptr;
1381 2 void** ptr_out = ptr_in;
1382 2 void** ptr_end = ptr_in + sl->item_capacity;
1383
1384
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2 times.
10 while (ptr_in != ptr_end)
1385 {
1386
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 times.
8 if (*ptr_in != NULL)
1387 {
1388
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 5 times.
7 if (ptr_in != ptr_out)
1389 {
1390 2 *ptr_out = *ptr_in;
1391 }
1392 7 ++ptr_out;
1393 }
1394 8 ++ptr_in;
1395 }
1396
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 while (ptr_out != ptr_end)
1397 {
1398 1 *ptr_out = NULL;
1399 1 ++ptr_out;
1400 }
1401 2 }
1402
1403 1 void gate_slotlist_clear(gate_slotlist_t* sl)
1404 {
1405 1 gate_size_t itemsize = sl->item_size;
1406 1 gate_mem_copyctor_t ctor = sl->construct_item;
1407 1 gate_mem_dtor_t dtor = sl->destruct_item;
1408 1 gate_slotlist_destroy(sl);
1409 1 gate_slotlist_create(sl, itemsize, ctor, dtor);
1410 1 }
1411 6 gate_size_t gate_slotlist_length(gate_slotlist_t const* sl)
1412 {
1413 6 return sl->item_count;
1414 }
1415 19 gate_size_t gate_slotlist_capacity(gate_slotlist_t const* sl)
1416 {
1417 19 return sl->item_capacity;
1418 }
1419
1420 21 void* gate_slotlist_import(gate_slotlist_t* sl, void* item)
1421 {
1422 void** ptr;
1423
1424
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 12 times.
21 if (sl->item_count >= sl->item_capacity)
1425 {
1426
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
9 if (NULL == gate_slotlist_resize_to(sl, sl->item_count + 4 + sl->item_capacity / 2))
1427 {
1428 /* out of memory */
1429 return NULL;
1430 }
1431 }
1432 21 ptr = gate_slotlist_next_free_slot(sl);
1433
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (ptr == NULL)
1434 {
1435 return NULL;
1436 }
1437 21 *ptr = item;
1438
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 if (item != NULL)
1439 {
1440 21 ++sl->item_count;
1441 }
1442 21 return *ptr;
1443 }
1444 1 void* gate_slotlist_import_at(gate_slotlist_t* sl, gate_size_t index, void* item)
1445 {
1446 gate_size_t move_count;
1447
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (index >= sl->item_capacity)
1448 {
1449 if (NULL == gate_slotlist_resize_to(sl, index + 4))
1450 {
1451 /* out of memory */
1452 return NULL;
1453 }
1454 }
1455
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 else if (sl->data_ptr[index] != NULL)
1456 {
1457 if (NULL == gate_slotlist_resize_to(sl, sl->item_capacity + 4))
1458 {
1459 /* out of memory */
1460 return NULL;
1461 }
1462 }
1463
1464
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (sl->data_ptr[index] != NULL)
1465 {
1466 move_count = sl->item_capacity - index - 1;
1467 if (move_count > 0)
1468 {
1469 gate_mem_move(&sl->data_ptr[index + 1], &sl->data_ptr[index], move_count * sizeof(void*));
1470 }
1471 }
1472 1 sl->data_ptr[index] = item;
1473
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (item != NULL)
1474 {
1475 1 ++sl->item_count;
1476 }
1477 1 return item;
1478 }
1479 void* gate_slotlist_export(gate_slotlist_t* sl, gate_slotlist_iterator_t* iterator)
1480 {
1481 return gate_slotlist_export_at(sl, *iterator);
1482 }
1483 4 void* gate_slotlist_export_at(gate_slotlist_t* sl, gate_size_t index)
1484 {
1485 void* ret;
1486
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
4 if (index >= sl->item_capacity || (sl->data_ptr == NULL))
1487 {
1488 return NULL;
1489 }
1490 4 ret = sl->data_ptr[index];
1491 4 sl->data_ptr[index] = NULL;
1492
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (ret != NULL)
1493 {
1494 4 --sl->item_count;
1495 }
1496 4 return ret;
1497 }
1498
1499 5 static gate_bool_t slotlist_enum_is_valid(gate_enumerator_t const* enumerator)
1500 {
1501 5 return enumerator->current_position != NULL;
1502 }
1503
1504 4 static gate_bool_t slotlist_enum_next(gate_enumerator_t* enumerator)
1505 {
1506 4 gate_slotlist_t const* ptr_sl = (gate_slotlist_t const*)enumerator->ptr_origin;
1507 4 gate_slotlist_iterator_t* ptr_iter = (gate_slotlist_iterator_t*)&enumerator->handles[0];
1508 4 enumerator->current_position = gate_slotlist_next(ptr_sl, ptr_iter);
1509 4 return NULL != enumerator->current_position;
1510 }
1511 4 static void const* slotlist_enum_get(gate_enumerator_t const* enumerator)
1512 {
1513 4 return enumerator->current_position;
1514 }
1515
1516 1 gate_enumerator_t* gate_slotlist_enumerate(gate_slotlist_t const* sl, gate_enumerator_t* enumerator)
1517 {
1518 gate_slotlist_iterator_t* ptr_iter;
1519
1520 1 gate_mem_clear(enumerator, sizeof(gate_enumerator_t));
1521 1 ptr_iter = (gate_slotlist_iterator_t*)&enumerator->handles[0];
1522 1 enumerator->ptr_origin = sl;
1523 1 enumerator->is_valid = &slotlist_enum_is_valid;
1524 1 enumerator->next = &slotlist_enum_next;
1525 1 enumerator->get = &slotlist_enum_get;
1526 1 enumerator->current_position = gate_slotlist_first(sl, ptr_iter);
1527
1528 1 return enumerator;
1529 }
1530
1531 /*******************************
1532 * *
1533 * LinkedList implementation *
1534 * *
1535 *******************************/
1536
1537 28 gate_result_t gate_linkedlist_create(gate_linkedlist_t* list, gate_size_t itemsize, gate_mem_copyctor_t copyctor, gate_mem_dtor_t dtor)
1538 {
1539 28 gate_result_t ret = GATE_RESULT_OK;
1540 28 list->item_size = itemsize;
1541 28 list->construct_item = copyctor;
1542 28 list->destruct_item = dtor;
1543 28 list->first = NULL;
1544 28 list->last = NULL;
1545 28 return ret;
1546 }
1547 20 void gate_linkedlist_destroy(gate_linkedlist_t* list)
1548 {
1549 20 gate_linkedentry_t* ptr = list->first;
1550 gate_linkedentry_t* next;
1551 20 gate_mem_dtor_t const dtor = list->destruct_item;
1552
1553
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 16 times.
20 if (dtor)
1554 {
1555
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 4 times.
10 while (ptr != NULL)
1556 {
1557 6 dtor(ptr->data);
1558 6 next = ptr->next;
1559 6 gate_mem_dealloc(ptr);
1560 6 ptr = next;
1561 }
1562 }
1563 else
1564 {
1565
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 while (ptr != NULL)
1566 {
1567 next = ptr->next;
1568 gate_mem_dealloc(ptr);
1569 ptr = next;
1570 }
1571 }
1572 20 gate_mem_clear(list, sizeof(gate_linkedlist_t));
1573 20 }
1574
1575 10 static gate_linkedentry_t* gate_linkedentry_create(gate_linkedlist_t* list, void const* item)
1576 {
1577 10 gate_linkedentry_t* ret = (gate_linkedentry_t*)gate_mem_alloc(sizeof(gate_linkedentry_t) + list->item_size);
1578 gate_result_t result;
1579
1580
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (!ret)
1581 {
1582 return NULL;
1583 }
1584
1585
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if (list->construct_item)
1586 {
1587 10 result = list->construct_item(&ret->attachment.content[0], item);
1588
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (GATE_FAILED(result))
1589 {
1590 gate_mem_dealloc(ret);
1591 return NULL;
1592 }
1593 }
1594 else
1595 {
1596 if (NULL == gate_mem_copy(&ret->attachment.content[0], item, list->item_size))
1597 {
1598 gate_mem_dealloc(ret);
1599 return NULL;
1600 }
1601 }
1602 10 ret->data = &ret->attachment.content[0];
1603 10 ret->previous = NULL;
1604 10 ret->next = NULL;
1605 10 return ret;
1606 }
1607 4 static void gate_linkedentry_destroy(gate_linkedlist_t* list, gate_linkedentry_t* entry)
1608 {
1609
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (list->destruct_item)
1610 {
1611 4 list->destruct_item(entry->data);
1612 }
1613 4 gate_mem_dealloc(entry);
1614 4 }
1615
1616 9 gate_linkedentry_t* gate_linkedlist_add(gate_linkedlist_t* list, void const* item)
1617 {
1618 9 gate_linkedentry_t* ret = gate_linkedentry_create(list, item);
1619
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if (ret)
1620 {
1621 9 ret->previous = list->last;
1622
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 3 times.
9 if (list->last)
1623 {
1624 6 list->last->next = ret;
1625 }
1626 else
1627 {
1628 3 list->first = ret;
1629 }
1630 9 list->last = ret;
1631 }
1632 9 return ret;
1633 }
1634 1 gate_linkedentry_t* gate_linkedlist_insert(gate_linkedlist_t* list, gate_linkedentry_t* entry, void const* item)
1635 {
1636 1 gate_linkedentry_t* ret = NULL;
1637
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (entry == NULL)
1638 {
1639 ret = gate_linkedlist_add(list, item);
1640 }
1641 else
1642 {
1643 1 ret = gate_linkedentry_create(list, item);
1644
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (ret)
1645 {
1646 1 ret->next = entry;
1647 1 ret->previous = entry->previous;
1648 1 entry->previous = ret;
1649
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (ret->previous == NULL)
1650 {
1651 1 list->first = ret;
1652 }
1653 }
1654 }
1655 1 return ret;
1656 }
1657 4 gate_result_t gate_linkedlist_remove(gate_linkedlist_t* list, gate_linkedentry_t* entry)
1658 {
1659
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!entry)
1660 {
1661 return GATE_RESULT_NULLPOINTER;
1662 }
1663 else
1664 {
1665
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
4 if ((entry->previous == NULL) && (entry->next == NULL))
1666 {
1667 1 list->first = NULL;
1668 1 list->last = NULL;
1669 }
1670 else
1671 {
1672
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (entry->previous == NULL)
1673 {
1674 list->first = entry->next;
1675 entry->next->previous = NULL;
1676 }
1677
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 else if (entry->next == NULL)
1678 {
1679 3 list->last = entry->previous;
1680 3 entry->previous->next = NULL;
1681 }
1682 else
1683 {
1684 entry->previous->next = entry->next;
1685 entry->next->previous = entry->previous;
1686 }
1687 }
1688 4 gate_linkedentry_destroy(list, entry);
1689 4 return GATE_RESULT_OK;
1690 }
1691 }
1692 7 gate_linkedentry_t* gate_linkedlist_first(gate_linkedlist_t const* list)
1693 {
1694 7 return list->first;
1695 }
1696 6 gate_linkedentry_t* gate_linkedlist_last(gate_linkedlist_t const* list)
1697 {
1698 6 return list->last;
1699 }
1700 5 gate_linkedentry_t* gate_linkedlist_previous(gate_linkedentry_t const* entry)
1701 {
1702
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (entry)
1703 {
1704 5 return entry->previous;
1705 }
1706 return NULL;
1707 }
1708 14 gate_linkedentry_t* gate_linkedlist_next(gate_linkedentry_t const* entry)
1709 {
1710
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 if (entry)
1711 {
1712 14 return entry->next;
1713 }
1714 return NULL;
1715 }
1716
1717 5 gate_bool_t gate_linkedlist_empty(gate_linkedlist_t const* list)
1718 {
1719 5 return list->first == NULL;
1720 }
1721
1722 8 static gate_bool_t gate_linkedlist_enum_is_valid(gate_enumerator_t const* enumerator)
1723 {
1724 8 return NULL != enumerator->current_position;
1725 }
1726 3 static gate_bool_t gate_linkedlist_enum_next(gate_enumerator_t* enumerator)
1727 {
1728 3 gate_linkedentry_t* entry = enumerator->current_position;
1729
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (entry)
1730 {
1731 3 enumerator->current_position = entry->next;
1732 3 return (enumerator->current_position == NULL) ? false : true;
1733 }
1734 return false;
1735 }
1736 9 static void const* gate_linkedlist_enum_get(gate_enumerator_t const* enumerator)
1737 {
1738 9 gate_linkedentry_t* entry = enumerator->current_position;
1739
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if (entry)
1740 {
1741 9 return entry->data;
1742 }
1743 return NULL;
1744 }
1745
1746 1 gate_enumerator_t* gate_linkedlist_enumerate(gate_linkedlist_t const* list, gate_enumerator_t* enumerator)
1747 {
1748
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if (!list || !enumerator)
1749 {
1750 return NULL;
1751 }
1752 else
1753 {
1754 1 gate_mem_clear(enumerator, sizeof(gate_enumerator_t));
1755 1 enumerator->is_valid = &gate_linkedlist_enum_is_valid;
1756 1 enumerator->next = &gate_linkedlist_enum_next;
1757 1 enumerator->get = &gate_linkedlist_enum_get;
1758
1759 1 enumerator->ptr_origin = list;
1760 1 enumerator->current_position = list->first;
1761 1 return enumerator;
1762 }
1763 }
1764