1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
|
/*
* Copyright (C) 2014 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* Copyright (C) 2013 Martin Willi
* Copyright (C) 2013 revosec AG
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
/**
* @defgroup array array
* @{ @ingroup collections
*/
#ifndef ARRAY_H_
#define ARRAY_H_
#include <collections/enumerator.h>
/**
* Variable sized array with fixed size elements.
*
* An array is a primitive object with associated functions to avoid the
* overhead of an object with methods. It is efficient in memory usage, but
* less efficient than a linked list in manipulating elements.
*/
typedef struct array_t array_t;
typedef enum array_idx_t array_idx_t;
/**
* Special array index values for insert/remove.
*/
enum array_idx_t {
ARRAY_HEAD = 0,
ARRAY_TAIL = -1,
};
/**
* Callback function invoked for each array element.
*
* Data is a pointer to the array element. If this is a pointer based array,
* (esize is zero), data is the pointer itself.
*
* @param data pointer to array data, or the pointer itself
* @param idx array index
* @param user user data passed with callback
*/
typedef void (*array_callback_t)(void *data, int idx, void *user);
/**
* Create a array instance.
*
* Elements get tight packed to each other. If any alignment is required, pass
* appropriate padding to each element. The reserved space does not affect
* array_count(), but just preallocates buffer space.
*
* @param esize element size for this array, use 0 for a pointer array
* @param reserve number of items to allocate space for
* @return array instance
*/
array_t *array_create(u_int esize, u_int8_t reserve);
/**
* Get the number of elements currently in the array.
*
* @return number of elements
*/
int array_count(array_t *array);
/**
* Compress an array, remove unused head/tail space.
*
* @param array array to compress, or NULL
*/
void array_compress(array_t *array);
/**
* Create an enumerator over an array.
*
* The enumerater enumerates directly over the array element (pass a pointer to
* element types), unless the array is pointer based. If zero is passed as
* element size during construction, the enumerator enumerates over the
* dereferenced pointer values.
*
* @param array array to create enumerator for, or NULL
* @return enumerator, over elements or pointers
*/
enumerator_t* array_create_enumerator(array_t *array);
/**
* Remove an element at enumerator position.
*
* @warning For **value based** arrays don't use the pointer returned by
* enumerate() anymore after calling this function. For performance reasons
* that pointer will point to internal data structures that get modified when
* this function is called.
*
* @param array array to remove element in
* @param enumerator enumerator position, from array_create_enumerator()
*/
void array_remove_at(array_t *array, enumerator_t *enumerator);
/**
* Insert an element to an array.
*
* If the array is pointer based (esize = 0), the pointer itself is appended.
* Otherwise the element gets copied from the pointer.
* The idx must be either within array_count() or one above to append the item.
* Passing -1 has the same effect as passing array_count(), i.e. appends the
* item. It is always valid to pass idx 0 to prepend the item.
*
* @param array array to append element to
* @param idx index to insert item at
* @param data pointer to array element to copy
*/
void array_insert(array_t *array, int idx, void *data);
/**
* Create an pointer based array if it does not exist, insert pointer.
*
* This is a convenience function for insert a pointer and implicitly
* create a pointer based array if array is NULL. Array is set the the newly
* created array, if any.
*
* @param array pointer to array reference, potentially NULL
* @param idx index to insert item at
* @param ptr pointer to append
*/
void array_insert_create(array_t **array, int idx, void *ptr);
/**
* Create a value based array if it does not exist, insert value.
*
* This is a convenience function to insert a value and implicitly
* create a value based array if array is NULL. Array is set the the newly
* created array, if any.
*
* @param array pointer to array reference, potentially NULL
* @param esize element size of this array
* @param idx index to insert item at
* @param val pointer to value to insert
*/
void array_insert_create_value(array_t **array, u_int esize,
int idx, void *val);
/**
* Insert all items from an enumerator to an array.
*
* @param array array to add items to
* @param idx index to insert each item with
* @param enumerator enumerator over void*, gets destroyed
*/
void array_insert_enumerator(array_t *array, int idx, enumerator_t *enumerator);
/**
* Get an element from the array.
*
* If data is given, the element is copied to that position.
*
* @param array array to get element from, or NULL
* @param idx index of the item to get
* @param data data to copy element to, or NULL
* @return TRUE if idx valid and item returned
*/
bool array_get(array_t *array, int idx, void *data);
/**
* Remove an element from the array.
*
* If data is given, the element is copied to that position.
*
* @param array array to remove element from, or NULL
* @param idx index of the item to remove
* @param data data to copy element to, or NULL
* @return TRUE if idx existed and item removed
*/
bool array_remove(array_t *array, int idx, void *data);
/**
* Sort the array.
*
* The comparison function must return an integer less than, equal to, or
* greater than zero if the first argument is considered to be respectively less
* than, equal to, or greater than the second. If two elements compare as
* equal, their order in the sorted array is undefined.
*
* The comparison function receives pointers to the array elements (esize != 0)
* or the actual pointers (esize = 0). The third argument is the user data
* supplied to this function.
*
* @param array array to sort, or NULL
* @param cmp comparison function
* @param user user data to pass to comparison function
*/
void array_sort(array_t *array, int (*cmp)(const void*,const void*,void*),
void *user);
/**
* Binary search of a sorted array.
*
* The array should be sorted in ascending order according to the given
* comparison function.
*
* The comparison function must return an integer less than, equal to, or
* greater than zero if the first argument (the key) is considered to be
* respectively less than, equal to, or greater than the second.
*
* If there are multiple elements that match the key it is not specified which
* element is returned.
*
* The comparison function receives the key object and a pointer to an array
* element (esize != 0) or an actual pointer (esize = 0).
*
* @param array array to search, or NULL
* @param key key to search for
* @param cmp comparison function
* @param data data to copy element to, or NULL
* @return index of the element if found, -1 if not
*/
int array_bsearch(array_t *array, const void *key,
int (*cmp)(const void*,const void*), void *data);
/**
* Invoke a callback for all array members.
*
* @param array array to traverse, or NULL
* @param cb callback function to invoke each element with
* @param user user data to pass to callback
*/
void array_invoke(array_t *array, array_callback_t cb, void *user);
/**
* Invoke a method of each element defined with offset.
*
* @param array array to traverse, or NULL
* @param offset offset of element method, use offsetof()
*/
void array_invoke_offset(array_t *array, size_t offset);
/**
* Destroy an array.
*
* @param array array to destroy, or NULL
*/
void array_destroy(array_t *array);
/**
* Destroy an array, call a function to clean up all elements.
*
* @param array array to destroy, or NULL
* @param cb callback function to free element data
* @param user user data to pass to callback
*/
void array_destroy_function(array_t *array, array_callback_t cb, void *user);
/**
* Destroy an array, call element method defined with offset.
*
* @param array array to destroy, or NULL
* @param offset offset of element method, use offsetof()
*/
void array_destroy_offset(array_t *array, size_t offset);
/**
* Required on some platforms to initialize thread local value to implement
* array_sort().
*/
void arrays_init();
/**
* Destroys the thread local value if required.
*/
void arrays_deinit();
#endif /** ARRAY_H_ @}*/
|