blob: aa8d4e084d44337930d58fc63a68851f70af6ed9 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
#include <string.h>
#include "array.h"
/* Invariant: There are always >= next_pot(n_elements) elements
* allocated for data.
*/
struct array_t
{
size_t element_size;
size_t n_elements;
/* uint8_t data[]; */
};
static size_t
next_pot (size_t n)
{
n -= 1;
n |= (n >> 1);
n |= (n >> 2);
n |= (n >> 4);
n |= (n >> 8);
n |= (n >> 16);
if (sizeof (n) > 4)
n |= (n >> 32);
return n + 1;
}
static bool_t
array_reallocate (array_t **array, size_t n_elements)
{
size_t alloc = next_pot (n_elements);
if (alloc != next_pot ((*array)->n_elements))
{
array_t *new_array;
if (!(new_array = realloc (
(*array), sizeof (array_t) + alloc * (*array)->element_size)))
return FALSE;
*array = new_array;
}
(*array)->n_elements = n_elements;
return TRUE;
}
bool_t
array_create (array_t **array, size_t element_size)
{
if (!(*array = malloc (sizeof (array_t))))
return FALSE;
(*array)->element_size = element_size;
(*array)->n_elements = 0;
return TRUE;
}
/* Delete the last n_elements */
void
array_delete_tail (array_t **array, size_t n_delete)
{
array_reallocate (array, (*array)->n_elements - n_delete);
}
void
array_free (array_t **array)
{
free (*array);
*array = NULL;
}
void *
array_get_data (array_t **array, size_t *n_elements)
{
if (n_elements)
*n_elements = (*array)->n_elements;
return (*array) + 1;
}
bool_t
array_append (array_t **array, size_t n_elements, void *tail)
{
size_t old_n_elements = (*array)->n_elements;
size_t tail_offset = old_n_elements * (*array)->element_size;
if (!array_reallocate (array, old_n_elements + n_elements))
return FALSE;
if (tail)
*(void **)tail = ((uint8_t *)((*array) + 1)) + tail_offset;
return TRUE;
}
|