blob: aaff87d177d79d806ff63b57e1b811888a7d65c9 [file] [log] [blame]
Harald Welte3fb0b6f2010-05-19 19:02:52 +02001/* 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 <osmocom/vty/vector.h>
26#include <osmocom/vty/vty.h>
Pablo Neira Ayuso83419342011-03-22 16:36:13 +010027#include <osmocom/core/talloc.h>
Harald Welte20144f72014-03-11 10:47:08 +010028#include <string.h>
Harald Welte3fb0b6f2010-05-19 19:02:52 +020029
30void *tall_vty_vec_ctx;
31
32/* Initialize vector : allocate memory and return vector. */
33vector vector_init(unsigned int size)
34{
35 vector v = talloc_zero(tall_vty_vec_ctx, struct _vector);
36 if (!v)
37 return NULL;
38
39 /* allocate at least one slot */
40 if (size == 0)
41 size = 1;
42
43 v->alloced = size;
44 v->active = 0;
45 v->index = _talloc_zero(tall_vty_vec_ctx, sizeof(void *) * size,
46 "vector_init:index");
47 if (!v->index) {
48 talloc_free(v);
49 return NULL;
50 }
51 return v;
52}
53
54void vector_only_wrapper_free(vector v)
55{
56 talloc_free(v);
57}
58
59void vector_only_index_free(void *index)
60{
61 talloc_free(index);
62}
63
64void vector_free(vector v)
65{
66 talloc_free(v->index);
67 talloc_free(v);
68}
69
70vector vector_copy(vector v)
71{
72 unsigned int size;
73 vector new = talloc_zero(tall_vty_vec_ctx, struct _vector);
74 if (!new)
75 return NULL;
76
77 new->active = v->active;
78 new->alloced = v->alloced;
79
80 size = sizeof(void *) * (v->alloced);
81 new->index = _talloc_zero(tall_vty_vec_ctx, size, "vector_copy:index");
82 if (!new->index) {
83 talloc_free(new);
84 return NULL;
85 }
86 memcpy(new->index, v->index, size);
87
88 return new;
89}
90
91/* Check assigned index, and if it runs short double index pointer */
92void vector_ensure(vector v, unsigned int num)
93{
94 if (v->alloced > num)
95 return;
96
97 v->index = talloc_realloc_size(tall_vty_vec_ctx, v->index,
98 sizeof(void *) * (v->alloced * 2));
99 memset(&v->index[v->alloced], 0, sizeof(void *) * v->alloced);
100 v->alloced *= 2;
101
102 if (v->alloced <= num)
103 vector_ensure(v, num);
104}
105
106/* This function only returns next empty slot index. It dose not mean
107 the slot's index memory is assigned, please call vector_ensure()
108 after calling this function. */
109int vector_empty_slot(vector v)
110{
111 unsigned int i;
112
113 if (v->active == 0)
114 return 0;
115
116 for (i = 0; i < v->active; i++)
117 if (v->index[i] == 0)
118 return i;
119
120 return i;
121}
122
123/* Set value to the smallest empty slot. */
124int vector_set(vector v, void *val)
125{
126 unsigned int i;
127
128 i = vector_empty_slot(v);
129 vector_ensure(v, i);
130
131 v->index[i] = val;
132
133 if (v->active <= i)
134 v->active = i + 1;
135
136 return i;
137}
138
139/* Set value to specified index slot. */
140int vector_set_index(vector v, unsigned int i, void *val)
141{
142 vector_ensure(v, i);
143
144 v->index[i] = val;
145
146 if (v->active <= i)
147 v->active = i + 1;
148
149 return i;
150}
151
152/* Look up vector. */
153void *vector_lookup(vector v, unsigned int i)
154{
155 if (i >= v->active)
156 return NULL;
157 return v->index[i];
158}
159
160/* Lookup vector, ensure it. */
161void *vector_lookup_ensure(vector v, unsigned int i)
162{
163 vector_ensure(v, i);
164 return v->index[i];
165}
166
167/* Unset value at specified index slot. */
168void vector_unset(vector v, unsigned int i)
169{
170 if (i >= v->alloced)
171 return;
172
173 v->index[i] = NULL;
174
175 if (i + 1 == v->active) {
176 v->active--;
177 while (i && v->index[--i] == NULL && v->active--) ; /* Is this ugly ? */
178 }
179}
180
181/* Count the number of not emplty slot. */
182unsigned int vector_count(vector v)
183{
184 unsigned int i;
185 unsigned count = 0;
186
187 for (i = 0; i < v->active; i++)
188 if (v->index[i] != NULL)
189 count++;
190
191 return count;
192}