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