1/* 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 18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 19 * 02111-1307, USA. 20 */ 21 22#include <zebra.h> 23 24#include "vector.h" 25#include "memory.h" 26 27/* Initialize vector : allocate memory and return vector. */ 28vector 29vector_init (unsigned int size) 30{ 31 vector v = XCALLOC (MTYPE_VECTOR, sizeof (struct _vector)); 32 33 /* allocate at least one slot */ 34 if (size == 0) 35 size = 1; 36 37 v->alloced = size; 38 v->active = 0; 39 v->index = XCALLOC (MTYPE_VECTOR_INDEX, sizeof (void *) * size); 40 return v; 41} 42 43void 44vector_only_wrapper_free (vector v) 45{ 46 XFREE (MTYPE_VECTOR, v); 47} 48 49void 50vector_only_index_free (void *index) 51{ 52 XFREE (MTYPE_VECTOR_INDEX, index); 53} 54 55void 56vector_free (vector v) 57{ 58 XFREE (MTYPE_VECTOR_INDEX, v->index); 59 XFREE (MTYPE_VECTOR, v); 60} 61 62vector 63vector_copy (vector v) 64{ 65 unsigned int size; 66 vector new = XCALLOC (MTYPE_VECTOR, sizeof (struct _vector)); 67 68 new->active = v->active; 69 new->alloced = v->alloced; 70 71 size = sizeof (void *) * (v->alloced); 72 new->index = XCALLOC (MTYPE_VECTOR_INDEX, size); 73 memcpy (new->index, v->index, size); 74 75 return new; 76} 77 78/* Check assigned index, and if it runs short double index pointer */ 79void 80vector_ensure (vector v, unsigned int num) 81{ 82 if (v->alloced > num) 83 return; 84 85 v->index = XREALLOC (MTYPE_VECTOR_INDEX, 86 v->index, sizeof (void *) * (v->alloced * 2)); 87 memset (&v->index[v->alloced], 0, sizeof (void *) * v->alloced); 88 v->alloced *= 2; 89 90 if (v->alloced <= num) 91 vector_ensure (v, num); 92} 93 94/* This function only returns next empty slot index. It dose not mean 95 the slot's index memory is assigned, please call vector_ensure() 96 after calling this function. */ 97int 98vector_empty_slot (vector v) 99{ 100 unsigned int i; 101 102 if (v->active == 0) 103 return 0; 104 105 for (i = 0; i < v->active; i++) 106 if (v->index[i] == 0) 107 return i; 108 109 return i; 110} 111 112/* Set value to the smallest empty slot. */ 113int 114vector_set (vector v, void *val) 115{ 116 unsigned int i; 117 118 i = vector_empty_slot (v); 119 vector_ensure (v, i); 120 121 v->index[i] = val; 122 123 if (v->active <= i) 124 v->active = i + 1; 125 126 return i; 127} 128 129/* Set value to specified index slot. */ 130int 131vector_set_index (vector v, unsigned int i, void *val) 132{ 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/* Look up vector. */ 144void * 145vector_lookup (vector v, unsigned int i) 146{ 147 if (i >= v->active) 148 return NULL; 149 return v->index[i]; 150} 151 152/* Lookup vector, ensure it. */ 153void * 154vector_lookup_ensure (vector v, unsigned int i) 155{ 156 vector_ensure (v, i); 157 return v->index[i]; 158} 159 160/* Unset value at specified index slot. */ 161void 162vector_unset (vector v, unsigned int i) 163{ 164 if (i >= v->alloced) 165 return; 166 167 v->index[i] = NULL; 168 169 if (i + 1 == v->active) 170 { 171 v->active--; 172 while (i && v->index[--i] == NULL && v->active--) 173 ; /* Is this ugly ? */ 174 } 175} 176 177/* Count the number of not emplty slot. */ 178unsigned int 179vector_count (vector v) 180{ 181 unsigned int i; 182 unsigned count = 0; 183 184 for (i = 0; i < v->active; i++) 185 if (v->index[i] != NULL) 186 count++; 187 188 return count; 189} 190