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