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
|
/*
* 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
* deferenced 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.
*
* @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);
/**
* 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);
/**
* 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);
/**
* 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);
#endif /** ARRAY_H_ @}*/
|