]>
Commit | Line | Data |
---|---|---|
37bc30c8 ML |
1 | /* |
2 | chronyd/chronyc - Programs for keeping computer clocks accurate. | |
3 | ||
4 | ********************************************************************** | |
5 | * Copyright (C) Miroslav Lichvar 2014 | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of version 2 of the GNU General Public License as | |
9 | * published by the Free Software Foundation. | |
10 | * | |
11 | * This program is distributed in the hope that it will be useful, but | |
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | * General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License along | |
17 | * with this program; if not, write to the Free Software Foundation, Inc., | |
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
19 | * | |
20 | ********************************************************************** | |
21 | ||
22 | ======================================================================= | |
23 | ||
24 | Functions implementing an array with automatic memory allocation. | |
25 | ||
26 | */ | |
27 | ||
28 | #include "config.h" | |
29 | ||
30 | #include "sysincl.h" | |
31 | ||
32 | #include "array.h" | |
33 | #include "memory.h" | |
34 | ||
35 | struct ARR_Instance_Record { | |
36 | void *data; | |
37 | unsigned int elem_size; | |
38 | unsigned int used; | |
39 | unsigned int allocated; | |
40 | }; | |
41 | ||
42 | ARR_Instance | |
43 | ARR_CreateInstance(unsigned int elem_size) | |
44 | { | |
45 | ARR_Instance array; | |
46 | ||
70b108ab ML |
47 | assert(elem_size > 0); |
48 | ||
37bc30c8 ML |
49 | array = MallocNew(struct ARR_Instance_Record); |
50 | ||
51 | array->data = NULL; | |
52 | array->elem_size = elem_size; | |
53 | array->used = 0; | |
54 | array->allocated = 0; | |
55 | ||
56 | return array; | |
57 | } | |
58 | ||
59 | void | |
60 | ARR_DestroyInstance(ARR_Instance array) | |
61 | { | |
62 | Free(array->data); | |
63 | Free(array); | |
64 | } | |
65 | ||
66 | static void | |
67 | realloc_array(ARR_Instance array, unsigned int min_size) | |
68 | { | |
70b108ab | 69 | assert(min_size <= 2 * min_size); |
37bc30c8 ML |
70 | if (array->allocated >= min_size && array->allocated <= 2 * min_size) |
71 | return; | |
72 | ||
73 | if (array->allocated < min_size) { | |
74 | while (array->allocated < min_size) | |
75 | array->allocated = array->allocated ? 2 * array->allocated : 1; | |
76 | } else { | |
77 | array->allocated = min_size; | |
78 | } | |
79 | ||
7ffee735 | 80 | array->data = Realloc2(array->data, array->allocated, array->elem_size); |
37bc30c8 ML |
81 | } |
82 | ||
83 | void * | |
84 | ARR_GetNewElement(ARR_Instance array) | |
85 | { | |
86 | array->used++; | |
87 | realloc_array(array, array->used); | |
88 | return ARR_GetElement(array, array->used - 1); | |
89 | } | |
90 | ||
91 | void * | |
92 | ARR_GetElement(ARR_Instance array, unsigned int index) | |
93 | { | |
94 | assert(index < array->used); | |
70b108ab | 95 | return (void *)((char *)array->data + (size_t)index * array->elem_size); |
37bc30c8 ML |
96 | } |
97 | ||
98 | void * | |
99 | ARR_GetElements(ARR_Instance array) | |
100 | { | |
934df19c ML |
101 | /* Return a non-NULL pointer when the array has zero size */ |
102 | if (!array->data) { | |
103 | assert(!array->used); | |
104 | return array; | |
105 | } | |
106 | ||
37bc30c8 ML |
107 | return array->data; |
108 | } | |
109 | ||
110 | void | |
111 | ARR_AppendElement(ARR_Instance array, void *element) | |
112 | { | |
113 | void *e; | |
114 | ||
115 | e = ARR_GetNewElement(array); | |
116 | memcpy(e, element, array->elem_size); | |
117 | } | |
118 | ||
119 | void | |
120 | ARR_SetSize(ARR_Instance array, unsigned int size) | |
121 | { | |
122 | realloc_array(array, size); | |
123 | array->used = size; | |
124 | } | |
125 | ||
126 | unsigned int | |
127 | ARR_GetSize(ARR_Instance array) | |
128 | { | |
129 | return array->used; | |
130 | } |