libosmocore/src/vty/vector.c

199 lines
3.8 KiB
C

/*! \file vector.c
* Generic vector interface routine. */
/*
* Copyright (C) 1997 Kunihiro Ishiguro
*
* SPDX-License-Identifier: GPL-2.0+
*
* This file is part of GNU Zebra.
*
* GNU Zebra is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* GNU Zebra is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
#include <stdlib.h>
#include <unistd.h>
#include <osmocom/vty/vector.h>
#include <osmocom/vty/vty.h>
#include <osmocom/core/talloc.h>
#include <string.h>
/*! \addtogroup vector
* @{
* Generic vector routines, used by VTY internally
*/
void *tall_vty_vec_ctx;
/* Initialize vector : allocate memory and return vector. */
vector vector_init(unsigned int size)
{
vector v = talloc_zero(tall_vty_vec_ctx, struct _vector);
if (!v)
return NULL;
/* allocate at least one slot */
if (size == 0)
size = 1;
v->alloced = size;
v->active = 0;
v->index = _talloc_zero(tall_vty_vec_ctx, sizeof(void *) * size,
"vector_init:index");
if (!v->index) {
talloc_free(v);
return NULL;
}
return v;
}
void vector_only_wrapper_free(vector v)
{
talloc_free(v);
}
void vector_only_index_free(void *index)
{
talloc_free(index);
}
void vector_free(vector v)
{
talloc_free(v->index);
talloc_free(v);
}
vector vector_copy(vector v)
{
unsigned int size;
vector new = talloc_zero(tall_vty_vec_ctx, struct _vector);
if (!new)
return NULL;
new->active = v->active;
new->alloced = v->alloced;
size = sizeof(void *) * (v->alloced);
new->index = _talloc_zero(tall_vty_vec_ctx, size, "vector_copy:index");
if (!new->index) {
talloc_free(new);
return NULL;
}
memcpy(new->index, v->index, size);
return new;
}
/* Check assigned index, and if it runs short double index pointer */
void vector_ensure(vector v, unsigned int num)
{
if (v->alloced > num)
return;
v->index = talloc_realloc_size(tall_vty_vec_ctx, v->index,
sizeof(void *) * (v->alloced * 2));
memset(&v->index[v->alloced], 0, sizeof(void *) * v->alloced);
v->alloced *= 2;
if (v->alloced <= num)
vector_ensure(v, num);
}
/* This function only returns next empty slot index. It dose not mean
the slot's index memory is assigned, please call vector_ensure()
after calling this function. */
int vector_empty_slot(vector v)
{
unsigned int i;
if (v->active == 0)
return 0;
for (i = 0; i < v->active; i++)
if (v->index[i] == 0)
return i;
return i;
}
/* Set value to the smallest empty slot. */
int vector_set(vector v, void *val)
{
unsigned int i;
i = vector_empty_slot(v);
vector_ensure(v, i);
v->index[i] = val;
if (v->active <= i)
v->active = i + 1;
return i;
}
/* Set value to specified index slot. */
int vector_set_index(vector v, unsigned int i, void *val)
{
vector_ensure(v, i);
v->index[i] = val;
if (v->active <= i)
v->active = i + 1;
return i;
}
/* Look up vector. */
void *vector_lookup(vector v, unsigned int i)
{
if (i >= v->active)
return NULL;
return v->index[i];
}
/* Lookup vector, ensure it. */
void *vector_lookup_ensure(vector v, unsigned int i)
{
vector_ensure(v, i);
return v->index[i];
}
/* Unset value at specified index slot. */
void vector_unset(vector v, unsigned int i)
{
if (i >= v->alloced)
return;
v->index[i] = NULL;
if (i + 1 == v->active) {
v->active--;
while (i && v->index[--i] == NULL && v->active--) ; /* Is this ugly ? */
}
}
/* Count the number of not emplty slot. */
unsigned int vector_count(vector v)
{
unsigned int i;
unsigned count = 0;
for (i = 0; i < v->active; i++)
if (v->index[i] != NULL)
count++;
return count;
}
/*! @} */