array.c revision 302408
1178355Ssam/*
2178355Ssam * Copyright (c) 2010 Kungliga Tekniska H��gskolan
3178355Ssam * (Royal Institute of Technology, Stockholm, Sweden).
4208060Sdougb * All rights reserved.
5178355Ssam *
6178355Ssam * Portions Copyright (c) 2010 Apple Inc. All rights reserved.
7178355Ssam *
8178355Ssam * Redistribution and use in source and binary forms, with or without
9178355Ssam * modification, are permitted provided that the following conditions
10178355Ssam * are met:
11178355Ssam *
12178355Ssam * 1. Redistributions of source code must retain the above copyright
13208060Sdougb *    notice, this list of conditions and the following disclaimer.
14178355Ssam *
15178355Ssam * 2. Redistributions in binary form must reproduce the above copyright
16178355Ssam *    notice, this list of conditions and the following disclaimer in the
17178355Ssam *    documentation and/or other materials provided with the distribution.
18178355Ssam *
19178355Ssam * 3. Neither the name of the Institute nor the names of its contributors
20178355Ssam *    may be used to endorse or promote products derived from this software
21178355Ssam *    without specific prior written permission.
22178355Ssam *
23178355Ssam * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24208060Sdougb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25178355Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26178355Ssam * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27178355Ssam * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28178355Ssam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29178355Ssam * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30178355Ssam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31178355Ssam * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32178355Ssam * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33178355Ssam * SUCH DAMAGE.
34178355Ssam */
35178355Ssam
36178355Ssam#include "baselocl.h"
37178355Ssam
38178355Ssam/*
39178355Ssam *
40178355Ssam */
41178355Ssam
42186106Ssamstruct heim_array_data {
43178355Ssam    size_t len;
44178355Ssam    heim_object_t *val;
45178355Ssam};
46178355Ssam
47178355Ssamstatic void
48178355Ssamarray_dealloc(heim_object_t ptr)
49178355Ssam{
50178355Ssam    heim_array_t array = ptr;
51178355Ssam    size_t n;
52178355Ssam    for (n = 0; n < array->len; n++)
53178355Ssam	heim_release(array->val[n]);
54178355Ssam    free(array->val);
55178355Ssam}
56178355Ssam
57178355Ssamstruct heim_type_data array_object = {
58178355Ssam    HEIM_TID_ARRAY,
59178355Ssam    "dict-object",
60178355Ssam    NULL,
61178355Ssam    array_dealloc,
62178355Ssam    NULL,
63178355Ssam    NULL,
64178355Ssam    NULL
65178355Ssam};
66178355Ssam
67178355Ssam/**
68178355Ssam * Allocate an array
69178355Ssam *
70178355Ssam * @return A new allocated array, free with heim_release()
71178355Ssam */
72178355Ssam
73178355Ssamheim_array_t
74178355Ssamheim_array_create(void)
75178355Ssam{
76178355Ssam    heim_array_t array;
77178355Ssam
78178355Ssam    array = _heim_alloc_object(&array_object, sizeof(*array));
79178355Ssam    if (array == NULL)
80178355Ssam	return NULL;
81178355Ssam
82178355Ssam    array->val = NULL;
83178355Ssam    array->len = 0;
84178355Ssam
85178355Ssam    return array;
86223497Sadrian}
87178355Ssam
88178355Ssam/**
89178355Ssam * Get type id of an dict
90178355Ssam *
91178355Ssam * @return the type id
92178355Ssam */
93178355Ssam
94178355Ssamheim_tid_t
95178355Ssamheim_array_get_type_id(void)
96178355Ssam{
97178355Ssam    return HEIM_TID_ARRAY;
98178355Ssam}
99223498Sadrian
100178355Ssam/**
101178355Ssam * Append object to array
102178355Ssam *
103178355Ssam * @param array array to add too
104178355Ssam * @param object the object to add
105178355Ssam *
106178355Ssam * @return zero if added, errno otherwise
107178355Ssam */
108178355Ssam
109223498Sadrianint
110178355Ssamheim_array_append_value(heim_array_t array, heim_object_t object)
111178355Ssam{
112178355Ssam    heim_object_t *ptr;
113178355Ssam
114178355Ssam    ptr = realloc(array->val, (array->len + 1) * sizeof(array->val[0]));
115178355Ssam    if (ptr == NULL)
116178355Ssam	return ENOMEM;
117178355Ssam    array->val = ptr;
118178355Ssam    array->val[array->len++] = heim_retain(object);
119178355Ssam
120178355Ssam    return 0;
121178355Ssam}
122178355Ssam
123178355Ssam/**
124178355Ssam * Iterate over all objects in array
125178355Ssam *
126178355Ssam * @param array array to iterate over
127178355Ssam * @param fn function to call on each object
128178355Ssam * @param ctx context passed to fn
129178355Ssam */
130178355Ssam
131178355Ssamvoid
132178355Ssamheim_array_iterate_f(heim_array_t array, heim_array_iterator_f_t fn, void *ctx)
133178355Ssam{
134178355Ssam    size_t n;
135178355Ssam    for (n = 0; n < array->len; n++)
136178355Ssam	fn(array->val[n], ctx);
137178355Ssam}
138178355Ssam
139178355Ssam#ifdef __BLOCKS__
140178355Ssam/**
141223496Sadrian * Iterate over all objects in array
142223496Sadrian *
143223496Sadrian * @param array array to iterate over
144223496Sadrian * @param fn block to call on each object
145223496Sadrian */
146223496Sadrian
147223563Sadrianvoid
148223563Sadrianheim_array_iterate(heim_array_t array, void (^fn)(heim_object_t))
149223563Sadrian{
150223563Sadrian    size_t n;
151223563Sadrian    for (n = 0; n < array->len; n++)
152223563Sadrian	fn(array->val[n]);
153223563Sadrian}
154223563Sadrian#endif
155223563Sadrian
156223563Sadrian/**
157223563Sadrian * Get length of array
158223563Sadrian *
159178355Ssam * @param array array to get length of
160178355Ssam *
161178355Ssam * @return length of array
162178355Ssam */
163178355Ssam
164178355Ssamsize_t
165178355Ssamheim_array_get_length(heim_array_t array)
166178355Ssam{
167178355Ssam    return array->len;
168178355Ssam}
169178355Ssam
170178355Ssam/**
171178355Ssam * Copy value of array
172178355Ssam *
173178355Ssam * @param array array copy object from
174178355Ssam * @param idx index of object, 0 based, must be smaller then
175178355Ssam *        heim_array_get_length()
176178355Ssam *
177178355Ssam * @return a retained copy of the object
178178355Ssam */
179178355Ssam
180178355Ssamheim_object_t
181178355Ssamheim_array_copy_value(heim_array_t array, size_t idx)
182178355Ssam{
183178355Ssam    if (idx >= array->len)
184178355Ssam	heim_abort("index too large");
185178355Ssam    return heim_retain(array->val[idx]);
186178355Ssam}
187178355Ssam
188178355Ssam/**
189178355Ssam * Delete value at idx
190178355Ssam *
191178355Ssam * @param array the array to modify
192178355Ssam * @param idx the key to delete
193178355Ssam */
194178355Ssam
195178355Ssamvoid
196178355Ssamheim_array_delete_value(heim_array_t array, size_t idx)
197223496Sadrian{
198223496Sadrian    heim_object_t obj;
199223496Sadrian    if (idx >= array->len)
200223496Sadrian	heim_abort("index too large");
201223496Sadrian    obj = array->val[idx];
202223496Sadrian
203223496Sadrian    array->len--;
204223496Sadrian
205223496Sadrian    if (idx < array->len)
206223496Sadrian	memmove(&array->val[idx], &array->val[idx + 1],
207223496Sadrian		(array->len - idx) * sizeof(array->val[0]));
208223496Sadrian
209223496Sadrian    heim_release(obj);
210223496Sadrian}
211223563Sadrian
212223563Sadrian#ifdef __BLOCKS__
213223563Sadrian/**
214223563Sadrian * Get value at idx
215223563Sadrian *
216223563Sadrian * @param array the array to modify
217223563Sadrian * @param idx the key to delete
218223563Sadrian */
219223563Sadrian
220223563Sadrianvoid
221223563Sadrianheim_array_filter(heim_array_t array, int (^block)(heim_object_t))
222223563Sadrian{
223223563Sadrian    size_t n = 0;
224223563Sadrian
225223563Sadrian    while (n < array->len) {
226223563Sadrian	if (block(array->val[n])) {
227223563Sadrian	    heim_array_delete_value(array, n);
228223563Sadrian	} else {
229223563Sadrian	    n++;
230223563Sadrian	}
231223563Sadrian    }
232223563Sadrian}
233223563Sadrian
234223563Sadrian#endif /* __BLOCKS__ */
235223563Sadrian