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