12 typedef struct 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
= {
72 #define ARRAY ((W_ArrayBag*)bag->data)
75 #define I2O(a, i) ((a)->base + i)
79 WMCreateArrayBagWithDestructor(int initialSize
, void (*destructor
)(void*))
85 assert(0&&"array bag is not working");
86 bag
= wmalloc(sizeof(WMBag
));
88 array
= wmalloc(sizeof(W_ArrayBag
));
92 array
->items
= wmalloc(sizeof(void*) * size
);
99 bag
->func
= arrayFunctions
;
101 bag
->destructor
= destructor
;
108 WMCreateArrayBag(int initialSize
)
110 return WMCreateArrayBagWithDestructor(initialSize
, NULL
);
115 getItemCount(WMBag
*bag
)
122 appendBag(WMBag
*bag
, WMBag
*appendedBag
)
124 W_ArrayBag
*array
= (W_ArrayBag
*)appendedBag
->data
;
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
]);
142 putInBag(WMBag
*bag
, void *item
)
144 return insertInBag(bag
, ARRAY
->last
+1, item
);
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
) {
163 } else if (index
>= array
->first
) {
164 memmove(array
->items
+ I2O(array
, index
),
165 array
->items
+ (I2O(array
, index
) + 1), sizeof(void*));
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
;
184 removeFromBag(WMBag
*bag
, void *item
)
187 W_ArrayBag
*array
= ARRAY
;
189 for (i
= 0; i
< array
->count
; i
++) {
190 if (array
->items
[i
] == item
) {
192 bag
->destructor(array
->items
[i
]);
194 memmove(&array
->items
[i
], &array
->items
[i
+ 1],
195 (array
->count
- i
- 1) * sizeof(void*));
208 deleteFromBag(WMBag
*bag
, int index
)
210 W_ArrayBag
*array
= ARRAY
;
212 if (index
< 0 || index
>= array
->count
)
215 if (index
< array
->count
-1) {
217 bag
->destructor(array
->items
[index
]);
219 memmove(&array
->items
[index
], &array
->items
[index
+ 1],
220 (array
->count
- index
- 1) * sizeof(void*));
229 getFromBag(WMBag
*bag
, int index
)
231 if (index
< 0 || index
>= ARRAY
->count
)
234 return ARRAY
->items
[index
];
240 firstInBag(WMBag
*bag
, void *item
)
243 int count
= ARRAY
->count
;
244 W_ArrayBag
*array
= ARRAY
;
246 for (j
= 0; j
< count
; j
++) {
247 if (array
->items
[j
] == item
)
257 countInBag(WMBag
*bag
, void *item
)
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
)
272 replaceInBag(WMBag
*bag
, int index
, void *item
)
276 if (index
< 0 || index
>= ARRAY
->count
)
279 old
= ARRAY
->items
[index
];
281 ARRAY
->items
[index
] = item
;
288 sortBag(WMBag
*bag
, int (*comparer
)(const void*, const void*))
290 qsort(ARRAY
->items
, ARRAY
->count
, sizeof(void*), comparer
);
299 W_ArrayBag
*array
= ARRAY
;
301 if (bag
->destructor
) {
302 while (--array
->count
) {
303 bag
->destructor(array
->items
[array
->count
]);
322 mapBag(WMBag
*bag
, void (*function
)(void *, void *), void *clientData
)
326 for (i
= 0; i
< ARRAY
->last
; i
++) {
328 (*function
)(ARRAY
->items
[i
], clientData
);
334 findInBag(WMBag
*bag
, int (*match
)(void*))
338 for (i
= 0; i
< ARRAY
->last
; i
++) {
339 if ((*match
)(ARRAY
->items
[i
]))
348 first(WMBag
*bag
, void **ptr
)
352 if (ARRAY
->count
== 0)
356 return ARRAY
->items
[0];
361 last(WMBag
*bag
, void **ptr
)
365 if (ARRAY
->count
== 0)
368 *(int*)ptr
= ARRAY
->count
-1;
370 return ARRAY
->items
[ARRAY
->count
-1];
375 next(WMBag
*bag
, void **ptr
)
381 if (*(int*)ptr
>= ARRAY
->count
) {
386 return ARRAY
->items
[*(int*)ptr
];
391 previous(WMBag
*bag
, void **ptr
)
397 if (*(int*)ptr
< 0) {
402 return ARRAY
->items
[*(int*)ptr
];
408 iteratorAtIndex(WMBag
*bag
, int index
, WMBagIterator
*ptr
)
414 indexForIterator(WMBag
*bag
, WMBagIterator ptr
)