00001 /*- 00002 * Copyright (c) 2009 The NetBSD Foundation, Inc. 00003 * All rights reserved. 00004 * 00005 * This code is derived from software contributed to The NetBSD Foundation 00006 * by David A. Holland. 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions 00010 * are met: 00011 * 1. Redistributions of source code must retain the above copyright 00012 * notice, this list of conditions and the following disclaimer. 00013 * 2. Redistributions in binary form must reproduce the above copyright 00014 * notice, this list of conditions and the following disclaimer in the 00015 * documentation and/or other materials provided with the distribution. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 00018 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 00019 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00020 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 00021 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00022 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00023 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00024 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00025 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00026 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00027 * POSSIBILITY OF SUCH DAMAGE. 00028 */ 00029 00030 #define ARRAYINLINE 00031 00032 #include <types.h> 00033 #include <kern/errno.h> 00034 #include <lib.h> 00035 #include <array.h> 00036 00037 struct array * 00038 array_create(void) 00039 { 00040 struct array *a; 00041 00042 a = kmalloc(sizeof(*a)); 00043 if (a != NULL) { 00044 array_init(a); 00045 } 00046 return a; 00047 } 00048 00049 void 00050 array_destroy(struct array *a) 00051 { 00052 array_cleanup(a); 00053 kfree(a); 00054 } 00055 00056 void 00057 array_init(struct array *a) 00058 { 00059 a->num = a->max = 0; 00060 a->v = NULL; 00061 } 00062 00063 void 00064 array_cleanup(struct array *a) 00065 { 00066 /* 00067 * Require array to be empty - helps avoid memory leaks since 00068 * we don't/can't free anything any contents may be pointing 00069 * to. 00070 */ 00071 ARRAYASSERT(a->num == 0); 00072 kfree(a->v); 00073 #ifdef ARRAYS_CHECKED 00074 a->v = NULL; 00075 #endif 00076 } 00077 00078 int 00079 array_setsize(struct array *a, unsigned num) 00080 { 00081 void **newptr; 00082 unsigned newmax; 00083 00084 if (num > a->max) { 00085 /* Don't touch A until the allocation succeeds. */ 00086 newmax = a->max; 00087 while (num > newmax) { 00088 newmax = newmax ? newmax*2 : 4; 00089 } 00090 00091 /* 00092 * We don't have krealloc, and it wouldn't be 00093 * worthwhile to implement just for this. So just 00094 * allocate a new block and copy. (Exercise: what 00095 * about this and/or kmalloc makes it not worthwhile?) 00096 */ 00097 00098 newptr = kmalloc(newmax*sizeof(*a->v)); 00099 if (newptr == NULL) { 00100 return ENOMEM; 00101 } 00102 memcpy(newptr, a->v, a->num*sizeof(*a->v)); 00103 kfree(a->v); 00104 a->v = newptr; 00105 a->max = newmax; 00106 } 00107 a->num = num; 00108 00109 return 0; 00110 } 00111 00112 void 00113 array_remove(struct array *a, unsigned index) 00114 { 00115 unsigned num_to_move; 00116 00117 ARRAYASSERT(a->num <= a->max); 00118 ARRAYASSERT(index < a->num); 00119 00120 num_to_move = a->num - (index + 1); 00121 memmove(a->v + index, a->v + index+1, num_to_move*sizeof(void *)); 00122 a->num--; 00123 }
1.7.6.1