17c450da7SStanislav Sedov /*
27c450da7SStanislav Sedov * Copyright (c) 2010 Kungliga Tekniska Högskolan
37c450da7SStanislav Sedov * (Royal Institute of Technology, Stockholm, Sweden).
47c450da7SStanislav Sedov * All rights reserved.
57c450da7SStanislav Sedov *
67c450da7SStanislav Sedov * Portions Copyright (c) 2010 Apple Inc. All rights reserved.
77c450da7SStanislav Sedov *
87c450da7SStanislav Sedov * Redistribution and use in source and binary forms, with or without
97c450da7SStanislav Sedov * modification, are permitted provided that the following conditions
107c450da7SStanislav Sedov * are met:
117c450da7SStanislav Sedov *
127c450da7SStanislav Sedov * 1. Redistributions of source code must retain the above copyright
137c450da7SStanislav Sedov * notice, this list of conditions and the following disclaimer.
147c450da7SStanislav Sedov *
157c450da7SStanislav Sedov * 2. Redistributions in binary form must reproduce the above copyright
167c450da7SStanislav Sedov * notice, this list of conditions and the following disclaimer in the
177c450da7SStanislav Sedov * documentation and/or other materials provided with the distribution.
187c450da7SStanislav Sedov *
197c450da7SStanislav Sedov * 3. Neither the name of the Institute nor the names of its contributors
207c450da7SStanislav Sedov * may be used to endorse or promote products derived from this software
217c450da7SStanislav Sedov * without specific prior written permission.
227c450da7SStanislav Sedov *
237c450da7SStanislav Sedov * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
247c450da7SStanislav Sedov * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
257c450da7SStanislav Sedov * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
267c450da7SStanislav Sedov * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
277c450da7SStanislav Sedov * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
287c450da7SStanislav Sedov * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
297c450da7SStanislav Sedov * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
307c450da7SStanislav Sedov * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
317c450da7SStanislav Sedov * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
327c450da7SStanislav Sedov * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
337c450da7SStanislav Sedov * SUCH DAMAGE.
347c450da7SStanislav Sedov */
357c450da7SStanislav Sedov
367c450da7SStanislav Sedov #include "baselocl.h"
377c450da7SStanislav Sedov
387c450da7SStanislav Sedov /*
397c450da7SStanislav Sedov *
407c450da7SStanislav Sedov */
417c450da7SStanislav Sedov
427c450da7SStanislav Sedov struct heim_array_data {
437c450da7SStanislav Sedov size_t len;
447c450da7SStanislav Sedov heim_object_t *val;
457c450da7SStanislav Sedov };
467c450da7SStanislav Sedov
477c450da7SStanislav Sedov static void
array_dealloc(heim_object_t ptr)487c450da7SStanislav Sedov array_dealloc(heim_object_t ptr)
497c450da7SStanislav Sedov {
507c450da7SStanislav Sedov heim_array_t array = ptr;
517c450da7SStanislav Sedov size_t n;
527c450da7SStanislav Sedov for (n = 0; n < array->len; n++)
537c450da7SStanislav Sedov heim_release(array->val[n]);
547c450da7SStanislav Sedov free(array->val);
557c450da7SStanislav Sedov }
567c450da7SStanislav Sedov
577c450da7SStanislav Sedov struct heim_type_data array_object = {
587c450da7SStanislav Sedov HEIM_TID_ARRAY,
597c450da7SStanislav Sedov "dict-object",
607c450da7SStanislav Sedov NULL,
617c450da7SStanislav Sedov array_dealloc,
627c450da7SStanislav Sedov NULL,
637c450da7SStanislav Sedov NULL,
647c450da7SStanislav Sedov NULL
657c450da7SStanislav Sedov };
667c450da7SStanislav Sedov
677c450da7SStanislav Sedov /**
687c450da7SStanislav Sedov * Allocate an array
697c450da7SStanislav Sedov *
707c450da7SStanislav Sedov * @return A new allocated array, free with heim_release()
717c450da7SStanislav Sedov */
727c450da7SStanislav Sedov
737c450da7SStanislav Sedov heim_array_t
heim_array_create(void)747c450da7SStanislav Sedov heim_array_create(void)
757c450da7SStanislav Sedov {
767c450da7SStanislav Sedov heim_array_t array;
777c450da7SStanislav Sedov
787c450da7SStanislav Sedov array = _heim_alloc_object(&array_object, sizeof(*array));
797c450da7SStanislav Sedov if (array == NULL)
807c450da7SStanislav Sedov return NULL;
817c450da7SStanislav Sedov
827c450da7SStanislav Sedov array->val = NULL;
837c450da7SStanislav Sedov array->len = 0;
847c450da7SStanislav Sedov
857c450da7SStanislav Sedov return array;
867c450da7SStanislav Sedov }
877c450da7SStanislav Sedov
887c450da7SStanislav Sedov /**
897c450da7SStanislav Sedov * Get type id of an dict
907c450da7SStanislav Sedov *
917c450da7SStanislav Sedov * @return the type id
927c450da7SStanislav Sedov */
937c450da7SStanislav Sedov
947c450da7SStanislav Sedov heim_tid_t
heim_array_get_type_id(void)957c450da7SStanislav Sedov heim_array_get_type_id(void)
967c450da7SStanislav Sedov {
977c450da7SStanislav Sedov return HEIM_TID_ARRAY;
987c450da7SStanislav Sedov }
997c450da7SStanislav Sedov
1007c450da7SStanislav Sedov /**
1017c450da7SStanislav Sedov * Append object to array
1027c450da7SStanislav Sedov *
1037c450da7SStanislav Sedov * @param array array to add too
1047c450da7SStanislav Sedov * @param object the object to add
1057c450da7SStanislav Sedov *
1067c450da7SStanislav Sedov * @return zero if added, errno otherwise
1077c450da7SStanislav Sedov */
1087c450da7SStanislav Sedov
1097c450da7SStanislav Sedov int
heim_array_append_value(heim_array_t array,heim_object_t object)1107c450da7SStanislav Sedov heim_array_append_value(heim_array_t array, heim_object_t object)
1117c450da7SStanislav Sedov {
1127c450da7SStanislav Sedov heim_object_t *ptr;
1137c450da7SStanislav Sedov
1147c450da7SStanislav Sedov ptr = realloc(array->val, (array->len + 1) * sizeof(array->val[0]));
1157c450da7SStanislav Sedov if (ptr == NULL)
1167c450da7SStanislav Sedov return ENOMEM;
1177c450da7SStanislav Sedov array->val = ptr;
1187c450da7SStanislav Sedov array->val[array->len++] = heim_retain(object);
1197c450da7SStanislav Sedov
1207c450da7SStanislav Sedov return 0;
1217c450da7SStanislav Sedov }
1227c450da7SStanislav Sedov
1237c450da7SStanislav Sedov /**
1247c450da7SStanislav Sedov * Iterate over all objects in array
1257c450da7SStanislav Sedov *
1267c450da7SStanislav Sedov * @param array array to iterate over
1277c450da7SStanislav Sedov * @param fn function to call on each object
1287c450da7SStanislav Sedov * @param ctx context passed to fn
1297c450da7SStanislav Sedov */
1307c450da7SStanislav Sedov
1317c450da7SStanislav Sedov void
heim_array_iterate_f(heim_array_t array,heim_array_iterator_f_t fn,void * ctx)1327c450da7SStanislav Sedov heim_array_iterate_f(heim_array_t array, heim_array_iterator_f_t fn, void *ctx)
1337c450da7SStanislav Sedov {
1347c450da7SStanislav Sedov size_t n;
1357c450da7SStanislav Sedov for (n = 0; n < array->len; n++)
1367c450da7SStanislav Sedov fn(array->val[n], ctx);
1377c450da7SStanislav Sedov }
1387c450da7SStanislav Sedov
1397c450da7SStanislav Sedov #ifdef __BLOCKS__
1407c450da7SStanislav Sedov /**
1417c450da7SStanislav Sedov * Iterate over all objects in array
1427c450da7SStanislav Sedov *
1437c450da7SStanislav Sedov * @param array array to iterate over
1447c450da7SStanislav Sedov * @param fn block to call on each object
1457c450da7SStanislav Sedov */
1467c450da7SStanislav Sedov
1477c450da7SStanislav Sedov void
1487c450da7SStanislav Sedov heim_array_iterate(heim_array_t array, void (^fn)(heim_object_t))
1497c450da7SStanislav Sedov {
1507c450da7SStanislav Sedov size_t n;
1517c450da7SStanislav Sedov for (n = 0; n < array->len; n++)
1527c450da7SStanislav Sedov fn(array->val[n]);
1537c450da7SStanislav Sedov }
1547c450da7SStanislav Sedov #endif
1557c450da7SStanislav Sedov
1567c450da7SStanislav Sedov /**
1577c450da7SStanislav Sedov * Get length of array
1587c450da7SStanislav Sedov *
1597c450da7SStanislav Sedov * @param array array to get length of
1607c450da7SStanislav Sedov *
1617c450da7SStanislav Sedov * @return length of array
1627c450da7SStanislav Sedov */
1637c450da7SStanislav Sedov
1647c450da7SStanislav Sedov size_t
heim_array_get_length(heim_array_t array)1657c450da7SStanislav Sedov heim_array_get_length(heim_array_t array)
1667c450da7SStanislav Sedov {
1677c450da7SStanislav Sedov return array->len;
1687c450da7SStanislav Sedov }
1697c450da7SStanislav Sedov
1707c450da7SStanislav Sedov /**
1717c450da7SStanislav Sedov * Copy value of array
1727c450da7SStanislav Sedov *
1737c450da7SStanislav Sedov * @param array array copy object from
1747c450da7SStanislav Sedov * @param idx index of object, 0 based, must be smaller then
1757c450da7SStanislav Sedov * heim_array_get_length()
1767c450da7SStanislav Sedov *
1777c450da7SStanislav Sedov * @return a retained copy of the object
1787c450da7SStanislav Sedov */
1797c450da7SStanislav Sedov
1807c450da7SStanislav Sedov heim_object_t
heim_array_copy_value(heim_array_t array,size_t idx)1817c450da7SStanislav Sedov heim_array_copy_value(heim_array_t array, size_t idx)
1827c450da7SStanislav Sedov {
1837c450da7SStanislav Sedov if (idx >= array->len)
1847c450da7SStanislav Sedov heim_abort("index too large");
1857c450da7SStanislav Sedov return heim_retain(array->val[idx]);
1867c450da7SStanislav Sedov }
1877c450da7SStanislav Sedov
1887c450da7SStanislav Sedov /**
1897c450da7SStanislav Sedov * Delete value at idx
1907c450da7SStanislav Sedov *
1917c450da7SStanislav Sedov * @param array the array to modify
1927c450da7SStanislav Sedov * @param idx the key to delete
1937c450da7SStanislav Sedov */
1947c450da7SStanislav Sedov
1957c450da7SStanislav Sedov void
heim_array_delete_value(heim_array_t array,size_t idx)1967c450da7SStanislav Sedov heim_array_delete_value(heim_array_t array, size_t idx)
1977c450da7SStanislav Sedov {
1987c450da7SStanislav Sedov heim_object_t obj;
1997c450da7SStanislav Sedov if (idx >= array->len)
2007c450da7SStanislav Sedov heim_abort("index too large");
2017c450da7SStanislav Sedov obj = array->val[idx];
2027c450da7SStanislav Sedov
2037c450da7SStanislav Sedov array->len--;
2047c450da7SStanislav Sedov
2057c450da7SStanislav Sedov if (idx < array->len)
2067c450da7SStanislav Sedov memmove(&array->val[idx], &array->val[idx + 1],
2077c450da7SStanislav Sedov (array->len - idx) * sizeof(array->val[0]));
2087c450da7SStanislav Sedov
2097c450da7SStanislav Sedov heim_release(obj);
2107c450da7SStanislav Sedov }
2117c450da7SStanislav Sedov
2127c450da7SStanislav Sedov #ifdef __BLOCKS__
2137c450da7SStanislav Sedov /**
2147c450da7SStanislav Sedov * Get value at idx
2157c450da7SStanislav Sedov *
2167c450da7SStanislav Sedov * @param array the array to modify
2177c450da7SStanislav Sedov * @param idx the key to delete
2187c450da7SStanislav Sedov */
2197c450da7SStanislav Sedov
2207c450da7SStanislav Sedov void
221813b7899SStanislav Sedov heim_array_filter(heim_array_t array, int (^block)(heim_object_t))
2227c450da7SStanislav Sedov {
2237c450da7SStanislav Sedov size_t n = 0;
2247c450da7SStanislav Sedov
2257c450da7SStanislav Sedov while (n < array->len) {
2267c450da7SStanislav Sedov if (block(array->val[n])) {
2277c450da7SStanislav Sedov heim_array_delete_value(array, n);
2287c450da7SStanislav Sedov } else {
2297c450da7SStanislav Sedov n++;
2307c450da7SStanislav Sedov }
2317c450da7SStanislav Sedov }
2327c450da7SStanislav Sedov }
2337c450da7SStanislav Sedov
2347c450da7SStanislav Sedov #endif /* __BLOCKS__ */
235