]> jfr.im git - irc/quakenet/newserv.git/blame - lib/array.c
merge
[irc/quakenet/newserv.git] / lib / array.c
CommitLineData
c86edd1d 1/*
8bf8b2a2
CP
2 unencumbered array.c
3 dynamic UNORDERED array (yes this got me...)
061b68ab 4
8bf8b2a2
CP
5 will grow by allocchunksize (by default 100) when full and
6 new space is requested.
7
8 will shrink by freechunksize (by default 150) if that many
9 items are not occupied at the end.
10
11 clean written from the function prototypes.
c86edd1d
Q
12*/
13
14#include <stdio.h>
15#include <stdlib.h>
8bf8b2a2 16#include <string.h>
c86edd1d
Q
17#include "../core/error.h"
18
8bf8b2a2
CP
19#include "array.h"
20
21void array_init(array *a, unsigned int itemsize) {
22 a->content = NULL;
23 a->cursi = 0; /* count */
c86edd1d 24
8bf8b2a2
CP
25 a->itemsize = itemsize;
26 a->capacity = 0;
27
28 /* allochunksize MUST be <= freechunksize */
29 a->allocchunksize = 100;
30 a->freechunksize = 150;
c86edd1d
Q
31}
32
8bf8b2a2
CP
33/* should be called free_and_reinit really */
34void array_free(array *a) {
35 free(a->content);
36
37 array_init(a, a->itemsize);
c86edd1d
Q
38}
39
40int array_getfreeslot(array *a) {
8bf8b2a2
CP
41 if(a->cursi + 1 >= a->capacity) {
42 a->capacity += a->allocchunksize;
43
44 /* we can be evil and use the same pointer as we're gonna exit if we fail */
45 a->content = realloc(a->content, a->capacity * a->itemsize);
46
9264d86b 47 if(!a->content)
48 Error("array", ERR_STOP, "Array resize failed.");
c86edd1d 49 }
8bf8b2a2
CP
50
51 return a->cursi++;
c86edd1d
Q
52}
53
8bf8b2a2
CP
54void array_delslot(array *a, unsigned int index) {
55 /* if we're not deleting the end item then swap the last item into the deleted items space */
56 /* unordered so we can do this, and we can also use memcpy */
57 if(--a->cursi != index)
58 memcpy((char *)a->content + index * a->itemsize, (char *)a->content + a->cursi * a->itemsize, a->itemsize);
59
60 if(a->cursi + a->freechunksize < a->capacity) {
61
62 a->capacity = a->cursi + a->allocchunksize;
63
64 if(a->capacity == 0) {
65 free(a->content);
66
67 a->content = NULL;
68 } else {
69 void *newp = realloc(a->content, a->capacity * a->itemsize);
70
71 if(!newp) {
72 Error("array", ERR_WARNING, "Unable to shrink array!");
73 } else {
74 a->content = newp;
75 }
c86edd1d
Q
76 }
77 }
78}
79