byte_array.c
Raw
1#include <cutils/byte_array.h>
2
3Bytearray* new_bytearray_ext(size_t capacity, size_t element_size, char* array_storage, Bytearray* struct_storage, short flags)
4{
5 Bytearray* bytearray;
6
7 if(struct_storage)
8 {
9 bytearray = struct_storage;
10 } else {
11 bytearray = malloc(sizeof(*bytearray));
12 if(!bytearray)
13 return NULL;
14 }
15
16 if(array_storage)
17 {
18 bytearray->items = array_storage;
19 } else {
20 bytearray->items = malloc(sizeof(*bytearray->items)*capacity*element_size);
21 if(!bytearray->items)
22 {
23 free(bytearray);
24 return NULL;
25 }
26 }
27 bytearray->length = 0;
28 bytearray->capacity = capacity;
29 bytearray->element_size = element_size;
30 bytearray->flags = flags;
31
32 return bytearray;
33}
34
35void delete_bytearray(Bytearray* bytearray)
36{
37 delete_bytearray_ext(bytearray,
38 (bytearray->flags & BT_FREE_EL) ? free : NULL,
39 (bytearray->flags & BT_FREE_ARRAY) ? free : NULL,
40 (bytearray->flags & BT_FREE_STRUCT) ? free : NULL);
41}
42
43
44void delete_bytearray_ext(Bytearray* bytearray, void(*rmv_el) (void*), void(*rmv_items) (void*), void(*rmv_struct) (void*))
45{
46 if(rmv_el)
47 {
48 size_t i;
49 for(i = 0; i < bytearray->length; i++)
50 {
51 rmv_el(&bytearray->items[i*bytearray->element_size]);
52 }
53 }
54 if(rmv_items)
55 rmv_items(bytearray->items);
56 if(rmv_struct)
57 rmv_struct(bytearray);
58}
59
60void* bytearray_at(const Bytearray* bytearray, size_t index)
61{
62 if(index >= bytearray->length)
63 return NULL;
64 else
65 return bytearray->items+(index*bytearray->element_size);
66}
67
68void* bytearray_pop_at(Bytearray* bytearray, size_t index)
69{
70 void *tmp, *ret;
71
72 tmp = bytearray_at(bytearray, index);
73 if(!tmp)
74 {
75 errno = 0;
76 return NULL;
77 }
78
79 ret = malloc(bytearray->element_size);
80 if(!ret)
81 {
82 errno = ENOMEM;
83 return NULL;
84 }
85
86 memcpy(ret, tmp, bytearray->element_size);
87 bytearray_remove(bytearray, index, NULL);
88 return ret;
89}
90
91bool_t bytearray_insert(Bytearray* bytearray, size_t index, const void* item)
92{
93 size_t length = bytearray->length;
94 size_t size = bytearray->element_size;
95
96 if(index > length || !bytearray_adjust_size(bytearray, length+1))
97 return b_false;
98
99 memmove(bytearray->items+index*size+1*size, bytearray->items+index*size, (length*size-index*size)*sizeof(*bytearray->items));
100 memcpy(bytearray->items+index*size, item, bytearray->element_size);
101 ++bytearray->length;
102 return b_true;
103}
104
105void bytearray_remove(Bytearray* bytearray, size_t index, void (*rmv)(void*))
106{
107 if(index < bytearray->length)
108 {
109 size_t length = bytearray->length;
110 size_t elsize = bytearray->element_size;
111 if(rmv)
112 rmv(&bytearray->items[index*elsize]);
113
114 memmove(bytearray->items+index*elsize, bytearray->items+index*elsize+1*elsize, (length*elsize-index*elsize-1*elsize)*sizeof(*bytearray->items));
115 --bytearray->length;
116 }
117}
118
119bool_t bytearray_adjust_size(Bytearray* bytearray, size_t size)
120{
121 if(bytearray->flags & BT_FIXED)
122 {
123 if(bytearray->capacity < size)
124 return b_false;
125 else
126 return b_true;
127 }
128
129 while(bytearray->capacity < size)
130 {
131 size_t capacity = bytearray->capacity;
132 size_t elsize = bytearray->element_size;
133 char* tmp = bytearray->items;
134 bytearray->items = realloc(bytearray->items, capacity*elsize*2*sizeof(*bytearray->items));
135 if(!bytearray->items)
136 {
137 bytearray->items = tmp;
138 return b_false;
139 }
140 bytearray->capacity *= 2;
141 }
142 return b_true;
143}
144
145bool_t bytearray_shrink(Bytearray* bytearray)
146{
147 if(bytearray->flags & BT_FIXED)
148 return b_false;
149
150 while(bytearray->capacity > bytearray->length*2)
151 {
152 size_t capacity = bytearray->capacity;
153 size_t size = bytearray->element_size;
154 char* tmp = bytearray->items;
155 bytearray->items = realloc(bytearray->items, (capacity*size)/(2*sizeof(*bytearray->items)));
156 if(!bytearray->items)
157 {
158 bytearray->items = tmp;
159 return b_false;
160 }
161 bytearray->capacity /= 2;
162 }
163 return b_true;
164}
165
166size_t* bytearray_find(const Bytearray* haystack, const void* needle, int (*cmp)(const void*, const void*))
167{
168 size_t* ret;
169 size_t i;
170
171 for(i = 0; i < haystack->length; i++)
172 {
173 if(cmp(haystack->items+(i*haystack->element_size),needle) == 0)
174 {
175 ret = malloc(sizeof(*ret));
176 *ret = i;
177 return ret;
178 }
179 }
180 return NULL;
181}
182