bag tree finished.. updated code to new bags
[wmaker-crm.git] / WINGs / bagarray.c
blob1e66ff1818f86c0b4e354f532e0689926ea620c1
5 #include <stdlib.h>
6 #include <string.h>
8 #include "WUtil.h"
10 #if 0
12 typedef struct W_ArrayBag {
13 void **items;
14 int size;
15 int count;
17 int base;
18 int first;
19 int last;
20 } W_ArrayBag;
23 static int getItemCount(WMBag *bag);
24 static int appendBag(WMBag *bag, WMBag *appendedBag);
25 static int putInBag(WMBag *bag, void *item);
26 static int insertInBag(WMBag *bag, int index, void *item);
27 static int removeFromBag(WMBag *bag, void *item);
28 static int deleteFromBag(WMBag *bag, int index);
29 static void* getFromBag(WMBag *bag, int index);
30 static int firstInBag(WMBag *bag, void *item);
31 static int countInBag(WMBag *bag, void *item);
32 static void* replaceInBag(WMBag *bag, int index, void *item);
33 static int sortBag(WMBag *bag, int (*comparer)(const void*, const void*));
34 static void emptyBag(WMBag *bag);
35 static void freeBag(WMBag *bag);
36 static void mapBag(WMBag *bag, void (*function)(void*, void*), void *data);
37 static int findInBag(WMBag *bag, int (*match)(void*));
38 static void* first(WMBag *bag, void **ptr);
39 static void* last(WMBag *bag, void **ptr);
40 static void* next(WMBag *bag, void **ptr);
41 static void* previous(WMBag *bag, void **ptr);
42 static void* iteratorAtIndex(WMBag *bag, int index, WMBagIterator *ptr);
43 static int indexForIterator(WMBag *bag, WMBagIterator ptr);
46 static W_BagFunctions arrayFunctions = {
47 getItemCount,
48 appendBag,
49 putInBag,
50 insertInBag,
51 removeFromBag,
52 deleteFromBag,
53 deleteFromBag,
54 getFromBag,
55 firstInBag,
56 countInBag,
57 replaceInBag,
58 sortBag,
59 emptyBag,
60 freeBag,
61 mapBag,
62 findInBag,
63 first,
64 last,
65 next,
66 previous,
67 iteratorAtIndex,
68 indexForIterator
72 #define ARRAY ((W_ArrayBag*)bag->data)
75 #define I2O(a, i) ((a)->base + i)
78 WMBag*
79 WMCreateArrayBagWithDestructor(int initialSize, void (*destructor)(void*))
81 WMBag *bag;
82 W_ArrayBag *array;
83 int size;
85 assert(0&&"array bag is not working");
86 bag = wmalloc(sizeof(WMBag));
88 array = wmalloc(sizeof(W_ArrayBag));
90 bag->data = array;
92 array->items = wmalloc(sizeof(void*) * size);
93 array->size = size;
94 array->count = 0;
95 array->first = 0;
96 array->last = 0;
97 array->base = 0;
99 bag->func = arrayFunctions;
101 bag->destructor = destructor;
103 return bag;
107 WMBag*
108 WMCreateArrayBag(int initialSize)
110 return WMCreateArrayBagWithDestructor(initialSize, NULL);
114 static int
115 getItemCount(WMBag *bag)
117 return ARRAY->count;
121 static int
122 appendBag(WMBag *bag, WMBag *appendedBag)
124 W_ArrayBag *array = (W_ArrayBag*)appendedBag->data;
125 int ok;
126 int i;
128 for (i = array->first; i <= array->last; i++) {
129 if (array->items[array->base+i]) {
130 ok = putInBag(bag, array->items[array->base+i]);
131 if (!ok)
132 return 0;
136 return 1;
141 static int
142 putInBag(WMBag *bag, void *item)
144 return insertInBag(bag, ARRAY->last+1, item);
149 static int
150 insertInBag(WMBag *bag, int index, void *item)
152 W_ArrayBag *array = ARRAY;
154 if (I2O(array, index) >= array->size) {
155 array->size = WMAX(array->size + 16, I2O(array, index));
156 array->items = wrealloc(array->items, sizeof(void*) * array->size);
157 memset(array->items + I2O(array, array->last), 0,
158 sizeof(void*) * (array->size - I2O(array, array->last)));
161 if (index > array->last) {
162 array->last = index;
163 } else if (index >= array->first) {
164 memmove(array->items + I2O(array, index),
165 array->items + (I2O(array, index) + 1), sizeof(void*));
166 array->last++;
167 } else {
168 memmove(array->items,
169 array->items + (abs(index) - array->base),
170 sizeof(void*) * (abs(index) - array->base));
171 memset(array->items, 0, sizeof(void*) * (abs(index) - array->base));
172 array->first = index;
173 array->base = abs(index);
176 array->items[array->base + index] = item;
177 array->count++;
179 return 1;
183 static int
184 removeFromBag(WMBag *bag, void *item)
186 int i;
187 W_ArrayBag *array = ARRAY;
189 for (i = 0; i < array->count; i++) {
190 if (array->items[i] == item) {
191 if (bag->destructor)
192 bag->destructor(array->items[i]);
194 memmove(&array->items[i], &array->items[i + 1],
195 (array->count - i - 1) * sizeof(void*));
196 array->count--;
198 return 1;
202 return 0;
207 static int
208 deleteFromBag(WMBag *bag, int index)
210 W_ArrayBag *array = ARRAY;
212 if (index < 0 || index >= array->count)
213 return 0;
215 if (index < array->count-1) {
216 if (bag->destructor)
217 bag->destructor(array->items[index]);
219 memmove(&array->items[index], &array->items[index + 1],
220 (array->count - index - 1) * sizeof(void*));
222 array->count--;
224 return 1;
228 static void*
229 getFromBag(WMBag *bag, int index)
231 if (index < 0 || index >= ARRAY->count)
232 return NULL;
234 return ARRAY->items[index];
239 static int
240 firstInBag(WMBag *bag, void *item)
242 int j;
243 int count = ARRAY->count;
244 W_ArrayBag *array = ARRAY;
246 for (j = 0; j < count; j++) {
247 if (array->items[j] == item)
248 return j;
250 return -1;
256 static int
257 countInBag(WMBag *bag, void *item)
259 int i, j;
260 int count = ARRAY->count;
261 W_ArrayBag *array = ARRAY;
263 for (j = 0, i = 0; j < count; j++) {
264 if (array->items[j] == item)
265 i++;
267 return i;
271 static void*
272 replaceInBag(WMBag *bag, int index, void *item)
274 void *old;
276 if (index < 0 || index >= ARRAY->count)
277 return NULL;
279 old = ARRAY->items[index];
281 ARRAY->items[index] = item;
283 return old;
287 static int
288 sortBag(WMBag *bag, int (*comparer)(const void*, const void*))
290 qsort(ARRAY->items, ARRAY->count, sizeof(void*), comparer);
291 return 1;
296 static void
297 emptyBag(WMBag *bag)
299 W_ArrayBag *array = ARRAY;
301 if (bag->destructor) {
302 while (--array->count) {
303 bag->destructor(array->items[array->count]);
306 ARRAY->count=0;
310 static void
311 freeBag(WMBag *bag)
313 emptyBag(bag);
315 wfree(ARRAY->items);
316 wfree(ARRAY);
317 wfree(bag);
321 static void
322 mapBag(WMBag *bag, void (*function)(void *, void *), void *clientData)
324 int i;
326 for (i = 0; i < ARRAY->last; i++) {
327 if (ARRAY->items[i])
328 (*function)(ARRAY->items[i], clientData);
333 static int
334 findInBag(WMBag *bag, int (*match)(void*))
336 int i;
338 for (i = 0; i < ARRAY->last; i++) {
339 if ((*match)(ARRAY->items[i]))
340 return i;
343 return -1;
347 static void*
348 first(WMBag *bag, void **ptr)
350 *ptr = NULL;
352 if (ARRAY->count == 0)
353 return NULL;
355 *(int**)ptr = 0;
356 return ARRAY->items[0];
360 static void*
361 last(WMBag *bag, void **ptr)
363 *ptr = NULL;
365 if (ARRAY->count == 0)
366 return NULL;
368 *(int*)ptr = ARRAY->count-1;
370 return ARRAY->items[ARRAY->count-1];
374 static void*
375 next(WMBag *bag, void **ptr)
377 if (!*ptr)
378 return NULL;
380 (*(int*)ptr)++;
381 if (*(int*)ptr >= ARRAY->count) {
382 *ptr = NULL;
383 return NULL;
386 return ARRAY->items[*(int*)ptr];
390 static void*
391 previous(WMBag *bag, void **ptr)
393 if (!*ptr)
394 return NULL;
396 (*(int*)ptr)--;
397 if (*(int*)ptr < 0) {
398 *ptr = NULL;
399 return NULL;
402 return ARRAY->items[*(int*)ptr];
407 static void*
408 iteratorAtIndex(WMBag *bag, int index, WMBagIterator *ptr)
413 static int
414 indexForIterator(WMBag *bag, WMBagIterator ptr)
419 #endif