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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 }