blob: c8885a41446ee5b9335f25ebb222cc665f4a22ab [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>
Harald Welte2477d932009-08-07 00:32:41 +020026#include <openbsc/talloc.h>
Harald Welte955049f2009-03-10 12:16:51 +000027#include <memory.h>
28
Harald Welte2477d932009-08-07 00:32:41 +020029static void *tall_vvec_ctx;
30
Harald Welte955049f2009-03-10 12:16:51 +000031/* Initialize vector : allocate memory and return vector. */
32vector vector_init(unsigned int size)
33{
Harald Welte2477d932009-08-07 00:32:41 +020034 vector v = talloc_zero(tall_vvec_ctx, struct _vector);
Harald Welte955049f2009-03-10 12:16:51 +000035 if (!v)
36 return NULL;
37
38 /* allocate at least one slot */
39 if (size == 0)
40 size = 1;
41
42 v->alloced = size;
43 v->active = 0;
Harald Welte2477d932009-08-07 00:32:41 +020044 v->index = _talloc_zero(tall_vvec_ctx, sizeof(void *) * size,
45 "vector_init:index");
Harald Welte955049f2009-03-10 12:16:51 +000046 if (!v->index) {
Harald Welte2477d932009-08-07 00:32:41 +020047 talloc_free(v);
Harald Welte955049f2009-03-10 12:16:51 +000048 return NULL;
49 }
50 return v;
51}
52
53void vector_only_wrapper_free(vector v)
54{
Harald Welte2477d932009-08-07 00:32:41 +020055 talloc_free(v);
Harald Welte955049f2009-03-10 12:16:51 +000056}
57
58void vector_only_index_free(void *index)
59{
Harald Welte2477d932009-08-07 00:32:41 +020060 talloc_free(index);
Harald Welte955049f2009-03-10 12:16:51 +000061}
62
63void vector_free(vector v)
64{
Harald Welte2477d932009-08-07 00:32:41 +020065 talloc_free(v->index);
66 talloc_free(v);
Harald Welte955049f2009-03-10 12:16:51 +000067}
68
69vector vector_copy(vector v)
70{
71 unsigned int size;
Harald Welte2477d932009-08-07 00:32:41 +020072 vector new = talloc_zero(tall_vvec_ctx, struct _vector);
Harald Welte955049f2009-03-10 12:16:51 +000073 if (!new)
74 return NULL;
75
76 new->active = v->active;
77 new->alloced = v->alloced;
78
79 size = sizeof(void *) * (v->alloced);
Harald Welte2477d932009-08-07 00:32:41 +020080 new->index = _talloc_zero(tall_vvec_ctx, size, "vector_copy:index");
Harald Welte955049f2009-03-10 12:16:51 +000081 if (!new->index) {
Harald Welte2477d932009-08-07 00:32:41 +020082 talloc_free(new);
Harald Welte955049f2009-03-10 12:16:51 +000083 return NULL;
84 }
85 memcpy(new->index, v->index, size);
86
87 return new;
88}
89
90/* Check assigned index, and if it runs short double index pointer */
91void vector_ensure(vector v, unsigned int num)
92{
93 if (v->alloced > num)
94 return;
95
Harald Welte2477d932009-08-07 00:32:41 +020096 v->index = talloc_realloc_size(tall_vvec_ctx, v->index,
97 sizeof(void *) * (v->alloced * 2));
Harald Welte955049f2009-03-10 12:16:51 +000098 memset(&v->index[v->alloced], 0, sizeof(void *) * v->alloced);
99 v->alloced *= 2;
100
101 if (v->alloced <= num)
102 vector_ensure(v, num);
103}
104
105/* This function only returns next empty slot index. It dose not mean
106 the slot's index memory is assigned, please call vector_ensure()
107 after calling this function. */
108int vector_empty_slot(vector v)
109{
110 unsigned int i;
111
112 if (v->active == 0)
113 return 0;
114
115 for (i = 0; i < v->active; i++)
116 if (v->index[i] == 0)
117 return i;
118
119 return i;
120}
121
122/* Set value to the smallest empty slot. */
123int vector_set(vector v, void *val)
124{
125 unsigned int i;
126
127 i = vector_empty_slot(v);
128 vector_ensure(v, i);
129
130 v->index[i] = val;
131
132 if (v->active <= i)
133 v->active = i + 1;
134
135 return i;
136}
137
138/* Set value to specified index slot. */
139int vector_set_index(vector v, unsigned int i, void *val)
140{
141 vector_ensure(v, i);
142
143 v->index[i] = val;
144
145 if (v->active <= i)
146 v->active = i + 1;
147
148 return i;
149}
150
151/* Look up vector. */
152void *vector_lookup(vector v, unsigned int i)
153{
154 if (i >= v->active)
155 return NULL;
156 return v->index[i];
157}
158
159/* Lookup vector, ensure it. */
160void *vector_lookup_ensure(vector v, unsigned int i)
161{
162 vector_ensure(v, i);
163 return v->index[i];
164}
165
166/* Unset value at specified index slot. */
167void vector_unset(vector v, unsigned int i)
168{
169 if (i >= v->alloced)
170 return;
171
172 v->index[i] = NULL;
173
174 if (i + 1 == v->active) {
175 v->active--;
176 while (i && v->index[--i] == NULL && v->active--) ; /* Is this ugly ? */
177 }
178}
179
180/* Count the number of not emplty slot. */
181unsigned int vector_count(vector v)
182{
183 unsigned int i;
184 unsigned count = 0;
185
186 for (i = 0; i < v->active; i++)
187 if (v->index[i] != NULL)
188 count++;
189
190 return count;
191}
Harald Welte2477d932009-08-07 00:32:41 +0200192
193static __attribute__((constructor)) void on_dso_load_vty_vec(void)
194{
195 tall_vvec_ctx = talloc_named_const(NULL, 1, "vty_vector");
196}