annotate array.c @ 65:b2cd1fd33bb0

Remove useless macros
author David Demelier <markand@malikania.fr>
date Wed, 09 Nov 2011 20:12:24 +0100
parents 9cc5d6d0563e
children cff6869fbc94
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
62
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
1 /*
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
2 * array.c -- manipulate dynamic arrays
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
3 *
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
4 * Copyright (c) 2011, David Demelier <markand@malikania.fr>
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
5 *
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
6 * Permission to use, copy, modify, and/or distribute this software for any
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
7 * purpose with or without fee is hereby granted, provided that the above
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
8 * copyright notice and this permission notice appear in all copies.
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
9 *
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
17 */
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
18
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
19 #include <stdio.h>
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
20 #include <stdlib.h>
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
21 #include <string.h>
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
22
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
23 #include "array.h"
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
24
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
25 #define OFFSET(x) (arr->unit * (x))
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
26
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
27 static int array_grow(struct array *);
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
28
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
29 struct array *
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
30 array_new(enum array_type type, size_t unit, int length)
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
31 {
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
32 struct array *arr;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
33
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
34 if (unit == 0 || (arr = malloc(sizeof (struct array))) == NULL)
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
35 return NULL;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
36
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
37 memset(arr, 0, sizeof (struct array));
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
38 arr->type = type;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
39 arr->bsize = (length == 0) ? ARRAY_DEFAULT_BSIZE : length;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
40 arr->unit = unit;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
41 arr->size = OFFSET(arr->bsize);
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
42
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
43 if ((arr->data = malloc(arr->size)) == NULL) {
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
44 free(arr);
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
45 return NULL;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
46 }
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
47
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
48 return arr;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
49 }
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
50
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
51 /*
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
52 * Add to the head of array. NOTE: this may be very slow when adding a lot
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
53 * of object (about 100000). If you need to add a lot of data please consider
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
54 * using linked list instead.
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
55 */
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
56
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
57 int
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
58 array_push(struct array *arr, const void *data)
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
59 {
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
60 if (array_grow(arr) < 0)
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
61 return -1;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
62
64
9cc5d6d0563e Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents: 62
diff changeset
63 memmove((char *)arr->data + arr->unit, arr->data, OFFSET(arr->length++));
9cc5d6d0563e Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents: 62
diff changeset
64 memcpy((char *)arr->data, data, arr->unit);
62
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
65
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
66 return 0;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
67 }
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
68
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
69 /*
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
70 * Insert the data at the specified index. The function returns -1 on
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
71 * allocation failure or when the index is outof bounds otherwise 0 is returned.
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
72 */
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
73
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
74 int
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
75 array_insert(struct array *arr, const void *data, int index)
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
76 {
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
77 if (index > arr->length - 1 || index < 0 || array_grow(arr) < 0)
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
78 return -1;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
79
64
9cc5d6d0563e Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents: 62
diff changeset
80 memmove((char *)arr->data + OFFSET(index + 1),
9cc5d6d0563e Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents: 62
diff changeset
81 (char *)arr->data + OFFSET(index), OFFSET(arr->length++ - index));
9cc5d6d0563e Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents: 62
diff changeset
82 memcpy((char *)arr->data + OFFSET(index), data, arr->unit);
62
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
83
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
84 return 0;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
85 }
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
86
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
87 /*
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
88 * Append the data to the end of array.
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
89 */
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
90
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
91 int
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
92 array_append(struct array *arr, const void *data)
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
93 {
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
94 if (array_grow(arr) < 0)
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
95 return -1;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
96
64
9cc5d6d0563e Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents: 62
diff changeset
97 memcpy((char *)arr->data + OFFSET(arr->length++), data, arr->unit);
62
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
98
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
99 return 0;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
100 }
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
101
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
102 /*
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
103 * Remove the array's head.
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
104 */
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
105
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
106 void
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
107 array_pop(struct array *arr)
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
108 {
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
109 if (arr->length > 0) {
64
9cc5d6d0563e Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents: 62
diff changeset
110 memmove((char *)arr->data, (char *)arr->data + OFFSET(1),
62
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
111 OFFSET(--arr->length));
64
9cc5d6d0563e Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents: 62
diff changeset
112 memset((char *)arr->data + OFFSET(arr->length), 0, arr->unit);
62
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
113 }
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
114 }
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
115
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
116 /*
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
117 * Remove the array's tail.
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
118 */
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
119
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
120 void
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
121 array_unqueue(struct array *arr)
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
122 {
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
123 if (arr->length > 0)
64
9cc5d6d0563e Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents: 62
diff changeset
124 memset((char *)arr->data + OFFSET(--arr->length), 0, arr->unit);
62
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
125 }
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
126
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
127 /*
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
128 * Remove the data at the specified index. Bounds are checked.
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
129 */
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
130
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
131 void
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
132 array_remove(struct array *arr, int index)
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
133 {
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
134 if (arr->length > 0 && index >= 0 && index < arr->length) {
64
9cc5d6d0563e Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents: 62
diff changeset
135 memmove((char *)arr->data + OFFSET(index),
9cc5d6d0563e Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents: 62
diff changeset
136 (char *)arr->data + OFFSET(index + 1),
62
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
137 OFFSET(arr->length - index - 1));
64
9cc5d6d0563e Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents: 62
diff changeset
138 memset((char *)arr->data + OFFSET(--arr->length), 0, arr->unit);
62
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
139 }
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
140 }
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
141
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
142 /*
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
143 * Remove the object referenced by the `data' argument. Useful when you
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
144 * don't know the index.
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
145 */
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
146
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
147 void
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
148 array_unref(struct array *arr, const void *data)
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
149 {
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
150 void *elm;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
151 int i;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
152
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
153 for (i = 0; i < arr->length; ++i) {
64
9cc5d6d0563e Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents: 62
diff changeset
154 elm = (char *)arr->data + OFFSET(i);
62
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
155
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
156 if (memcmp(elm, data, arr->unit) == 0)
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
157 array_remove(arr, i);
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
158 }
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
159 }
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
160
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
161 /*
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
162 * Swap the two elements referenced by index `i1' and `i2'. This function needs
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
163 * to allocate data to swap elements thus if the functions fails it returns -1
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
164 * otherwise 0 is returned.
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
165 */
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
166
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
167 int
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
168 array_iswap(struct array *arr, int i1, int i2)
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
169 {
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
170 void *tmp;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
171
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
172 /* Out of bounds */
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
173 if (i1 >= arr->length || i1 < 0 || i2 >= arr->length || i2 < 0)
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
174 return -1;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
175
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
176 /*
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
177 * Only allocate at this time, the user may do not want to use this
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
178 * function.
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
179 */
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
180
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
181 if ((tmp = malloc(arr->unit)) == NULL)
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
182 return -1;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
183
64
9cc5d6d0563e Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents: 62
diff changeset
184 memcpy((char *)tmp, (char *)arr->data + OFFSET(i1), arr->unit);
9cc5d6d0563e Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents: 62
diff changeset
185 memcpy((char *)arr->data + OFFSET(i1), (char *)arr->data + OFFSET(i2),
62
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
186 arr->unit);
64
9cc5d6d0563e Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents: 62
diff changeset
187 memcpy((char *)arr->data + OFFSET(i2), (char *)tmp, arr->unit);
62
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
188
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
189 /*
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
190 * Clear bytes for safety you probably don't want a password or
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
191 * secure data to be left somewhere in the memory.
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
192 */
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
193
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
194 memset(tmp, 0, arr->unit);
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
195 free(tmp);
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
196
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
197 return 0;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
198 }
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
199
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
200 /*
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
201 * Swap the two elements referenced by data `o1' and `o2'. This function
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
202 * may be slow on large arrays since it must travel all the object
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
203 * to find the indexes.
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
204 */
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
205
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
206 int
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
207 array_pswap(struct array *arr, const void *o1, const void *o2)
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
208 {
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
209 int found, i1, i2;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
210
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
211 for (i1 = found = 0; !found && i1 < arr->length; ++i1)
64
9cc5d6d0563e Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents: 62
diff changeset
212 found = memcmp((char *)arr->data + OFFSET(i1), o1, arr->unit) == 0;
62
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
213
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
214 if (!found)
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
215 return -1;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
216
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
217 for (i2 = found = 0; !found && i2 < arr->length; ++i2)
64
9cc5d6d0563e Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents: 62
diff changeset
218 found = memcmp((char *)arr->data + OFFSET(i2), o2, arr->unit) == 0;
62
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
219
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
220 if (!found)
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
221 return -1;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
222
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
223 return array_iswap(arr, --i1, --i2);
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
224 }
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
225
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
226 /*
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
227 * Apply the function `fn' on each object and give the optional `udata'
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
228 * argument to the function too.
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
229 */
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
230
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
231 void
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
232 array_map(const struct array *arr, void (*fn)(void *, void *), void *udata)
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
233 {
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
234 int i;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
235
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
236 for (i = 0; i < arr->length; ++i)
64
9cc5d6d0563e Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents: 62
diff changeset
237 fn((char *)arr->data + OFFSET(i), udata);
62
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
238 }
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
239
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
240 /*
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
241 * Compare each object with the user supplied function. If the `fn' function
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
242 * returns 1 then the data is returned. Optional idx argument can be set to
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
243 * indicate the data position. If the data was not found the function returns
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
244 * NULL.
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
245 */
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
246
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
247 void *
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
248 array_find(const struct array *arr, int (*fn)(void *, void *), int *ix, void *u)
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
249 {
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
250 int st, i;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
251 void *data;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
252
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
253 for (i = st = 0; i < arr->length && st != 1; ++i)
64
9cc5d6d0563e Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents: 62
diff changeset
254 st = fn((char *)arr->data + OFFSET(i), u);
62
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
255
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
256 if (st) {
64
9cc5d6d0563e Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents: 62
diff changeset
257 data = (char *)arr->data + OFFSET(--i);
62
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
258 if (ix)
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
259 *ix = i;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
260 } else
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
261 data = NULL;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
262
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
263 return data;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
264 }
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
265
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
266 /*
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
267 * Erase every bytes and set the length to 0.
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
268 */
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
269
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
270 void
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
271 array_clear(struct array *arr)
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
272 {
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
273 memset(arr->data, 0, arr->size);
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
274 arr->length = 0;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
275 }
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
276
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
277 /*
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
278 * Same as array_clear except it also free the array object.
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
279 */
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
280
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
281 void
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
282 array_free(struct array *arr)
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
283 {
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
284 array_clear(arr);
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
285
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
286 if (arr->data)
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
287 free(arr->data);
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
288
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
289 free(arr);
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
290 }
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
291
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
292 /*
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
293 * Increate the array storage when it is full. If the buffer is fixed size
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
294 * it returns -1 on full buffer otherwise 0 is returned if allocation
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
295 * succeeded.
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
296 */
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
297
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
298 static int
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
299 array_grow(struct array *arr)
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
300 {
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
301 if ((arr->size / arr->unit) > (size_t) arr->length)
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
302 return 0;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
303
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
304 if (arr->type == ARRAY_AUTO) {
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
305 if ((arr->data = realloc(arr->data, arr->size +
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
306 OFFSET(arr->bsize))) == NULL)
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
307 return -1;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
308
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
309 arr->size += OFFSET(arr->bsize);
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
310 } else
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
311 return -1;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
312
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
313 return 0;
d10ab6bc555d HG self failure
David Demelier <markand@malikania.fr>
parents:
diff changeset
314 }