blob: c21bca7070b1701a753afe060f2eee39aeb96670 [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
Jaroslav Škarvada2b82c1c2015-11-11 16:02:54 +010018 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
Harald Welte3fb0b6f2010-05-19 19:02:52 +020020 */
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
Harald Welte96e2a002017-06-12 21:44:18 +020030/*! \addtogroup vector
31 * @{
Neels Hofmeyr87e45502017-06-20 00:17:59 +020032 * Generic vector routines, used by VTY internally
Harald Welte96e2a002017-06-12 21:44:18 +020033 */
34
Harald Welte3fb0b6f2010-05-19 19:02:52 +020035void *tall_vty_vec_ctx;
36
37/* Initialize vector : allocate memory and return vector. */
38vector vector_init(unsigned int size)
39{
40 vector v = talloc_zero(tall_vty_vec_ctx, struct _vector);
41 if (!v)
42 return NULL;
43
44 /* allocate at least one slot */
45 if (size == 0)
46 size = 1;
47
48 v->alloced = size;
49 v->active = 0;
50 v->index = _talloc_zero(tall_vty_vec_ctx, sizeof(void *) * size,
51 "vector_init:index");
52 if (!v->index) {
53 talloc_free(v);
54 return NULL;
55 }
56 return v;
57}
58
59void vector_only_wrapper_free(vector v)
60{
61 talloc_free(v);
62}
63
64void vector_only_index_free(void *index)
65{
66 talloc_free(index);
67}
68
69void vector_free(vector v)
70{
71 talloc_free(v->index);
72 talloc_free(v);
73}
74
75vector vector_copy(vector v)
76{
77 unsigned int size;
78 vector new = talloc_zero(tall_vty_vec_ctx, struct _vector);
79 if (!new)
80 return NULL;
81
82 new->active = v->active;
83 new->alloced = v->alloced;
84
85 size = sizeof(void *) * (v->alloced);
86 new->index = _talloc_zero(tall_vty_vec_ctx, size, "vector_copy:index");
87 if (!new->index) {
88 talloc_free(new);
89 return NULL;
90 }
91 memcpy(new->index, v->index, size);
92
93 return new;
94}
95
96/* Check assigned index, and if it runs short double index pointer */
97void vector_ensure(vector v, unsigned int num)
98{
99 if (v->alloced > num)
100 return;
101
102 v->index = talloc_realloc_size(tall_vty_vec_ctx, v->index,
103 sizeof(void *) * (v->alloced * 2));
104 memset(&v->index[v->alloced], 0, sizeof(void *) * v->alloced);
105 v->alloced *= 2;
106
107 if (v->alloced <= num)
108 vector_ensure(v, num);
109}
110
111/* This function only returns next empty slot index. It dose not mean
112 the slot's index memory is assigned, please call vector_ensure()
113 after calling this function. */
114int vector_empty_slot(vector v)
115{
116 unsigned int i;
117
118 if (v->active == 0)
119 return 0;
120
121 for (i = 0; i < v->active; i++)
122 if (v->index[i] == 0)
123 return i;
124
125 return i;
126}
127
128/* Set value to the smallest empty slot. */
129int vector_set(vector v, void *val)
130{
131 unsigned int i;
132
133 i = vector_empty_slot(v);
134 vector_ensure(v, i);
135
136 v->index[i] = val;
137
138 if (v->active <= i)
139 v->active = i + 1;
140
141 return i;
142}
143
144/* Set value to specified index slot. */
145int vector_set_index(vector v, unsigned int i, void *val)
146{
147 vector_ensure(v, i);
148
149 v->index[i] = val;
150
151 if (v->active <= i)
152 v->active = i + 1;
153
154 return i;
155}
156
157/* Look up vector. */
158void *vector_lookup(vector v, unsigned int i)
159{
160 if (i >= v->active)
161 return NULL;
162 return v->index[i];
163}
164
165/* Lookup vector, ensure it. */
166void *vector_lookup_ensure(vector v, unsigned int i)
167{
168 vector_ensure(v, i);
169 return v->index[i];
170}
171
172/* Unset value at specified index slot. */
173void vector_unset(vector v, unsigned int i)
174{
175 if (i >= v->alloced)
176 return;
177
178 v->index[i] = NULL;
179
180 if (i + 1 == v->active) {
181 v->active--;
182 while (i && v->index[--i] == NULL && v->active--) ; /* Is this ugly ? */
183 }
184}
185
186/* Count the number of not emplty slot. */
187unsigned int vector_count(vector v)
188{
189 unsigned int i;
190 unsigned count = 0;
191
192 for (i = 0; i < v->active; i++)
193 if (v->index[i] != NULL)
194 count++;
195
196 return count;
197}
Harald Welte96e2a002017-06-12 21:44:18 +0200198
199/*! @} */