1 /*
2 LICENSE INFORMATION:
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public
5 License as published by the Free Software Foundation; either
6 version 2 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 General Public License for more details.
12
13 You should have received a copy of the GNU General Public
14 License along with this program; if not, write to the Free Software
15 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 Copyright (c) 2002 Bruno T. C. de Oliveira
17
18 INFORMA��ES DE LICEN�A:
19 Este programa � um software de livre distribui��o; voc� pode
20 redistribu�-lo e/ou modific�-lo sob os termos da GNU General
21 Public License, conforme publicado pela Free Software Foundation,
22 pela vers�o 2 da licen�a ou qualquer vers�o posterior.
23
24 Este programa � distribu�do na esperan�a de que ele ser� �til
25 aos seus usu�rios, por�m, SEM QUAISQUER GARANTIAS; sem sequer
26 a garantia impl�cita de COMERCIABILIDADE ou DE ADEQUA��O A
27 QUALQUER FINALIDADE ESPEC�FICA. Consulte a GNU General Public
28 License para obter mais detalhes (uma c�pia acompanha este
29 programa, armazenada no arquivo COPYING).
30 */
31
32
33 #include "darray.h"
34 #include "util.h"
35 #include <stdio.h>
36 #include <stdlib.h>
37
38 #define DEFAULT_CAPACITY 20
39
40 #define CAPACITY_AHEAD 20 /* when a value is assigned to an out of bounds
41 item, this is how far beyond it the capacity
42 grows. */
43
44 struct DArray_ {
45 int len;
46 int cap;
47 void **items;
48 void (*value_destroyer)(void*);
49 };
50
darray_create()51 DArray* darray_create() {
52 return darray_create_ex(DEFAULT_CAPACITY, NULL);
53 }
54
darray_create_ex(int cap,void (* vd)(void *))55 DArray* darray_create_ex(int cap, void (*vd)(void*)) {
56 DArray* da = zalloc(sizeof(DArray));
57
58 da->len = 0;
59 da->cap = (cap > 0) ? cap : DEFAULT_CAPACITY;
60 da->items = zalloc(sizeof(void*) * da->cap);
61 da->value_destroyer = vd;
62
63 return da;
64 }
65
darray_destroy(DArray * da)66 void darray_destroy(DArray* da) {
67 int i;
68 if (!da) return;
69 if (da->value_destroyer) {
70 /* call value destroyer for each item */
71 for (i = 0; i < da->len; i++)
72 if (da->items[i]) (*da->value_destroyer)(da->items[i]);
73 }
74
75 /* free up the items array then the darray itself */
76 sfree(da->items);
77 sfree(da);
78 }
79
darray_len(DArray * da)80 int darray_len(DArray* da) {
81 /* this one is really complicated */
82 return da->len;
83 }
84
darray_get(DArray * da,int i)85 void* darray_get(DArray* da, int i) {
86 return (i >= 0 && i < da->len) ? da->items[i] : NULL;
87 }
88
darray_set(DArray * da,int i,const void * v)89 void darray_set(DArray* da, int i, const void *v) {
90 if (i < 0) {
91 fprintf(stderr, "*** FATAL ERROR ***\n"
92 "Attempt to darray_set with negative index %d\n", i);
93 abort();
94 }
95 else if (i >= da->len) {
96 da->cap = i + CAPACITY_AHEAD;
97 da->items = srealloc(da->items, sizeof(void*) * da->cap);
98
99 /* grow array while assignung NULLs to all newly included items */
100 while (i >= da->len) da->items[da->len++] = NULL;
101 }
102 else {
103 /* call value destroyer if there was anything there */
104 if (da->items[i] && da->value_destroyer)
105 (*da->value_destroyer)(da->items[i]);
106 }
107
108 da->items[i] = (void*) v;
109 }
110
darray_snatch(DArray * da,int i)111 void* darray_snatch(DArray *da, int i) {
112 void *v;
113 if (i >= 0 && i < da->len) {
114 v = da->items[i];
115 da->items[i] = NULL;
116 return v;
117 }
118 else return NULL;
119 }
120
darray_append(DArray * da,const void * v)121 void darray_append(DArray *da, const void *v) {
122 darray_set(da, da->len, v);
123 }
124
darray_remove(DArray * da,int i)125 void darray_remove(DArray *da, int i) {
126 if (i < 0 || i >= da->len) return;
127 if (da->items[i] && da->value_destroyer)
128 (*da->value_destroyer)(da->items[i]);
129
130 while (i < da->len - 1) {
131 da->items[i] = da->items[i+1];
132 i++;
133 }
134
135 da->len--;
136 }
137
138