array.c 7.12 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* 
 * Copyright (c) 2012 Christoph Mueller <ruunhb@googlemail.com>
 * 
 * Crystal is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Crystal is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

19

20
21
22
23
24
25
#include "array.h"
#include <assert.h>
#include <string.h>

struct CryArray
{
26
	uint8_t* data;
27
28
29
30
31
	size_t alloc;
	size_t length;
};


32
33


34
struct CryArray*        
35
cry_array_new(size_t init_capacity)
36
{
37
38
	assert(init_capacity != 0);

39
	struct CryArray* array = cry_malloc(struct CryArray);
40
	array->alloc = init_capacity;
41
	array->length = 0;
42
	array->data = cry_calloc(uint8_t, array->alloc);
43
44
45
46
47

	return array;
}


48

49
50
51
52
53
54
55
56
57
58
void                    
cry_array_free(struct CryArray* array)
{
	assert(array != 0);

	cry_free(array->data);
	cry_free(array);
}


59

60
61
62
63
64
65
66
67
68
size_t                  
cry_array_size(struct CryArray* array)
{
	assert(array != 0);

	return array->length;
}


69

70
size_t                  
71
cry_array_capacity(struct CryArray* array)
72
73
74
{
	assert(array != 0);

75
	return array->alloc;
76
77
78
}


79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
size_t                  
cry_array_ensure(struct CryArray* array, size_t min_capacity)
{
	assert(array != 0);

	if(array->alloc < min_capacity) {
		size_t new_capacity = (array->alloc >> 1);
		array->alloc = (new_capacity > min_capacity) ? new_capacity : min_capacity;
		array->data = cry_realloc(uint8_t, array->data, array->alloc);
	}

	return array->alloc;
}


size_t                  
cry_array_trim(struct CryArray* array)
{
	assert(array != 0);

	array->data = cry_realloc(uint8_t, array->data, array->length);
	array->alloc = array->length;

	return array->alloc;
}

105

106
void                    
107
cry_array_append(struct CryArray* array, const_pointer data, size_t size)
108
{
109
	assert(array != 0);
110

111
	cry_array_ensure(array, array->length + size);
112

113
	memcpy(array->data + array->length, data, size);
114

115
	array->length += size;
116
117
118
}


119
return_code
120
cry_array_insert(struct CryArray* array, size_t index, const_pointer data, size_t size)
121
{
122
	assert(array != 0);
123

124
        if(index >= array->length)
125
126
                return CRY_OUT_OF_INDEX_RANGE;

127
	cry_array_ensure(array, array->length + size);
128

129
	memmove(array->data + index + size, array->data + index, array->length - index);
130
	memcpy(array->data + index, data, size);
131

132
	array->length += size;
133
134

	return CRY_OKAY;
135
136
137
}


138
return_code		
139
cry_array_replace(struct CryArray* array, size_t index, const_pointer data, size_t size)
140
141
142
143
144
145
146
147
148
149
{
        assert(array != 0);

        if(index >= array->length && index + size > array->length)
                return CRY_OUT_OF_INDEX_RANGE;

        cry_array_ensure(array, array->length + size);

        memcpy(array->data + index, data, size);
}
150
151
152

return_code
cry_array_remove(struct CryArray* array, size_t index, size_t size)
153
{
154
	assert(array != 0);
155

156
	if(index >= array->length)
157
		return CRY_OUT_OF_INDEX_RANGE;
158

159
	memmove(array->data + index, array->data + index + size, array->length - index - size);
160

161
	array->length -= size;
162

163
	return CRY_OKAY;
164
165
166
}


167

168
169
170
171
172
173
174
175
176
177
void
cry_array_clear(struct CryArray* array)
{
        assert(array != 0);

        array->length = 0;
}



178
179
180
pointer                 
cry_array_get(struct CryArray* array, size_t index)
{
181
	assert(array != 0);
182

183
184
	if(index < array->length)
		return array->data + index;
185

186
187
	return 0;
}
188
189


190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
pointer
cry_array_clone(struct CryArray* array)
{
	assert(array != 0);

	uint8_t* ptr = 0;

	if(array->length > 0) {
		ptr = cry_calloc(uint8_t, array->length);
		memcpy(ptr, array->data, array->length);
	}
	
	return ptr;
}


206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
struct CryPtrArray
{
	pointer* data;
	size_t alloc;
	size_t length;
};


struct CryPtrArray*     
cry_ptr_array_new(size_t init_capacity)
{
	assert(init_capacity != 0);

	struct CryPtrArray* array = cry_malloc(struct CryPtrArray);
	array->alloc = init_capacity;
	array->length = 0;
	array->data = cry_calloc(pointer, array->alloc);
	
	return array;
}


void                    
cry_ptr_array_free(struct CryPtrArray* array)
{
	assert(array != 0);

	cry_free(array->data);
	cry_free(array);
}


size_t                  
cry_ptr_array_size(struct CryPtrArray* array)
{
	assert(array != 0);

	return array->length;
}


size_t                  
cry_ptr_array_capacity(struct CryPtrArray* array)
{
	assert(array != 0);

	return array->alloc;
}


size_t                  
cry_ptr_array_ensure(struct CryPtrArray* array, size_t min_capacity)
{
	assert(array != 0);

	if(array->alloc < min_capacity) {
		size_t new_capacity = (array->alloc >> 1);
		array->alloc = (new_capacity > min_capacity) ? new_capacity : min_capacity;
		array->data = cry_realloc(pointer, array->data, array->alloc);
	}

	return array->alloc;
}


size_t                  
cry_ptr_array_trim(struct CryPtrArray* array)
{
	assert(array != 0);

	array->data = cry_realloc(pointer, array->data, array->length);
	array->alloc = array->length;

	return array->alloc;
}


void                    
cry_ptr_array_append(struct CryPtrArray* array, pointer ptr)
{
	assert(array != 0);

	cry_ptr_array_ensure(array, array->length + 1); 

	*(array->data + array->length) = ptr;

	array->length += 1;
}


return_code             
cry_ptr_array_insert(struct CryPtrArray* array, size_t index, pointer ptr)
{
	assert(array != 0);

301
	if(index >= array->length)
302
303
304
305
306
307
308
309
310
311
312
313
314
315
		return CRY_OUT_OF_INDEX_RANGE;

	cry_ptr_array_ensure(array, array->length + 1); 

	memmove(array->data + index + 1, array->data + index, (array->length - index) * sizeof(pointer));

	*(array->data + index) = ptr;

	array->length += 1;

	return CRY_OKAY;
}


316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
pointer			
cry_ptr_array_replace(struct CryPtrArray* array, size_t index, pointer ptr)
{
        assert(array != 0);

        if(index >= array->length)
                return 0;

        pointer data = *(array->data + index);

        *(array->data + index) = ptr;

        return data;
}

331
332
333
334
335
pointer                
cry_ptr_array_remove(struct CryPtrArray* array, size_t index)
{
	assert(array != 0);

336
	if(index >= array->length)
337
338
		return 0;

339
	pointer data = *(array->data + index);
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359

	memmove(array->data + index, array->data + index + 1, (array->length - index - 1) * sizeof(pointer));

	array->length -= 1;

	return data;
}


pointer                 
cry_ptr_array_get(struct CryPtrArray* array, size_t index)
{
	assert(array != 0);

	if(index < array->length)
		return *(array->data + index);

	return 0;
}

360
361
362
363
364
365
366
367
368
369
370
371
372
void			
cry_ptr_array_clear(struct CryPtrArray* array, cry_free_funptr fun)
{
        assert(array != 0);

        if(fun != 0) {
                size_t index = 0;
                for(index = 0; index < array->length; ++index)
                        fun(*(array->data + index));
        }

        array->length = 0;
}
373
374


375
376
377
378
379
380
381
382
383
384
385
void 
cry_ptr_array_each(struct CryPtrArray* array, cry_foreach_funptr fun, pointer data)
{
        assert(array != 0 && fun != 0);

        size_t index = 0;

        for(index = 0; index < array->length; ++index) {
                fun(*(array->data + index), data);
        }
}