/*-1* Copyright (c) 2009 The NetBSD Foundation, Inc.2* All rights reserved.3*4* This code is derived from software contributed to The NetBSD Foundation5* by David A. Holland.6*7* Redistribution and use in source and binary forms, with or without8* modification, are permitted provided that the following conditions9* are met:10* 1. Redistributions of source code must retain the above copyright11* notice, this list of conditions and the following disclaimer.12* 2. Redistributions in binary form must reproduce the above copyright13* notice, this list of conditions and the following disclaimer in the14* documentation and/or other materials provided with the distribution.15*16* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS17* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED18* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR19* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS20* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR21* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF22* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS23* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN24* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)25* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE26* POSSIBILITY OF SUCH DAMAGE.27*/2829#define ARRAYINLINE3031#include <types.h>32#include <kern/errno.h>33#include <lib.h>34#include <array.h>3536struct array *37array_create(void)38{39struct array *a;4041a = kmalloc(sizeof(*a));42if (a != NULL) {43array_init(a);44}45return a;46}4748void49array_destroy(struct array *a)50{51array_cleanup(a);52kfree(a);53}5455void56array_init(struct array *a)57{58a->num = a->max = 0;59a->v = NULL;60}6162void63array_cleanup(struct array *a)64{65/*66* Require array to be empty - helps avoid memory leaks since67* we don't/can't free anything any contents may be pointing68* to.69*/70ARRAYASSERT(a->num == 0);71kfree(a->v);72#ifdef ARRAYS_CHECKED73a->v = NULL;74#endif75}7677int78array_setsize(struct array *a, unsigned num)79{80void **newptr;81unsigned newmax;8283if (num > a->max) {84/* Don't touch A until the allocation succeeds. */85newmax = a->max;86while (num > newmax) {87newmax = newmax ? newmax*2 : 4;88}8990/*91* We don't have krealloc, and it wouldn't be92* worthwhile to implement just for this. So just93* allocate a new block and copy. (Exercise: what94* about this and/or kmalloc makes it not worthwhile?)95*/9697newptr = kmalloc(newmax*sizeof(*a->v));98if (newptr == NULL) {99return ENOMEM;100}101memcpy(newptr, a->v, a->num*sizeof(*a->v));102kfree(a->v);103a->v = newptr;104a->max = newmax;105}106a->num = num;107108return 0;109}110111void112array_remove(struct array *a, unsigned index)113{114unsigned num_to_move;115116ARRAYASSERT(a->num <= a->max);117ARRAYASSERT(index < a->num);118119num_to_move = a->num - (index + 1);120memmove(a->v + index, a->v + index+1, num_to_move*sizeof(void *));121a->num--;122}123124125