/*1* Copyright (c) 2010 Kungliga Tekniska Högskolan2* (Royal Institute of Technology, Stockholm, Sweden).3* All rights reserved.4*5* Portions Copyright (c) 2010 Apple Inc. All rights reserved.6*7* Redistribution and use in source and binary forms, with or without8* modification, are permitted provided that the following conditions9* are met:10*11* 1. Redistributions of source code must retain the above copyright12* notice, this list of conditions and the following disclaimer.13*14* 2. Redistributions in binary form must reproduce the above copyright15* notice, this list of conditions and the following disclaimer in the16* documentation and/or other materials provided with the distribution.17*18* 3. Neither the name of the Institute nor the names of its contributors19* may be used to endorse or promote products derived from this software20* without specific prior written permission.21*22* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND23* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE24* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE25* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE26* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL27* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS28* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)29* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT30* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY31* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF32* SUCH DAMAGE.33*/3435#include "baselocl.h"3637/*38*39*/4041struct heim_array_data {42size_t len;43heim_object_t *val;44};4546static void47array_dealloc(heim_object_t ptr)48{49heim_array_t array = ptr;50size_t n;51for (n = 0; n < array->len; n++)52heim_release(array->val[n]);53free(array->val);54}5556struct heim_type_data array_object = {57HEIM_TID_ARRAY,58"dict-object",59NULL,60array_dealloc,61NULL,62NULL,63NULL64};6566/**67* Allocate an array68*69* @return A new allocated array, free with heim_release()70*/7172heim_array_t73heim_array_create(void)74{75heim_array_t array;7677array = _heim_alloc_object(&array_object, sizeof(*array));78if (array == NULL)79return NULL;8081array->val = NULL;82array->len = 0;8384return array;85}8687/**88* Get type id of an dict89*90* @return the type id91*/9293heim_tid_t94heim_array_get_type_id(void)95{96return HEIM_TID_ARRAY;97}9899/**100* Append object to array101*102* @param array array to add too103* @param object the object to add104*105* @return zero if added, errno otherwise106*/107108int109heim_array_append_value(heim_array_t array, heim_object_t object)110{111heim_object_t *ptr;112113ptr = realloc(array->val, (array->len + 1) * sizeof(array->val[0]));114if (ptr == NULL)115return ENOMEM;116array->val = ptr;117array->val[array->len++] = heim_retain(object);118119return 0;120}121122/**123* Iterate over all objects in array124*125* @param array array to iterate over126* @param fn function to call on each object127* @param ctx context passed to fn128*/129130void131heim_array_iterate_f(heim_array_t array, heim_array_iterator_f_t fn, void *ctx)132{133size_t n;134for (n = 0; n < array->len; n++)135fn(array->val[n], ctx);136}137138#ifdef __BLOCKS__139/**140* Iterate over all objects in array141*142* @param array array to iterate over143* @param fn block to call on each object144*/145146void147heim_array_iterate(heim_array_t array, void (^fn)(heim_object_t))148{149size_t n;150for (n = 0; n < array->len; n++)151fn(array->val[n]);152}153#endif154155/**156* Get length of array157*158* @param array array to get length of159*160* @return length of array161*/162163size_t164heim_array_get_length(heim_array_t array)165{166return array->len;167}168169/**170* Copy value of array171*172* @param array array copy object from173* @param idx index of object, 0 based, must be smaller then174* heim_array_get_length()175*176* @return a retained copy of the object177*/178179heim_object_t180heim_array_copy_value(heim_array_t array, size_t idx)181{182if (idx >= array->len)183heim_abort("index too large");184return heim_retain(array->val[idx]);185}186187/**188* Delete value at idx189*190* @param array the array to modify191* @param idx the key to delete192*/193194void195heim_array_delete_value(heim_array_t array, size_t idx)196{197heim_object_t obj;198if (idx >= array->len)199heim_abort("index too large");200obj = array->val[idx];201202array->len--;203204if (idx < array->len)205memmove(&array->val[idx], &array->val[idx + 1],206(array->len - idx) * sizeof(array->val[0]));207208heim_release(obj);209}210211#ifdef __BLOCKS__212/**213* Get value at idx214*215* @param array the array to modify216* @param idx the key to delete217*/218219void220heim_array_filter(heim_array_t array, int (^block)(heim_object_t))221{222size_t n = 0;223224while (n < array->len) {225if (block(array->val[n])) {226heim_array_delete_value(array, n);227} else {228n++;229}230}231}232233#endif /* __BLOCKS__ */234235236