1*ae771770SStanislav Sedov /*
2*ae771770SStanislav Sedov * Copyright (c) 2010 Kungliga Tekniska Högskolan
3*ae771770SStanislav Sedov * (Royal Institute of Technology, Stockholm, Sweden).
4*ae771770SStanislav Sedov * All rights reserved.
5*ae771770SStanislav Sedov *
6*ae771770SStanislav Sedov * Portions Copyright (c) 2010 Apple Inc. All rights reserved.
7*ae771770SStanislav Sedov *
8*ae771770SStanislav Sedov * Redistribution and use in source and binary forms, with or without
9*ae771770SStanislav Sedov * modification, are permitted provided that the following conditions
10*ae771770SStanislav Sedov * are met:
11*ae771770SStanislav Sedov *
12*ae771770SStanislav Sedov * 1. Redistributions of source code must retain the above copyright
13*ae771770SStanislav Sedov * notice, this list of conditions and the following disclaimer.
14*ae771770SStanislav Sedov *
15*ae771770SStanislav Sedov * 2. Redistributions in binary form must reproduce the above copyright
16*ae771770SStanislav Sedov * notice, this list of conditions and the following disclaimer in the
17*ae771770SStanislav Sedov * documentation and/or other materials provided with the distribution.
18*ae771770SStanislav Sedov *
19*ae771770SStanislav Sedov * 3. Neither the name of the Institute nor the names of its contributors
20*ae771770SStanislav Sedov * may be used to endorse or promote products derived from this software
21*ae771770SStanislav Sedov * without specific prior written permission.
22*ae771770SStanislav Sedov *
23*ae771770SStanislav Sedov * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24*ae771770SStanislav Sedov * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25*ae771770SStanislav Sedov * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26*ae771770SStanislav Sedov * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27*ae771770SStanislav Sedov * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28*ae771770SStanislav Sedov * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29*ae771770SStanislav Sedov * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30*ae771770SStanislav Sedov * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31*ae771770SStanislav Sedov * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32*ae771770SStanislav Sedov * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33*ae771770SStanislav Sedov * SUCH DAMAGE.
34*ae771770SStanislav Sedov */
35*ae771770SStanislav Sedov
36*ae771770SStanislav Sedov #include "baselocl.h"
37*ae771770SStanislav Sedov
38*ae771770SStanislav Sedov /*
39*ae771770SStanislav Sedov *
40*ae771770SStanislav Sedov */
41*ae771770SStanislav Sedov
42*ae771770SStanislav Sedov struct heim_array_data {
43*ae771770SStanislav Sedov size_t len;
44*ae771770SStanislav Sedov heim_object_t *val;
45*ae771770SStanislav Sedov };
46*ae771770SStanislav Sedov
47*ae771770SStanislav Sedov static void
array_dealloc(heim_object_t ptr)48*ae771770SStanislav Sedov array_dealloc(heim_object_t ptr)
49*ae771770SStanislav Sedov {
50*ae771770SStanislav Sedov heim_array_t array = ptr;
51*ae771770SStanislav Sedov size_t n;
52*ae771770SStanislav Sedov for (n = 0; n < array->len; n++)
53*ae771770SStanislav Sedov heim_release(array->val[n]);
54*ae771770SStanislav Sedov free(array->val);
55*ae771770SStanislav Sedov }
56*ae771770SStanislav Sedov
57*ae771770SStanislav Sedov struct heim_type_data array_object = {
58*ae771770SStanislav Sedov HEIM_TID_ARRAY,
59*ae771770SStanislav Sedov "dict-object",
60*ae771770SStanislav Sedov NULL,
61*ae771770SStanislav Sedov array_dealloc,
62*ae771770SStanislav Sedov NULL,
63*ae771770SStanislav Sedov NULL,
64*ae771770SStanislav Sedov NULL
65*ae771770SStanislav Sedov };
66*ae771770SStanislav Sedov
67*ae771770SStanislav Sedov /**
68*ae771770SStanislav Sedov * Allocate an array
69*ae771770SStanislav Sedov *
70*ae771770SStanislav Sedov * @return A new allocated array, free with heim_release()
71*ae771770SStanislav Sedov */
72*ae771770SStanislav Sedov
73*ae771770SStanislav Sedov heim_array_t
heim_array_create(void)74*ae771770SStanislav Sedov heim_array_create(void)
75*ae771770SStanislav Sedov {
76*ae771770SStanislav Sedov heim_array_t array;
77*ae771770SStanislav Sedov
78*ae771770SStanislav Sedov array = _heim_alloc_object(&array_object, sizeof(*array));
79*ae771770SStanislav Sedov if (array == NULL)
80*ae771770SStanislav Sedov return NULL;
81*ae771770SStanislav Sedov
82*ae771770SStanislav Sedov array->val = NULL;
83*ae771770SStanislav Sedov array->len = 0;
84*ae771770SStanislav Sedov
85*ae771770SStanislav Sedov return array;
86*ae771770SStanislav Sedov }
87*ae771770SStanislav Sedov
88*ae771770SStanislav Sedov /**
89*ae771770SStanislav Sedov * Get type id of an dict
90*ae771770SStanislav Sedov *
91*ae771770SStanislav Sedov * @return the type id
92*ae771770SStanislav Sedov */
93*ae771770SStanislav Sedov
94*ae771770SStanislav Sedov heim_tid_t
heim_array_get_type_id(void)95*ae771770SStanislav Sedov heim_array_get_type_id(void)
96*ae771770SStanislav Sedov {
97*ae771770SStanislav Sedov return HEIM_TID_ARRAY;
98*ae771770SStanislav Sedov }
99*ae771770SStanislav Sedov
100*ae771770SStanislav Sedov /**
101*ae771770SStanislav Sedov * Append object to array
102*ae771770SStanislav Sedov *
103*ae771770SStanislav Sedov * @param array array to add too
104*ae771770SStanislav Sedov * @param object the object to add
105*ae771770SStanislav Sedov *
106*ae771770SStanislav Sedov * @return zero if added, errno otherwise
107*ae771770SStanislav Sedov */
108*ae771770SStanislav Sedov
109*ae771770SStanislav Sedov int
heim_array_append_value(heim_array_t array,heim_object_t object)110*ae771770SStanislav Sedov heim_array_append_value(heim_array_t array, heim_object_t object)
111*ae771770SStanislav Sedov {
112*ae771770SStanislav Sedov heim_object_t *ptr;
113*ae771770SStanislav Sedov
114*ae771770SStanislav Sedov ptr = realloc(array->val, (array->len + 1) * sizeof(array->val[0]));
115*ae771770SStanislav Sedov if (ptr == NULL)
116*ae771770SStanislav Sedov return ENOMEM;
117*ae771770SStanislav Sedov array->val = ptr;
118*ae771770SStanislav Sedov array->val[array->len++] = heim_retain(object);
119*ae771770SStanislav Sedov
120*ae771770SStanislav Sedov return 0;
121*ae771770SStanislav Sedov }
122*ae771770SStanislav Sedov
123*ae771770SStanislav Sedov /**
124*ae771770SStanislav Sedov * Iterate over all objects in array
125*ae771770SStanislav Sedov *
126*ae771770SStanislav Sedov * @param array array to iterate over
127*ae771770SStanislav Sedov * @param fn function to call on each object
128*ae771770SStanislav Sedov * @param ctx context passed to fn
129*ae771770SStanislav Sedov */
130*ae771770SStanislav Sedov
131*ae771770SStanislav Sedov void
heim_array_iterate_f(heim_array_t array,heim_array_iterator_f_t fn,void * ctx)132*ae771770SStanislav Sedov heim_array_iterate_f(heim_array_t array, heim_array_iterator_f_t fn, void *ctx)
133*ae771770SStanislav Sedov {
134*ae771770SStanislav Sedov size_t n;
135*ae771770SStanislav Sedov for (n = 0; n < array->len; n++)
136*ae771770SStanislav Sedov fn(array->val[n], ctx);
137*ae771770SStanislav Sedov }
138*ae771770SStanislav Sedov
139*ae771770SStanislav Sedov #ifdef __BLOCKS__
140*ae771770SStanislav Sedov /**
141*ae771770SStanislav Sedov * Iterate over all objects in array
142*ae771770SStanislav Sedov *
143*ae771770SStanislav Sedov * @param array array to iterate over
144*ae771770SStanislav Sedov * @param fn block to call on each object
145*ae771770SStanislav Sedov */
146*ae771770SStanislav Sedov
147*ae771770SStanislav Sedov void
148*ae771770SStanislav Sedov heim_array_iterate(heim_array_t array, void (^fn)(heim_object_t))
149*ae771770SStanislav Sedov {
150*ae771770SStanislav Sedov size_t n;
151*ae771770SStanislav Sedov for (n = 0; n < array->len; n++)
152*ae771770SStanislav Sedov fn(array->val[n]);
153*ae771770SStanislav Sedov }
154*ae771770SStanislav Sedov #endif
155*ae771770SStanislav Sedov
156*ae771770SStanislav Sedov /**
157*ae771770SStanislav Sedov * Get length of array
158*ae771770SStanislav Sedov *
159*ae771770SStanislav Sedov * @param array array to get length of
160*ae771770SStanislav Sedov *
161*ae771770SStanislav Sedov * @return length of array
162*ae771770SStanislav Sedov */
163*ae771770SStanislav Sedov
164*ae771770SStanislav Sedov size_t
heim_array_get_length(heim_array_t array)165*ae771770SStanislav Sedov heim_array_get_length(heim_array_t array)
166*ae771770SStanislav Sedov {
167*ae771770SStanislav Sedov return array->len;
168*ae771770SStanislav Sedov }
169*ae771770SStanislav Sedov
170*ae771770SStanislav Sedov /**
171*ae771770SStanislav Sedov * Copy value of array
172*ae771770SStanislav Sedov *
173*ae771770SStanislav Sedov * @param array array copy object from
174*ae771770SStanislav Sedov * @param idx index of object, 0 based, must be smaller then
175*ae771770SStanislav Sedov * heim_array_get_length()
176*ae771770SStanislav Sedov *
177*ae771770SStanislav Sedov * @return a retained copy of the object
178*ae771770SStanislav Sedov */
179*ae771770SStanislav Sedov
180*ae771770SStanislav Sedov heim_object_t
heim_array_copy_value(heim_array_t array,size_t idx)181*ae771770SStanislav Sedov heim_array_copy_value(heim_array_t array, size_t idx)
182*ae771770SStanislav Sedov {
183*ae771770SStanislav Sedov if (idx >= array->len)
184*ae771770SStanislav Sedov heim_abort("index too large");
185*ae771770SStanislav Sedov return heim_retain(array->val[idx]);
186*ae771770SStanislav Sedov }
187*ae771770SStanislav Sedov
188*ae771770SStanislav Sedov /**
189*ae771770SStanislav Sedov * Delete value at idx
190*ae771770SStanislav Sedov *
191*ae771770SStanislav Sedov * @param array the array to modify
192*ae771770SStanislav Sedov * @param idx the key to delete
193*ae771770SStanislav Sedov */
194*ae771770SStanislav Sedov
195*ae771770SStanislav Sedov void
heim_array_delete_value(heim_array_t array,size_t idx)196*ae771770SStanislav Sedov heim_array_delete_value(heim_array_t array, size_t idx)
197*ae771770SStanislav Sedov {
198*ae771770SStanislav Sedov heim_object_t obj;
199*ae771770SStanislav Sedov if (idx >= array->len)
200*ae771770SStanislav Sedov heim_abort("index too large");
201*ae771770SStanislav Sedov obj = array->val[idx];
202*ae771770SStanislav Sedov
203*ae771770SStanislav Sedov array->len--;
204*ae771770SStanislav Sedov
205*ae771770SStanislav Sedov if (idx < array->len)
206*ae771770SStanislav Sedov memmove(&array->val[idx], &array->val[idx + 1],
207*ae771770SStanislav Sedov (array->len - idx) * sizeof(array->val[0]));
208*ae771770SStanislav Sedov
209*ae771770SStanislav Sedov heim_release(obj);
210*ae771770SStanislav Sedov }
211*ae771770SStanislav Sedov
212*ae771770SStanislav Sedov #ifdef __BLOCKS__
213*ae771770SStanislav Sedov /**
214*ae771770SStanislav Sedov * Get value at idx
215*ae771770SStanislav Sedov *
216*ae771770SStanislav Sedov * @param array the array to modify
217*ae771770SStanislav Sedov * @param idx the key to delete
218*ae771770SStanislav Sedov */
219*ae771770SStanislav Sedov
220*ae771770SStanislav Sedov void
221*ae771770SStanislav Sedov heim_array_filter(heim_array_t array, int (^block)(heim_object_t))
222*ae771770SStanislav Sedov {
223*ae771770SStanislav Sedov size_t n = 0;
224*ae771770SStanislav Sedov
225*ae771770SStanislav Sedov while (n < array->len) {
226*ae771770SStanislav Sedov if (block(array->val[n])) {
227*ae771770SStanislav Sedov heim_array_delete_value(array, n);
228*ae771770SStanislav Sedov } else {
229*ae771770SStanislav Sedov n++;
230*ae771770SStanislav Sedov }
231*ae771770SStanislav Sedov }
232*ae771770SStanislav Sedov }
233*ae771770SStanislav Sedov
234*ae771770SStanislav Sedov #endif /* __BLOCKS__ */
235