1 /**
2 * Dynamic Array
3 *
4 * Copyright (C) 2006-2014 by
5 * Jeffrey Fulmer - <jeff@joedog.org>, et al.
6 * This file is distributed as part of Siege
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 *--
22 */
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <limits.h>
27 #include <array.h>
28 #include <memory.h>
29 #include <setup.h>
30
31 typedef void *array;
32
33 struct ARRAY_T
34 {
35 int index;
36 int length;
37 array * data;
38 method free;
39 };
40
41 size_t ARRAYSIZE = sizeof(struct ARRAY_T);
42
43 ARRAY
new_array()44 new_array()
45 {
46 ARRAY this;
47
48 this = xcalloc(sizeof(struct ARRAY_T), 1);
49 this->index = -1;
50 this->length = 0;
51 this->free = NULL;
52 return this;
53 }
54
55 ARRAY
array_destroy(ARRAY this)56 array_destroy(ARRAY this)
57 {
58 int i;
59
60 if (this == NULL) return NULL;
61
62 if (this->free == NULL) {
63 this->free = free;
64 }
65
66 for (i = 0; i < this->length; i++) {
67 this->free(this->data[i]);
68 }
69 xfree(this->data);
70 xfree(this);
71 this = NULL;
72 return this;
73 }
74
75 ARRAY
array_destroyer(ARRAY this,method m)76 array_destroyer(ARRAY this, method m)
77 {
78 this->free = m;
79 return array_destroy(this);
80 }
81
82 void
array_set_destroyer(ARRAY this,method m)83 array_set_destroyer(ARRAY this, method m)
84 {
85 this->free = m;
86 }
87
88
89 void
array_push(ARRAY this,void * thing)90 array_push(ARRAY this, void *thing)
91 {
92 int len = 0;
93
94 if (thing==NULL) return;
95
96 len = strlen(thing)+1;
97 array_npush(this, (void*)thing, len);
98 return;
99 }
100
101 void
array_npush(ARRAY this,void * thing,size_t len)102 array_npush(ARRAY this, void *thing, size_t len)
103 {
104 array arr;
105 if (thing==NULL) return;
106 if (this->data == NULL && this->length == 0) {
107 this->data = xmalloc(sizeof(array));
108 } else {
109 this->data = realloc(this->data,(this->length+1)*sizeof(array));
110 }
111 arr = xmalloc(len+1);
112 memset(arr, '\0', len+1);
113 memcpy(arr, thing, len);
114 this->data[this->length] = arr;
115 this->length += 1;
116 return;
117 }
118
119 void *
array_get(ARRAY this,int index)120 array_get(ARRAY this, int index)
121 {
122 if (index > this->length) return NULL;
123
124 return this->data[index];
125 }
126
127 void *
array_remove(ARRAY this,int index)128 array_remove (ARRAY this, int index) {
129 int length = 0;
130 array arr;
131
132 if (index > this->length) return NULL;
133
134 arr = this->data[index];
135 length = --this->length;
136
137 for (; index < length; index++) {
138 this->data[index] = this->data[index+1];
139 }
140
141 return arr;
142 }
143
144 void *
array_pop(ARRAY this)145 array_pop(ARRAY this)
146 {
147 if (this == NULL) return NULL;
148 return this->length ? this->data[--this->length] : NULL;
149 }
150
151 void *
array_next(ARRAY this)152 array_next(ARRAY this)
153 {
154 this->index++;
155 return this->data[(this->index) % this->length];
156 }
157
158 void *
array_prev(ARRAY this)159 array_prev(ARRAY this)
160 {
161 this->index--;
162 return this->data[((this->index) + (this->length - 1)) % this->length] ;
163 }
164
165 size_t
array_length(ARRAY this)166 array_length(ARRAY this)
167 {
168 return this->length;
169 }
170
171 char *
array_to_string(ARRAY this)172 array_to_string(ARRAY this)
173 {
174 size_t i;
175 int len = 0;
176 char *str;
177
178 if (this->length == 0) return "NULL";
179
180 for (i = 0; i < array_length(this); i++) {
181 len += strlen(array_get(this, i))+3;
182 }
183 str = (char*)malloc(len+1);
184 memset(str, '\0', len+1);
185
186 for (i = 0; i < array_length(this); i++) {
187 strcat(str, "[");
188 strcat(str, array_get(this, i));
189 if (i == array_length(this) - 1) {
190 strcat(str, "]");
191 } else {
192 strcat(str, "],");
193 }
194 }
195 return str;
196 }
197
198 void
array_print(ARRAY this)199 array_print(ARRAY this)
200 {
201 printf("%s\n", array_to_string(this));
202 }
203
204
205 #if 0
206 #include <unistd.h>
207 int
208 main (int argc, char *argv[])
209 {
210 int x;
211 int i;
212 int len;
213 ARRAY A = new_array();
214 void *v;
215 for (i = 0; i < 1000000; i++) {
216 array_push(A, "Zero");
217 array_push(A, "One");
218 array_push(A, "Two");
219 array_push(A, "Three");
220 array_push(A, "Four");
221 array_push(A, "Five");
222 array_push(A, "Six-six-six");
223
224 while ((v = array_pop(A)) != NULL) {
225 printf("popped: %s\n", (char*)v);
226 xfree(v);
227 }
228
229 }
230 A = array_destroy(A);
231 return 0;
232 }
233 #endif
234
235
236