Hybrid ICN (hICN) plugin
v21.06-rc0-4-g18fa668
lib
includes
hicn
util
array.h
Go to the documentation of this file.
1
/*
2
* Copyright (c) 2017-2019 Cisco and/or its affiliates.
3
* Licensed under the Apache License, Version 2.0 (the "License");
4
* you may not use this file except in compliance with the License.
5
* You may obtain a copy of the License at:
6
*
7
* http://www.apache.org/licenses/LICENSE-2.0
8
*
9
* Unless required by applicable law or agreed to in writing, software
10
* distributed under the License is distributed on an "AS IS" BASIS,
11
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
* See the License for the specific language governing permissions and
13
* limitations under the License.
14
*/
15
21
#ifndef UTIL_ARRAY_H
22
#define UTIL_ARRAY_H
23
24
#include <assert.h>
25
#include <hicn/util/log.h>
26
#include <math.h>
// log2
27
#include <string.h>
// memmove
28
29
#define BUFSIZE 1024
30
31
typedef
int(*cmp_t)(
const
void
* x,
const
void
* y);
32
33
#define TYPEDEF_ARRAY_H(NAME, T) \
34
\
35
typedef struct { \
36
size_t size; \
37
size_t max_size_log; \
38
T * elements; \
39
} NAME ## _t; \
40
\
41
int NAME ## _initialize(NAME ## _t * array); \
42
\
43
int NAME ## _finalize(NAME ## _t * array); \
44
\
45
NAME ## _t * NAME ## _create(); \
46
\
47
void NAME ## _free(NAME ## _t * array); \
48
\
49
int NAME ## _add(NAME ## _t * array, T element); \
50
\
51
int NAME ## _remove_index(NAME ## _t * array, int index, T * element); \
52
\
53
int NAME ## _remove(NAME ## _t * array, const T search, T * element); \
54
\
55
int NAME ## _get(const NAME ## _t * array, const T search, T * element); \
56
\
57
int NAME ## _get_index(const NAME ## _t * array, int index, T * element); \
58
\
59
int NAME ## _get_elements(const NAME ## _t * array, T ** elements); \
60
\
61
size_t NAME ## _len(const NAME ## _t * array);
62
63
64
#define ARRAY_MAX_SIZE_LOG_INIT 0
65
66
#define TYPEDEF_ARRAY(NAME, T, CMP, SNPRINTF) \
67
int \
68
NAME ## _initialize(NAME ## _t * array) \
69
{ \
70
array->max_size_log = ARRAY_MAX_SIZE_LOG_INIT; \
71
array->size = 0; \
72
if (array->max_size_log == 0) { \
73
array->elements = NULL; \
74
return 0; \
75
} \
76
array->elements = malloc((1 << array->max_size_log) * sizeof(T)); \
77
if (!array->elements) \
78
return -1; \
79
return 0; \
80
} \
81
\
82
int \
83
NAME ## _finalize(NAME ## _t * array) \
84
{ \
85
for (unsigned i = 0; i < array->size; i++) { \
86
NAME ## _remove_index(array, i, NULL); \
87
} \
88
return 0; \
89
} \
90
\
91
NAME ## _t * \
92
NAME ## _create() \
93
{ \
94
NAME ## _t * array = malloc(sizeof(NAME ## _t)); \
95
if (!array) \
96
goto ERR_MALLOC; \
97
\
98
if (NAME ## _initialize(array) < 0) \
99
goto ERR_INITIALIZE; \
100
\
101
return array; \
102
\
103
ERR_INITIALIZE: \
104
free(array); \
105
ERR_MALLOC: \
106
return NULL; \
107
} \
108
\
109
void \
110
NAME ## _free(NAME ## _t * array) \
111
{ \
112
NAME ## _finalize(array); \
113
free(array->elements); \
114
free(array); \
115
} \
116
\
117
int \
118
NAME ## _add(NAME ## _t * array, T element) \
119
{ \
120
/* Ensure sufficient space for next addition */
\
121
size_t new_size_log = (array->size > 0) ? log2(array->size)+1 : 1; \
122
if (new_size_log > array->max_size_log) { \
123
array->max_size_log = new_size_log; \
124
array->elements = realloc(array->elements, \
125
(1 << new_size_log) * sizeof(T)); \
126
} \
127
\
128
if (!array->elements) \
129
goto ERR_REALLOC; \
130
\
131
array->elements[array->size++] = element; \
132
return 0; \
133
\
134
ERR_REALLOC: \
135
return -1; \
136
} \
137
\
138
int \
139
NAME ## _remove_index(NAME ## _t * array, int index, T * element) \
140
{ \
141
if (index > NAME ## _len(array)) \
142
return -1; \
143
if (element) \
144
*element = array->elements[index]; \
145
if (index < array->size) \
146
memmove(array->elements + index, array->elements + index + 1, \
147
array->size - index); \
148
array->size--; \
149
return 0; \
150
} \
151
\
152
int \
153
NAME ## _remove(NAME ## _t * array, const T search, T * element) \
154
{ \
155
for (unsigned i = 0; i < array->size; i++) { \
156
if (CMP(search, array->elements[i]) == 0) \
157
return facelet_array_remove_index(array, i, element); \
158
} \
159
/* Not found */
\
160
if (element) \
161
*element = NULL; \
162
return 0; \
163
} \
164
\
165
int \
166
NAME ## _get(const NAME ## _t * array, const T search, T * element) \
167
{ \
168
assert(element); \
169
for (unsigned i = 0; i < array->size; i++) \
170
if (CMP(search, array->elements[i]) == 0) { \
171
*element = array->elements[i]; \
172
return 0; \
173
} \
174
/* Not found */
\
175
*element = NULL; \
176
return 0; \
177
} \
178
\
179
int \
180
NAME ## _get_index(const NAME ## _t * array, int index, T * element) \
181
{ \
182
assert(element); \
183
*element = array->elements[index]; \
184
return 0; \
185
} \
186
\
187
int \
188
NAME ## _get_elements(const NAME ## _t * array, T ** elements) \
189
{ \
190
*elements = array->elements; \
191
return 0; \
192
} \
193
\
194
size_t \
195
NAME ## _len(const NAME ## _t * array) \
196
{ \
197
return array->size; \
198
}
199
200
#endif
/* UTIL_ARRAY_H */
Generated by
1.8.17