blob: ee07cbd2b63dc38e5b3322535e47284d5a701639 [file] [log] [blame]
Neels Hofmeyr17518fe2017-06-20 04:35:06 +02001/*! \file vector.c
2 * Generic vector interface routine. */
3/*
Harald Welte3fb0b6f2010-05-19 19:02:52 +02004 * Copyright (C) 1997 Kunihiro Ishiguro
5 *
6 * This file is part of GNU Zebra.
7 *
8 * GNU Zebra is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2, or (at your option) any
11 * later version.
12 *
13 * GNU Zebra is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with GNU Zebra; see the file COPYING. If not, write to the Free
Jaroslav Škarvada2b82c1c2015-11-11 16:02:54 +010020 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
Harald Welte3fb0b6f2010-05-19 19:02:52 +020022 */
23
24#include <stdlib.h>
25#include <unistd.h>
26
27#include <osmocom/vty/vector.h>
28#include <osmocom/vty/vty.h>
Pablo Neira Ayuso83419342011-03-22 16:36:13 +010029#include <osmocom/core/talloc.h>
Harald Welte20144f72014-03-11 10:47:08 +010030#include <string.h>
Harald Welte3fb0b6f2010-05-19 19:02:52 +020031
Harald Welte96e2a002017-06-12 21:44:18 +020032/*! \addtogroup vector
33 * @{
Neels Hofmeyr87e45502017-06-20 00:17:59 +020034 * Generic vector routines, used by VTY internally
Harald Welte96e2a002017-06-12 21:44:18 +020035 */
36
Harald Welte3fb0b6f2010-05-19 19:02:52 +020037void *tall_vty_vec_ctx;
38
39/* Initialize vector : allocate memory and return vector. */
40vector vector_init(unsigned int size)
41{
42 vector v = talloc_zero(tall_vty_vec_ctx, struct _vector);
43 if (!v)
44 return NULL;
45
46 /* allocate at least one slot */
47 if (size == 0)
48 size = 1;
49
50 v->alloced = size;
51 v->active = 0;
52 v->index = _talloc_zero(tall_vty_vec_ctx, sizeof(void *) * size,
53 "vector_init:index");
54 if (!v->index) {
55 talloc_free(v);
56 return NULL;
57 }
58 return v;
59}
60
61void vector_only_wrapper_free(vector v)
62{
63 talloc_free(v);
64}
65
66void vector_only_index_free(void *index)
67{
68 talloc_free(index);
69}
70
71void vector_free(vector v)
72{
73 talloc_free(v->index);
74 talloc_free(v);
75}
76
77vector vector_copy(vector v)
78{
79 unsigned int size;
80 vector new = talloc_zero(tall_vty_vec_ctx, struct _vector);
81 if (!new)
82 return NULL;
83
84 new->active = v->active;
85 new->alloced = v->alloced;
86
87 size = sizeof(void *) * (v->alloced);
88 new->index = _talloc_zero(tall_vty_vec_ctx, size, "vector_copy:index");
89 if (!new->index) {
90 talloc_free(new);
91 return NULL;
92 }
93 memcpy(new->index, v->index, size);
94
95 return new;
96}
97
98/* Check assigned index, and if it runs short double index pointer */
99void vector_ensure(vector v, unsigned int num)
100{
101 if (v->alloced > num)
102 return;
103
104 v->index = talloc_realloc_size(tall_vty_vec_ctx, v->index,
105 sizeof(void *) * (v->alloced * 2));
106 memset(&v->index[v->alloced], 0, sizeof(void *) * v->alloced);
107 v->alloced *= 2;
108
109 if (v->alloced <= num)
110 vector_ensure(v, num);
111}
112
113/* This function only returns next empty slot index. It dose not mean
114 the slot's index memory is assigned, please call vector_ensure()
115 after calling this function. */
116int vector_empty_slot(vector v)
117{
118 unsigned int i;
119
120 if (v->active == 0)
121 return 0;
122
123 for (i = 0; i < v->active; i++)
124 if (v->index[i] == 0)
125 return i;
126
127 return i;
128}
129
130/* Set value to the smallest empty slot. */
131int vector_set(vector v, void *val)
132{
133 unsigned int i;
134
135 i = vector_empty_slot(v);
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/* Set value to specified index slot. */
147int vector_set_index(vector v, unsigned int i, void *val)
148{
149 vector_ensure(v, i);
150
151 v->index[i] = val;
152
153 if (v->active <= i)
154 v->active = i + 1;
155
156 return i;
157}
158
159/* Look up vector. */
160void *vector_lookup(vector v, unsigned int i)
161{
162 if (i >= v->active)
163 return NULL;
164 return v->index[i];
165}
166
167/* Lookup vector, ensure it. */
168void *vector_lookup_ensure(vector v, unsigned int i)
169{
170 vector_ensure(v, i);
171 return v->index[i];
172}
173
174/* Unset value at specified index slot. */
175void vector_unset(vector v, unsigned int i)
176{
177 if (i >= v->alloced)
178 return;
179
180 v->index[i] = NULL;
181
182 if (i + 1 == v->active) {
183 v->active--;
184 while (i && v->index[--i] == NULL && v->active--) ; /* Is this ugly ? */
185 }
186}
187
188/* Count the number of not emplty slot. */
189unsigned int vector_count(vector v)
190{
191 unsigned int i;
192 unsigned count = 0;
193
194 for (i = 0; i < v->active; i++)
195 if (v->index[i] != NULL)
196 count++;
197
198 return count;
199}
Harald Welte96e2a002017-06-12 21:44:18 +0200200
201/*! @} */