1 /**************************************************************************
2 **
3 ** sngrep - SIP Messages flow viewer
4 **
5 ** Copyright (C) 2013-2018 Ivan Alonso (Kaian)
6 ** Copyright (C) 2013-2018 Irontec SL. All rights reserved.
7 **
8 ** This program is free software: you can redistribute it and/or modify
9 ** it under the terms of the GNU General Public License as published by
10 ** the Free Software Foundation, either version 3 of the License, or
11 ** (at your option) any later version.
12 **
13 ** This program is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ** GNU General Public License for more details.
17 **
18 ** You should have received a copy of the GNU General Public License
19 ** along with this program. If not, see <http://www.gnu.org/licenses/>.
20 **
21 ****************************************************************************/
22 /**
23 * @file vector.c
24 * @author Ivan Alonso [aka Kaian] <kaian@irontec.com>
25 *
26 * @brief Source code of functions defined in vector.h
27 *
28 */
29 #include "vector.h"
30 #include <string.h>
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include "util.h"
34
35 vector_t *
vector_create(int limit,int step)36 vector_create(int limit, int step)
37 {
38 vector_t *v;
39 // Allocate memory for this vector data
40 if (!(v = malloc(sizeof(vector_t))))
41 return NULL;
42
43 v->count = 0;
44 v->limit = limit;
45 v->step = step;
46 v->list = NULL;
47 v->sorter = NULL;
48 v->destroyer = NULL;
49
50 return v;
51 }
52
53 void
vector_destroy(vector_t * vector)54 vector_destroy(vector_t *vector)
55 {
56 // Nothing to free. Done.
57 if (!vector) return;
58 // Remove all items if a destroyer is set
59 vector_clear(vector);
60 // Deallocate vector list
61 sng_free(vector->list);
62 // Deallocate vector itself
63 sng_free(vector);
64 }
65
66 void
vector_destroy_items(vector_t * vector)67 vector_destroy_items(vector_t *vector)
68 {
69 int i;
70
71 // Nothing to free. Done
72 if (!vector) return;
73
74 // If vector contains items
75 if (vector->count) {
76 for (i = 0; i < vector->count; i++) {
77 free(vector->list[i]);
78 }
79 free(vector->list);
80 }
81 free(vector);
82 }
83
84 vector_t *
vector_clone(vector_t * original)85 vector_clone(vector_t *original)
86 {
87 vector_t *clone;
88 vector_iter_t it;
89 void *item;
90
91 // Check we have a valid vector pointer
92 if (!original)
93 return NULL;
94
95 // Create a new vector structure
96 clone = vector_create(original->limit, original->step);
97 vector_set_destroyer(clone, original->destroyer);
98 vector_set_sorter(clone, original->sorter);
99
100 // Fill the clone vector with the same elements
101 it = vector_iterator(original);
102 while ((item = vector_iterator_next(&it)))
103 vector_append(clone, item);
104
105 // Return the cloned vector
106 return clone;
107 }
108
109 vector_t *
vector_copy_if(vector_t * original,int (* filter)(void * item))110 vector_copy_if(vector_t *original, int (*filter)(void *item))
111 {
112 vector_t *clone;
113 vector_iter_t it;
114 void *item;
115
116 // Check we have a valid vector pointer
117 if (!original)
118 return NULL;
119
120 // Create a new vector structure
121 clone = vector_create(0, 1);
122 // Fill the clone vector with the same elements applying filter
123 it = vector_iterator(original);
124 vector_iterator_set_filter(&it, filter);
125 while ((item = vector_iterator_next(&it))) {
126 vector_append(clone, item);
127 }
128 // Return the cloned vector
129 return clone;
130 }
131
132 void
vector_clear(vector_t * vector)133 vector_clear(vector_t *vector)
134 {
135 // Remove all items in the vector
136 while (vector_first(vector))
137 vector_remove(vector, vector_first(vector));
138 }
139
140 int
vector_append(vector_t * vector,void * item)141 vector_append(vector_t *vector, void *item)
142 {
143 // Sanity check
144 if (!item)
145 return vector->count;
146
147 // Check if the vector has been initializated
148 if (!vector->list) {
149 vector->list = malloc(sizeof(void *) * vector->limit);
150 memset(vector->list, 0, sizeof(void *) * vector->limit);
151 }
152
153 // Check if we need to increase vector size
154 if (vector->count == vector->limit) {
155 // Increase vector size
156 vector->limit += vector->step;
157 // Add more memory to the list
158 vector->list = realloc(vector->list, sizeof(void *) * vector->limit);
159 // Initialize new allocated memory
160 memset(vector->list + vector->limit - vector->step, 0, vector->step);
161 }
162
163 // Add item to the end of the list
164 vector->list[vector->count++] = item;
165
166 // Check if vector has a sorter
167 if (vector->sorter) {
168 vector->sorter(vector, item);
169 }
170
171 return vector->count - 1;
172 }
173
174 int
vector_append_vector(vector_t * dst,vector_t * src)175 vector_append_vector(vector_t *dst, vector_t *src)
176 {
177 if (!dst || !src)
178 return 1;
179
180 vector_iter_t it = vector_iterator(src);
181
182 void *item;
183 while ((item = vector_iterator_next(&it)))
184 vector_append(dst, item);
185
186 return 0;
187 }
188
189 int
vector_insert(vector_t * vector,void * item,int pos)190 vector_insert(vector_t *vector, void *item, int pos)
191 {
192 if (!item)
193 return vector->count;
194
195 if (pos < 0 || pos > vector->count - 2)
196 return vector->count;
197
198 // If position is already filled with that item, we're done
199 if (vector->list[pos] == item)
200 return vector->count;
201
202 // If possition is occupied, move the other position
203 if (vector->list[pos]) {
204 memmove(vector->list + pos + 1, vector->list + pos,
205 sizeof(void *) * (vector->count - pos - 1));
206 }
207
208 // Set the position
209 vector->list[pos] = item;
210 return vector->count;
211 }
212
213
214 void
vector_remove(vector_t * vector,void * item)215 vector_remove(vector_t *vector, void *item)
216 {
217 // Get item position
218 int idx = vector_index(vector, item);
219 // Not found in the vector
220 if (idx == -1)
221 return;
222
223 // Decrease item counter
224 vector->count--;
225 // Move the rest of the elements one position up
226 memmove(vector->list + idx, vector->list + idx + 1, sizeof(void *) * (vector->count - idx));
227 // Reset vector last position
228 vector->list[vector->count] = NULL;
229
230 // Destroy the item if vector has a destroyer
231 if (vector->destroyer) {
232 vector->destroyer(item);
233 }
234 }
235
236 void
vector_set_destroyer(vector_t * vector,void (* destroyer)(void * item))237 vector_set_destroyer(vector_t *vector, void (*destroyer) (void *item))
238 {
239 vector->destroyer = destroyer;
240 }
241
242 void
vector_set_sorter(vector_t * vector,void (* sorter)(vector_t * vector,void * item))243 vector_set_sorter(vector_t *vector, void (*sorter) (vector_t *vector, void *item))
244 {
245 vector->sorter = sorter;
246 }
247
248 void
vector_generic_destroyer(void * item)249 vector_generic_destroyer(void *item)
250 {
251 sng_free(item);
252 }
253
254 void *
vector_item(vector_t * vector,int index)255 vector_item(vector_t *vector, int index)
256 {
257 if (!vector || index >= vector->count || index < 0)
258 return NULL;
259 return vector->list[index];
260 }
261
262 void
vector_set_item(vector_t * vector,int index,void * item)263 vector_set_item(vector_t *vector, int index, void *item)
264 {
265 if (!vector || index >= vector->count || index < 0)
266 return;
267 vector->list[index] = item;
268 }
269
270 void *
vector_first(vector_t * vector)271 vector_first(vector_t *vector)
272 {
273 return vector_item(vector, 0);
274 }
275
276 void *
vector_last(vector_t * vector)277 vector_last(vector_t *vector)
278 {
279 return vector_item(vector, vector_count(vector) - 1);
280 }
281
282 int
vector_index(vector_t * vector,void * item)283 vector_index(vector_t *vector, void *item)
284 {
285 // FIXME Bad perfomance
286 int i;
287 for (i = 0; i < vector->count; i++) {
288 if (vector->list[i] == item)
289 return i;
290 }
291 return -1;
292 }
293
294 int
vector_count(vector_t * vector)295 vector_count(vector_t *vector)
296 {
297 return (vector) ? vector->count : 0;
298 }
299
300 vector_iter_t
vector_iterator(vector_t * vector)301 vector_iterator(vector_t *vector)
302 {
303 vector_iter_t it;
304 memset(&it, 0, sizeof(vector_iter_t));
305 it.current = -1;
306 it.vector = vector;
307 return it;
308 }
309
310 vector_t *
vector_iterator_vector(vector_iter_t * it)311 vector_iterator_vector(vector_iter_t *it)
312 {
313 return it->vector;
314 }
315
316 int
vector_iterator_count(vector_iter_t * it)317 vector_iterator_count(vector_iter_t *it)
318 {
319 int count = 0;
320 int pos = it->current;
321
322 vector_iterator_reset(it);
323
324 if (!it->filter) {
325 count = vector_count(it->vector);
326 } else {
327 while (vector_iterator_next(it)) {
328 count++;
329 }
330 }
331
332 vector_iterator_set_current(it, pos);
333
334 return count;
335 }
336
337 void *
vector_iterator_next(vector_iter_t * it)338 vector_iterator_next(vector_iter_t *it)
339 {
340 void *item;
341
342 if (!it || it->current >= vector_count(it->vector))
343 return NULL;
344
345 while ((item = vector_item(it->vector, ++it->current))) {
346 if (it->filter) {
347 if (it->filter(item)) {
348 return item;
349 }
350 } else {
351 return item;
352 }
353 }
354 return NULL;
355 }
356
357 void *
vector_iterator_prev(vector_iter_t * it)358 vector_iterator_prev(vector_iter_t *it)
359 {
360 void *item;
361
362 if (it->current == -1)
363 return NULL;
364
365 while ((item = vector_item(it->vector, --it->current))) {
366 if (it->filter) {
367 if (it->filter(item)) {
368 return item;
369 }
370 } else {
371 return item;
372 }
373 }
374 return NULL;
375 }
376
377 void
vector_iterator_set_filter(vector_iter_t * it,int (* filter)(void * item))378 vector_iterator_set_filter(vector_iter_t *it, int
379 (*filter)(void *item))
380 {
381 it->filter = filter;
382 }
383
384 void
vector_iterator_set_current(vector_iter_t * it,int current)385 vector_iterator_set_current(vector_iter_t *it, int current)
386 {
387 it->current = current;
388 }
389
390 void
vector_iterator_set_last(vector_iter_t * it)391 vector_iterator_set_last(vector_iter_t *it)
392 {
393 it->current = vector_count(it->vector);
394 }
395
396 int
vector_iterator_current(vector_iter_t * it)397 vector_iterator_current(vector_iter_t *it)
398 {
399 return it->current;
400 }
401
402 void
vector_iterator_reset(vector_iter_t * it)403 vector_iterator_reset(vector_iter_t *it)
404 {
405 vector_iterator_set_current(it, -1);
406 }
407
408