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