Mercurial > code
annotate array.c @ 6:25cc379de564
Added array.c and array.h:
Various function to manipulate dynamic array. This let you adding as
much as you want object into the array. You may add object to the head,
end or at a specified index.
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 06 Sep 2011 22:19:18 +0200 |
parents | |
children | e8829146ebc7 |
rev | line source |
---|---|
6
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
1 /* |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
2 * array.h -- manipulate dymanic array |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
3 * |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
4 * Copyright (c) 2011, David Demelier <markand@malikania.fr> |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
5 * |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
6 * Permission to use, copy, modify, and/or distribute this software for any |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
7 * purpose with or without fee is hereby granted, provided that the above |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
8 * copyright notice and this permission notice appear in all copies. |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
9 * |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
17 */ |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
18 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
19 #include <stdio.h> |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
20 #include <stdlib.h> |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
21 #include <string.h> |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
22 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
23 #include "array.h" |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
24 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
25 #define SIZE(x) (sizeof (void *) * (x)) |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
26 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
27 static int array_grow(struct array *); |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
28 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
29 struct array * |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
30 array_new(const void *data, size_t bsize, int flags) |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
31 { |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
32 struct array *arr; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
33 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
34 if (!(arr = malloc(sizeof (struct array)))) |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
35 return NULL; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
36 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
37 memset(arr, 0, sizeof (struct array)); |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
38 arr->bsize = (bsize == 0) ? ARRAY_DEFAULT_BSIZE : bsize; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
39 arr->size = bsize + 1; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
40 arr->flags = flags; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
41 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
42 if (!(arr->data = calloc(bsize + 1, sizeof (void *)))) { |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
43 free(arr); |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
44 return NULL; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
45 } |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
46 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
47 if (data) |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
48 arr->data[arr->length++] = (void *) data; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
49 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
50 return arr; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
51 } |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
52 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
53 /* |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
54 * Add to the head of array. NOTE: this may be very slow when adding a lot |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
55 * of object (about 100000). If you need to add a lot of data please consider |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
56 * using linked list instead or use array_append and then use reverse foreach |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
57 * functions. |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
58 */ |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
59 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
60 int |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
61 array_push(struct array *arr, const void *data) |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
62 { |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
63 if (array_grow(arr) < 0) |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
64 return -1; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
65 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
66 memmove(arr->data + 1, arr->data, SIZE(arr->length++)); |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
67 arr->data[0] = (void *) data; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
68 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
69 return 0; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
70 } |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
71 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
72 /* |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
73 * Insert the data to the specified index. The function returns -1 on |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
74 * allocation failure if the array need to grow or when the index is out |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
75 * of bounds otherwise 0 is returned. |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
76 */ |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
77 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
78 int |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
79 array_insert(struct array *arr, const void *data, int index) |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
80 { |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
81 if (index > arr->length - 1 || index < 0 || array_grow(arr) < 0) |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
82 return -1; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
83 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
84 memmove(arr->data + index + 1, arr->data + index, |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
85 SIZE(arr->length++ - index)); |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
86 arr->data[index] = (void *) data; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
87 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
88 return 0; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
89 } |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
90 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
91 /* |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
92 * Append the data to the end of array. |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
93 */ |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
94 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
95 int |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
96 array_append(struct array *arr, const void *data) |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
97 { |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
98 if (array_grow(arr) < 0) |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
99 return -1; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
100 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
101 arr->data[arr->length++] = (void *) data; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
102 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
103 return 0; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
104 } |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
105 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
106 /* |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
107 * Remove the array's head and return the object or NULL if |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
108 * the array is empty. |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
109 */ |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
110 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
111 void * |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
112 array_pop(struct array *arr) |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
113 { |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
114 void *data; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
115 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
116 if (arr->length == 0) |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
117 return NULL; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
118 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
119 data = arr->data[0]; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
120 memmove(arr->data, arr->data + 1, SIZE(arr->length)); |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
121 arr->data[--arr->length] = NULL; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
122 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
123 return data; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
124 } |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
125 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
126 /* |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
127 * Remove the array's queue and return the object or NULL |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
128 * if the array is empty. |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
129 */ |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
130 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
131 void * |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
132 array_unqueue(struct array *arr) |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
133 { |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
134 void *data; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
135 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
136 if (arr->length == 0) |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
137 return NULL; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
138 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
139 data = arr->data[--arr->length]; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
140 arr->data[arr->length] = NULL; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
141 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
142 return data; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
143 } |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
144 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
145 /* |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
146 * Remove the entry at the specified index and return it. If the index is out of |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
147 * bounds or the list is empty the functions returns NULL. |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
148 */ |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
149 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
150 void * |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
151 array_remove(struct array *arr, int index) |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
152 { |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
153 void *data; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
154 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
155 if (arr->length == 0 || index < 0 || index > arr->length - 1) |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
156 return NULL; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
157 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
158 data = arr->data[index]; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
159 memmove(arr->data + index, arr->data + index + 1, |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
160 SIZE(arr->length - index)); |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
161 arr->data[--arr->length] = NULL; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
162 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
163 return data; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
164 } |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
165 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
166 /* |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
167 * Apply the function `fn' on each object and give the optional `udata' |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
168 * argument to the function too. |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
169 */ |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
170 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
171 void |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
172 array_map(struct array *arr, void (*fn)(void *, void *), void *udata) |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
173 { |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
174 size_t i; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
175 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
176 for (i = 0; arr->data[i]; ++i) |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
177 fn(arr->data[i], udata); |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
178 } |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
179 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
180 /* |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
181 * Compare each object with the user supplied function. If the `fn' function |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
182 * returns 1 then the data is returned. Optional idx argument can be set to |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
183 * indicate the data position. If the data was not found the function returns |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
184 * NULL. |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
185 */ |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
186 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
187 void * |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
188 array_find(struct array *arr, int (*fn)(void *, void *), void *udata, int *idx) |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
189 { |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
190 size_t i; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
191 int st; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
192 void *data; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
193 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
194 for (i = st = 0; arr->data[i] && !st; ++i) |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
195 st = fn(arr->data[i], udata); |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
196 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
197 if (st) { |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
198 data = arr->data[--i]; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
199 if (idx) |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
200 *idx = i; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
201 } else |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
202 data = NULL; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
203 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
204 return data; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
205 } |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
206 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
207 /* |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
208 * Reset the array, if the trash argument is set it will free the object |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
209 * too, otherwise the array is just truncated to 0 length. |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
210 */ |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
211 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
212 void |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
213 array_clear(struct array *arr, int trashit) |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
214 { |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
215 if (trashit) { |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
216 size_t i; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
217 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
218 for (i = 0; arr->data[i]; ++i) |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
219 free(arr->data[i]); |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
220 } |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
221 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
222 memset(arr->data, 0, SIZE(arr->size)); |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
223 arr->length = 0; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
224 } |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
225 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
226 /* |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
227 * Same as array_clear except it also free the array object. |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
228 */ |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
229 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
230 void |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
231 array_free(struct array *arr, int trashit) |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
232 { |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
233 array_clear(arr, trashit); |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
234 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
235 free(arr->data); |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
236 free(arr); |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
237 } |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
238 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
239 /* |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
240 * Increate the array storage when it is full. If the buffer is fixed size |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
241 * it returns -1 on full buffer otherwise 0 is returned if allocation |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
242 * succeeded. |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
243 */ |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
244 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
245 static int |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
246 array_grow(struct array *arr) |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
247 { |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
248 if (arr->size - 1 > arr->length) |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
249 return 0; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
250 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
251 if (arr->flags & ARRAY_AUTO) { |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
252 if (!(arr->data = realloc(arr->data, SIZE(arr->size + arr->bsize)))) |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
253 return -1; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
254 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
255 arr->size += arr->bsize; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
256 } else |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
257 return (arr->size - 1 == arr->length) ? -1 : 0; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
258 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
259 memset(arr->data + arr->length, 0, SIZE(arr->size - arr->length)); |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
260 |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
261 return 0; |
25cc379de564
Added array.c and array.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
262 } |