blob: 76870105ba20950126cd8872694dabd5a4dc7cc6 [file] [log] [blame]
Harald Welte955049f2009-03-10 12:16:51 +00001/* Generic vector interface routine
2 * Copyright (C) 1997 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22#include <stdlib.h>
23#include <unistd.h>
24
25#include <vty/vector.h>
26#include <memory.h>
27
28/* Initialize vector : allocate memory and return vector. */
29vector vector_init(unsigned int size)
30{
31 vector v = calloc(1, sizeof(struct _vector));
32 if (!v)
33 return NULL;
34
35 /* allocate at least one slot */
36 if (size == 0)
37 size = 1;
38
39 v->alloced = size;
40 v->active = 0;
41 v->index = calloc(1, sizeof(void *) * size);
42 if (!v->index) {
43 free(v);
44 return NULL;
45 }
46 return v;
47}
48
49void vector_only_wrapper_free(vector v)
50{
51 free(v);
52}
53
54void vector_only_index_free(void *index)
55{
56 free(index);
57}
58
59void vector_free(vector v)
60{
61 free(v->index);
62 free(v);
63}
64
65vector vector_copy(vector v)
66{
67 unsigned int size;
68 vector new = calloc(1, sizeof(struct _vector));
69 if (!new)
70 return NULL;
71
72 new->active = v->active;
73 new->alloced = v->alloced;
74
75 size = sizeof(void *) * (v->alloced);
76 new->index = calloc(1, size);
77 if (!new->index) {
78 free(new);
79 return NULL;
80 }
81 memcpy(new->index, v->index, size);
82
83 return new;
84}
85
86/* Check assigned index, and if it runs short double index pointer */
87void vector_ensure(vector v, unsigned int num)
88{
89 if (v->alloced > num)
90 return;
91
92 v->index = realloc(v->index, sizeof(void *) * (v->alloced * 2));
93 memset(&v->index[v->alloced], 0, sizeof(void *) * v->alloced);
94 v->alloced *= 2;
95
96 if (v->alloced <= num)
97 vector_ensure(v, num);
98}
99
100/* This function only returns next empty slot index. It dose not mean
101 the slot's index memory is assigned, please call vector_ensure()
102 after calling this function. */
103int vector_empty_slot(vector v)
104{
105 unsigned int i;
106
107 if (v->active == 0)
108 return 0;
109
110 for (i = 0; i < v->active; i++)
111 if (v->index[i] == 0)
112 return i;
113
114 return i;
115}
116
117/* Set value to the smallest empty slot. */
118int vector_set(vector v, void *val)
119{
120 unsigned int i;
121
122 i = vector_empty_slot(v);
123 vector_ensure(v, i);
124
125 v->index[i] = val;
126
127 if (v->active <= i)
128 v->active = i + 1;
129
130 return i;
131}
132
133/* Set value to specified index slot. */
134int vector_set_index(vector v, unsigned int i, void *val)
135{
136 vector_ensure(v, i);
137
138 v->index[i] = val;
139
140 if (v->active <= i)
141 v->active = i + 1;
142
143 return i;
144}
145
146/* Look up vector. */
147void *vector_lookup(vector v, unsigned int i)
148{
149 if (i >= v->active)
150 return NULL;
151 return v->index[i];
152}
153
154/* Lookup vector, ensure it. */
155void *vector_lookup_ensure(vector v, unsigned int i)
156{
157 vector_ensure(v, i);
158 return v->index[i];
159}
160
161/* Unset value at specified index slot. */
162void vector_unset(vector v, unsigned int i)
163{
164 if (i >= v->alloced)
165 return;
166
167 v->index[i] = NULL;
168
169 if (i + 1 == v->active) {
170 v->active--;
171 while (i && v->index[--i] == NULL && v->active--) ; /* Is this ugly ? */
172 }
173}
174
175/* Count the number of not emplty slot. */
176unsigned int vector_count(vector v)
177{
178 unsigned int i;
179 unsigned count = 0;
180
181 for (i = 0; i < v->active; i++)
182 if (v->index[i] != NULL)
183 count++;
184
185 return count;
186}