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