src/ucx/array_list.c

Sun, 27 Nov 2022 13:33:30 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 27 Nov 2022 13:33:30 +0100
changeset 443
ef3c8a0e1fee
parent 438
22eca559aded
child 490
d218607f5a7e
permissions
-rw-r--r--

improve daemon startup
parent will wait until daemon is started and returns error code if startup failed
daemon startup log messages will be printed by parent

436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1 /*
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
3 *
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
4 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
5 *
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
6 * Redistribution and use in source and binary forms, with or without
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
7 * modification, are permitted provided that the following conditions are met:
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
8 *
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
9 * 1. Redistributions of source code must retain the above copyright
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
10 * notice, this list of conditions and the following disclaimer.
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
11 *
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
12 * 2. Redistributions in binary form must reproduce the above copyright
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
13 * notice, this list of conditions and the following disclaimer in the
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
14 * documentation and/or other materials provided with the distribution.
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
15 *
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
26 * POSSIBILITY OF SUCH DAMAGE.
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
27 */
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
28
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
29 #include "cx/array_list.h"
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
30 #include <assert.h>
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
31 #include <string.h>
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
32 #include <stdint.h>
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
33
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
34 // LOW LEVEL ARRAY LIST FUNCTIONS
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
35
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
36 enum cx_array_copy_result cx_array_copy(
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
37 void **target,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
38 size_t *size,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
39 size_t *capacity,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
40 size_t index,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
41 void const *src,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
42 size_t elem_size,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
43 size_t elem_count,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
44 struct cx_array_reallocator_s *reallocator
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
45 ) {
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
46 // assert pointers
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
47 assert(target != NULL);
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
48 assert(size != NULL);
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
49 assert(src != NULL);
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
50
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
51 // determine capacity
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
52 size_t cap = capacity == NULL ? *size : *capacity;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
53
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
54 // check if resize is required
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
55 size_t minsize = index + elem_count;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
56 size_t newsize = *size < minsize ? minsize : *size;
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
57 bool needrealloc = newsize > cap;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
58
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
59 // reallocate if possible
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
60 if (needrealloc) {
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
61 // a reallocator and a capacity variable must be available
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
62 if (reallocator == NULL || capacity == NULL) {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
63 return CX_ARRAY_COPY_REALLOC_NOT_SUPPORTED;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
64 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
65
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
66 // check, if we need to repair the src pointer
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
67 uintptr_t targetaddr = (uintptr_t) *target;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
68 uintptr_t srcaddr = (uintptr_t) src;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
69 bool repairsrc = targetaddr <= srcaddr
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
70 && srcaddr < targetaddr + cap * elem_size;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
71
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
72 // calculate new capacity (next number divisible by 16)
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
73 cap = newsize - (newsize % 16) + 16;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
74 assert(cap > newsize);
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
75
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
76 // perform reallocation
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
77 void *newmem = reallocator->realloc(
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
78 *target, cap, elem_size, reallocator
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
79 );
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
80 if (newmem == NULL) {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
81 return CX_ARRAY_COPY_REALLOC_FAILED;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
82 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
83
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
84 // repair src pointer, if necessary
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
85 if (repairsrc) {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
86 src = ((char *) newmem) + (srcaddr - targetaddr);
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
87 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
88
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
89 // store new pointer and capacity
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
90 *target = newmem;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
91 *capacity = cap;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
92 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
93
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
94 // determine target pointer
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
95 char *start = *target;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
96 start += index * elem_size;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
97
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
98 // copy elements and set new size
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
99 memmove(start, src, elem_count * elem_size);
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
100 *size = newsize;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
101
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
102 // return successfully
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
103 return CX_ARRAY_COPY_SUCCESS;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
104 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
105
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
106 #define CX_ARRAY_SWAP_SBO_SIZE 512
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
107
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
108 void cx_array_swap(
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
109 void *arr,
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
110 size_t elem_size,
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
111 size_t idx1,
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
112 size_t idx2
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
113 ) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
114 // short circuit
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
115 if (idx1 == idx2) return;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
116
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
117 char sbo_mem[CX_ARRAY_SWAP_SBO_SIZE];
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
118 void *tmp;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
119
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
120 // decide if we can use the local buffer
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
121 if (elem_size > CX_ARRAY_SWAP_SBO_SIZE) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
122 tmp = malloc(elem_size);
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
123 // we don't want to enforce error handling
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
124 if (tmp == NULL) abort();
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
125 } else {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
126 tmp = sbo_mem;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
127 }
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
128
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
129 // calculate memory locations
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
130 char *left = arr, *right = arr;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
131 left += idx1 * elem_size;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
132 right += idx2 * elem_size;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
133
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
134 // three-way swap
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
135 memcpy(tmp, left, elem_size);
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
136 memcpy(left, right, elem_size);
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
137 memcpy(right, tmp, elem_size);
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
138
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
139 // free dynamic memory, if it was needed
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
140 if (tmp != sbo_mem) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
141 free(tmp);
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
142 }
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
143 }
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
144
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
145 // HIGH LEVEL ARRAY LIST FUNCTIONS
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
146
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
147 typedef struct {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
148 struct cx_list_s base;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
149 void *data;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
150 struct cx_array_reallocator_s reallocator;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
151 } cx_array_list;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
152
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
153 static void *cx_arl_realloc(
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
154 void *array,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
155 size_t capacity,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
156 size_t elem_size,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
157 struct cx_array_reallocator_s *alloc
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
158 ) {
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
159 // retrieve the pointer to the list allocator
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
160 CxAllocator const *al = alloc->ptr1;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
161
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
162 // use the list allocator to reallocate the memory
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
163 return cxRealloc(al, array, capacity * elem_size);
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
164 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
165
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
166 static void cx_arl_destructor(struct cx_list_s *list) {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
167 cx_array_list *arl = (cx_array_list *) list;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
168 cxFree(list->allocator, arl->data);
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
169 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
170
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
171 static int cx_arl_add(
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
172 struct cx_list_s *list,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
173 void const *elem
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
174 ) {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
175 cx_array_list *arl = (cx_array_list *) list;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
176 return cx_array_copy(
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
177 &arl->data,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
178 &list->size,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
179 &list->capacity,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
180 list->size,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
181 elem,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
182 list->itemsize,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
183 1,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
184 &arl->reallocator
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
185 );
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
186 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
187
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
188 static size_t cx_arl_add_array(
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
189 struct cx_list_s *list,
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
190 void const *array,
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
191 size_t n
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
192 ) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
193 cx_array_list *arl = (cx_array_list *) list;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
194 if (CX_ARRAY_COPY_SUCCESS == cx_array_copy(
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
195 &arl->data,
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
196 &list->size,
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
197 &list->capacity,
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
198 list->size,
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
199 array,
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
200 list->itemsize,
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
201 n,
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
202 &arl->reallocator
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
203 )) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
204 return n;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
205 } else {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
206 // array list implementation is "all or nothing"
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
207 return 0;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
208 }
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
209 }
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
210
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
211 static int cx_arl_insert(
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
212 struct cx_list_s *list,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
213 size_t index,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
214 void const *elem
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
215 ) {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
216 if (index > list->size) {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
217 return 1;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
218 } else if (index == list->size) {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
219 return cx_arl_add(list, elem);
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
220 } else {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
221 cx_array_list *arl = (cx_array_list *) list;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
222
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
223 // move elements starting at index to the right
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
224 if (cx_array_copy(
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
225 &arl->data,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
226 &list->size,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
227 &list->capacity,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
228 index + 1,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
229 ((char *) arl->data) + index * list->itemsize,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
230 list->itemsize,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
231 list->size - index,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
232 &arl->reallocator
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
233 )) {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
234 return 1;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
235 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
236
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
237 // place the element
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
238 memcpy(((char *) arl->data) + index * list->itemsize,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
239 elem, list->itemsize);
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
240
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
241 return 0;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
242 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
243 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
244
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
245 static int cx_arl_insert_iter(
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
246 struct cx_mut_iterator_s *iter,
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
247 void const *elem,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
248 int prepend
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
249 ) {
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
250 struct cx_list_s *list = iter->src_handle;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
251 if (iter->index < list->size) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
252 int result = cx_arl_insert(
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
253 list,
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
254 iter->index + 1 - prepend,
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
255 elem
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
256 );
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
257 if (result == 0 && prepend != 0) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
258 iter->index++;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
259 iter->elem_handle = ((char *) iter->elem_handle) + list->itemsize;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
260 }
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
261 return result;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
262 } else {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
263 int result = cx_arl_add(list, elem);
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
264 iter->index = list->size;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
265 return result;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
266 }
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
267 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
268
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
269 static int cx_arl_remove(
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
270 struct cx_list_s *list,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
271 size_t index
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
272 ) {
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
273 // out-of-bounds check
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
274 if (index >= list->size) {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
275 return 1;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
276 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
277
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
278 // short-circuit removal of last element
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
279 if (index == list->size - 1) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
280 list->size--;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
281 return 0;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
282 }
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
283
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
284 // just move the elements starting at index to the left
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
285 cx_array_list *arl = (cx_array_list *) list;
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
286 int result = cx_array_copy(
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
287 &arl->data,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
288 &list->size,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
289 &list->capacity,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
290 index,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
291 ((char *) arl->data) + (index + 1) * list->itemsize,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
292 list->itemsize,
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
293 list->size - index - 1,
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
294 &arl->reallocator
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
295 );
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
296 if (result == 0) {
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
297 // decrease the size
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
298 list->size--;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
299 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
300 return result;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
301 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
302
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
303 static void *cx_arl_at(
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
304 struct cx_list_s const *list,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
305 size_t index
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
306 ) {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
307 if (index < list->size) {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
308 cx_array_list const *arl = (cx_array_list const *) list;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
309 char *space = arl->data;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
310 return space + index * list->itemsize;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
311 } else {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
312 return NULL;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
313 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
314 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
315
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
316 static size_t cx_arl_find(
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
317 struct cx_list_s const *list,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
318 void const *elem
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
319 ) {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
320 char *cur = ((cx_array_list const *) list)->data;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
321
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
322 for (size_t i = 0; i < list->size; i++) {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
323 if (0 == list->cmpfunc(elem, cur)) {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
324 return i;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
325 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
326 cur += list->itemsize;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
327 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
328
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
329 return list->size;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
330 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
331
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
332 static void cx_arl_sort(struct cx_list_s *list) {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
333 qsort(((cx_array_list *) list)->data,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
334 list->size,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
335 list->itemsize,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
336 list->cmpfunc
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
337 );
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
338 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
339
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
340 static int cx_arl_compare(
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
341 struct cx_list_s const *list,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
342 struct cx_list_s const *other
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
343 ) {
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
344 if (list->size == other->size) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
345 char const *left = ((cx_array_list const *) list)->data;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
346 char const *right = ((cx_array_list const *) other)->data;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
347 for (size_t i = 0; i < list->size; i++) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
348 int d = list->cmpfunc(left, right);
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
349 if (d != 0) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
350 return d;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
351 }
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
352 left += list->itemsize;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
353 right += other->itemsize;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
354 }
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
355 return 0;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
356 } else {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
357 return list->size < other->size ? -1 : 1;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
358 }
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
359 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
360
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
361 static void cx_arl_reverse(struct cx_list_s *list) {
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
362 if (list->size < 2) return;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
363 void *data = ((cx_array_list const *) list)->data;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
364 size_t half = list->size / 2;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
365 for (size_t i = 0; i < half; i++) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
366 cx_array_swap(data, list->itemsize, i, list->size - 1 - i);
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
367 }
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
368 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
369
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
370 static bool cx_arl_iter_valid(void const *it) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
371 struct cx_iterator_s const *iter = it;
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
372 struct cx_list_s const *list = iter->src_handle;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
373 return iter->index < list->size;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
374 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
375
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
376 static void *cx_arl_iter_current(void const *it) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
377 struct cx_iterator_s const *iter = it;
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
378 return iter->elem_handle;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
379 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
380
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
381 static void cx_arl_iter_next(void *it) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
382 struct cx_iterator_base_s *itbase = it;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
383 if (itbase->remove) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
384 struct cx_mut_iterator_s *iter = it;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
385 itbase->remove = false;
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
386 cx_arl_remove(iter->src_handle, iter->index);
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
387 } else {
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
388 struct cx_iterator_s *iter = it;
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
389 iter->index++;
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
390 iter->elem_handle =
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
391 ((char *) iter->elem_handle)
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
392 + ((struct cx_list_s const *) iter->src_handle)->itemsize;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
393 }
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
394 }
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
395
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
396 static bool cx_arl_iter_flag_rm(void *it) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
397 struct cx_iterator_base_s *iter = it;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
398 if (iter->mutating) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
399 iter->remove = true;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
400 return true;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
401 } else {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
402 return false;
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
403 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
404 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
405
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
406 static struct cx_iterator_s cx_arl_iterator(
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
407 struct cx_list_s const *list,
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
408 size_t index
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
409 ) {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
410 struct cx_iterator_s iter;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
411
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
412 iter.index = index;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
413 iter.src_handle = list;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
414 iter.elem_handle = cx_arl_at(list, index);
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
415 iter.base.valid = cx_arl_iter_valid;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
416 iter.base.current = cx_arl_iter_current;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
417 iter.base.next = cx_arl_iter_next;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
418 iter.base.flag_removal = cx_arl_iter_flag_rm;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
419 iter.base.remove = false;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
420 iter.base.mutating = false;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
421
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
422 return iter;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
423 }
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
424
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
425 static struct cx_mut_iterator_s cx_arl_mut_iterator(
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
426 struct cx_list_s *list,
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
427 size_t index
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
428 ) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
429 CxIterator it = cx_arl_iterator(list, index);
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
430 it.base.mutating = true;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
431
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
432 // we know the iterators share the same memory layout
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
433 CxMutIterator iter;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
434 memcpy(&iter, &it, sizeof(CxMutIterator));
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
435 return iter;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
436 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
437
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
438 static cx_list_class cx_array_list_class = {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
439 cx_arl_destructor,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
440 cx_arl_add,
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
441 cx_arl_add_array,
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
442 cx_arl_insert,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
443 cx_arl_insert_iter,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
444 cx_arl_remove,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
445 cx_arl_at,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
446 cx_arl_find,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
447 cx_arl_sort,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
448 cx_arl_compare,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
449 cx_arl_reverse,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
450 cx_arl_iterator,
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
451 cx_arl_mut_iterator,
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
452 };
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
453
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
454 CxList *cxArrayListCreate(
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
455 CxAllocator const *allocator,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
456 CxListComparator comparator,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
457 size_t item_size,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
458 size_t initial_capacity
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
459 ) {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
460 cx_array_list *list = cxCalloc(allocator, 1, sizeof(cx_array_list));
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
461 if (list == NULL) return NULL;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
462
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
463 list->data = cxCalloc(allocator, initial_capacity, item_size);
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
464 if (list->data == NULL) {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
465 cxFree(allocator, list);
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
466 return NULL;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
467 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
468
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
469 list->base.cl = &cx_array_list_class;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
470 list->base.allocator = allocator;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
471 list->base.cmpfunc = comparator;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
472 list->base.itemsize = item_size;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
473 list->base.capacity = initial_capacity;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
474
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
475 // configure the reallocator
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
476 list->reallocator.realloc = cx_arl_realloc;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
477 list->reallocator.ptr1 = (void *) allocator;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
478
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
479 return (CxList *) list;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
480 }

mercurial