os161-1.99
 All Data Structures
array.c
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 }
 All Data Structures