blob: 371f71d955888675124ace5c8aa04fd253ae96cc [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 Welte0224e4d2009-08-07 13:25:41 +020026#include <vty/vty.h>
Harald Welte2477d932009-08-07 00:32:41 +020027#include <openbsc/talloc.h>
Harald Welte955049f2009-03-10 12:16:51 +000028#include <memory.h>
29
30/* Initialize vector : allocate memory and return vector. */
31vector vector_init(unsigned int size)
32{
Harald Welte0224e4d2009-08-07 13:25:41 +020033 vector v = talloc_zero(tall_vty_ctx, struct _vector);
Harald Welte955049f2009-03-10 12:16:51 +000034 if (!v)
35 return NULL;
36
37 /* allocate at least one slot */
38 if (size == 0)
39 size = 1;
40
41 v->alloced = size;
42 v->active = 0;
Harald Welte0224e4d2009-08-07 13:25:41 +020043 v->index = _talloc_zero(tall_vty_ctx, sizeof(void *) * size,
Harald Welte2477d932009-08-07 00:32:41 +020044 "vector_init:index");
Harald Welte955049f2009-03-10 12:16:51 +000045 if (!v->index) {
Harald Welte2477d932009-08-07 00:32:41 +020046 talloc_free(v);
Harald Welte955049f2009-03-10 12:16:51 +000047 return NULL;
48 }
49 return v;
50}
51
52void vector_only_wrapper_free(vector v)
53{
Harald Welte2477d932009-08-07 00:32:41 +020054 talloc_free(v);
Harald Welte955049f2009-03-10 12:16:51 +000055}
56
57void vector_only_index_free(void *index)
58{
Harald Welte2477d932009-08-07 00:32:41 +020059 talloc_free(index);
Harald Welte955049f2009-03-10 12:16:51 +000060}
61
62void vector_free(vector v)
63{
Harald Welte2477d932009-08-07 00:32:41 +020064 talloc_free(v->index);
65 talloc_free(v);
Harald Welte955049f2009-03-10 12:16:51 +000066}
67
68vector vector_copy(vector v)
69{
70 unsigned int size;
Harald Welte0224e4d2009-08-07 13:25:41 +020071 vector new = talloc_zero(tall_vty_ctx, struct _vector);
Harald Welte955049f2009-03-10 12:16:51 +000072 if (!new)
73 return NULL;
74
75 new->active = v->active;
76 new->alloced = v->alloced;
77
78 size = sizeof(void *) * (v->alloced);
Harald Welte0224e4d2009-08-07 13:25:41 +020079 new->index = _talloc_zero(tall_vty_ctx, size, "vector_copy:index");
Harald Welte955049f2009-03-10 12:16:51 +000080 if (!new->index) {
Harald Welte2477d932009-08-07 00:32:41 +020081 talloc_free(new);
Harald Welte955049f2009-03-10 12:16:51 +000082 return NULL;
83 }
84 memcpy(new->index, v->index, size);
85
86 return new;
87}
88
89/* Check assigned index, and if it runs short double index pointer */
90void vector_ensure(vector v, unsigned int num)
91{
92 if (v->alloced > num)
93 return;
94
Harald Welte0224e4d2009-08-07 13:25:41 +020095 v->index = talloc_realloc_size(tall_vty_ctx, v->index,
Harald Welte2477d932009-08-07 00:32:41 +020096 sizeof(void *) * (v->alloced * 2));
Harald Welte955049f2009-03-10 12:16:51 +000097 memset(&v->index[v->alloced], 0, sizeof(void *) * v->alloced);
98 v->alloced *= 2;
99
100 if (v->alloced <= num)
101 vector_ensure(v, num);
102}
103
104/* This function only returns next empty slot index. It dose not mean
105 the slot's index memory is assigned, please call vector_ensure()
106 after calling this function. */
107int vector_empty_slot(vector v)
108{
109 unsigned int i;
110
111 if (v->active == 0)
112 return 0;
113
114 for (i = 0; i < v->active; i++)
115 if (v->index[i] == 0)
116 return i;
117
118 return i;
119}
120
121/* Set value to the smallest empty slot. */
122int vector_set(vector v, void *val)
123{
124 unsigned int i;
125
126 i = vector_empty_slot(v);
127 vector_ensure(v, i);
128
129 v->index[i] = val;
130
131 if (v->active <= i)
132 v->active = i + 1;
133
134 return i;
135}
136
137/* Set value to specified index slot. */
138int vector_set_index(vector v, unsigned int i, void *val)
139{
140 vector_ensure(v, i);
141
142 v->index[i] = val;
143
144 if (v->active <= i)
145 v->active = i + 1;
146
147 return i;
148}
149
150/* Look up vector. */
151void *vector_lookup(vector v, unsigned int i)
152{
153 if (i >= v->active)
154 return NULL;
155 return v->index[i];
156}
157
158/* Lookup vector, ensure it. */
159void *vector_lookup_ensure(vector v, unsigned int i)
160{
161 vector_ensure(v, i);
162 return v->index[i];
163}
164
165/* Unset value at specified index slot. */
166void vector_unset(vector v, unsigned int i)
167{
168 if (i >= v->alloced)
169 return;
170
171 v->index[i] = NULL;
172
173 if (i + 1 == v->active) {
174 v->active--;
175 while (i && v->index[--i] == NULL && v->active--) ; /* Is this ugly ? */
176 }
177}
178
179/* Count the number of not emplty slot. */
180unsigned int vector_count(vector v)
181{
182 unsigned int i;
183 unsigned count = 0;
184
185 for (i = 0; i < v->active; i++)
186 if (v->index[i] != NULL)
187 count++;
188
189 return count;
190}