share/array: implement array_sort
[neverball] / share / array.c
1 #include <stdlib.h>
2 #include <assert.h>
3
4 #include "array.h"
5 #include "common.h"
6
7 struct array
8 {
9     unsigned char *data;
10
11     int elem_num;
12     int elem_len;
13     int data_len;
14 };
15
16 Array array_new(int elem_len)
17 {
18     Array a;
19
20     assert(elem_len > 0);
21
22     if ((a = malloc(sizeof (*a))))
23     {
24         a->data = malloc(elem_len);
25
26         a->elem_num = 0;
27         a->elem_len = elem_len;
28         a->data_len = elem_len;
29     }
30
31     return a;
32 }
33
34 void array_free(Array a)
35 {
36     assert(a);
37
38     free(a->data);
39     free(a);
40 }
41
42 void *array_add(Array a)
43 {
44     assert(a);
45
46     if ((a->elem_num + 1) * a->elem_len > a->data_len)
47         a->data = realloc(a->data, (a->data_len *= 2));
48
49     return &a->data[a->elem_num++ * a->elem_len];
50 }
51
52 void array_del(Array a)
53 {
54     assert(a);
55     assert(a->elem_num > 0);
56
57     if (a->elem_num-- * a->elem_len < a->data_len / 4)
58         a->data = realloc(a->data, (a->data_len /= 4));
59 }
60
61 void *array_get(Array a, int i)
62 {
63     assert(a);
64     assert(i >= 0 && i < a->elem_num);
65
66     return &a->data[i * a->elem_len];
67 }
68
69 void *array_rnd(Array a)
70 {
71     assert(a);
72
73     return a->elem_num ? array_get(a, rand_between(0, a->elem_num - 1)) : NULL;
74 }
75
76 int array_len(Array a)
77 {
78     assert(a);
79
80     return a->elem_num;
81 }
82
83 void array_sort(Array a, int (*cmp)(const void *, const void *))
84 {
85     assert(a);
86
87     qsort(a->data, a->elem_num, a->elem_len, cmp);
88 }