1226031Sstas/* 2226031Sstas * Copyright (c) 2010 Kungliga Tekniska H��gskolan 3226031Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4226031Sstas * All rights reserved. 5226031Sstas * 6226031Sstas * Portions Copyright (c) 2010 Apple Inc. All rights reserved. 7226031Sstas * 8226031Sstas * Redistribution and use in source and binary forms, with or without 9226031Sstas * modification, are permitted provided that the following conditions 10226031Sstas * are met: 11226031Sstas * 12226031Sstas * 1. Redistributions of source code must retain the above copyright 13226031Sstas * notice, this list of conditions and the following disclaimer. 14226031Sstas * 15226031Sstas * 2. Redistributions in binary form must reproduce the above copyright 16226031Sstas * notice, this list of conditions and the following disclaimer in the 17226031Sstas * documentation and/or other materials provided with the distribution. 18226031Sstas * 19226031Sstas * 3. Neither the name of the Institute nor the names of its contributors 20226031Sstas * may be used to endorse or promote products derived from this software 21226031Sstas * without specific prior written permission. 22226031Sstas * 23226031Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24226031Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25226031Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26226031Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27226031Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28226031Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29226031Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30226031Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31226031Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32226031Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33226031Sstas * SUCH DAMAGE. 34226031Sstas */ 35226031Sstas 36226031Sstas#include "baselocl.h" 37226031Sstas 38226031Sstas/* 39226031Sstas * 40226031Sstas */ 41226031Sstas 42226031Sstasstruct heim_array_data { 43226031Sstas size_t len; 44226031Sstas heim_object_t *val; 45226031Sstas}; 46226031Sstas 47226031Sstasstatic void 48226031Sstasarray_dealloc(heim_object_t ptr) 49226031Sstas{ 50226031Sstas heim_array_t array = ptr; 51226031Sstas size_t n; 52226031Sstas for (n = 0; n < array->len; n++) 53226031Sstas heim_release(array->val[n]); 54226031Sstas free(array->val); 55226031Sstas} 56226031Sstas 57226031Sstasstruct heim_type_data array_object = { 58226031Sstas HEIM_TID_ARRAY, 59226031Sstas "dict-object", 60226031Sstas NULL, 61226031Sstas array_dealloc, 62226031Sstas NULL, 63226031Sstas NULL, 64226031Sstas NULL 65226031Sstas}; 66226031Sstas 67226031Sstas/** 68226031Sstas * Allocate an array 69226031Sstas * 70226031Sstas * @return A new allocated array, free with heim_release() 71226031Sstas */ 72226031Sstas 73226031Sstasheim_array_t 74226031Sstasheim_array_create(void) 75226031Sstas{ 76226031Sstas heim_array_t array; 77226031Sstas 78226031Sstas array = _heim_alloc_object(&array_object, sizeof(*array)); 79226031Sstas if (array == NULL) 80226031Sstas return NULL; 81226031Sstas 82226031Sstas array->val = NULL; 83226031Sstas array->len = 0; 84226031Sstas 85226031Sstas return array; 86226031Sstas} 87226031Sstas 88226031Sstas/** 89226031Sstas * Get type id of an dict 90226031Sstas * 91226031Sstas * @return the type id 92226031Sstas */ 93226031Sstas 94226031Sstasheim_tid_t 95226031Sstasheim_array_get_type_id(void) 96226031Sstas{ 97226031Sstas return HEIM_TID_ARRAY; 98226031Sstas} 99226031Sstas 100226031Sstas/** 101226031Sstas * Append object to array 102226031Sstas * 103226031Sstas * @param array array to add too 104226031Sstas * @param object the object to add 105226031Sstas * 106226031Sstas * @return zero if added, errno otherwise 107226031Sstas */ 108226031Sstas 109226031Sstasint 110226031Sstasheim_array_append_value(heim_array_t array, heim_object_t object) 111226031Sstas{ 112226031Sstas heim_object_t *ptr; 113226031Sstas 114226031Sstas ptr = realloc(array->val, (array->len + 1) * sizeof(array->val[0])); 115226031Sstas if (ptr == NULL) 116226031Sstas return ENOMEM; 117226031Sstas array->val = ptr; 118226031Sstas array->val[array->len++] = heim_retain(object); 119226031Sstas 120226031Sstas return 0; 121226031Sstas} 122226031Sstas 123226031Sstas/** 124226031Sstas * Iterate over all objects in array 125226031Sstas * 126226031Sstas * @param array array to iterate over 127226031Sstas * @param fn function to call on each object 128226031Sstas * @param ctx context passed to fn 129226031Sstas */ 130226031Sstas 131226031Sstasvoid 132226031Sstasheim_array_iterate_f(heim_array_t array, heim_array_iterator_f_t fn, void *ctx) 133226031Sstas{ 134226031Sstas size_t n; 135226031Sstas for (n = 0; n < array->len; n++) 136226031Sstas fn(array->val[n], ctx); 137226031Sstas} 138226031Sstas 139226031Sstas#ifdef __BLOCKS__ 140226031Sstas/** 141226031Sstas * Iterate over all objects in array 142226031Sstas * 143226031Sstas * @param array array to iterate over 144226031Sstas * @param fn block to call on each object 145226031Sstas */ 146226031Sstas 147226031Sstasvoid 148226031Sstasheim_array_iterate(heim_array_t array, void (^fn)(heim_object_t)) 149226031Sstas{ 150226031Sstas size_t n; 151226031Sstas for (n = 0; n < array->len; n++) 152226031Sstas fn(array->val[n]); 153226031Sstas} 154226031Sstas#endif 155226031Sstas 156226031Sstas/** 157226031Sstas * Get length of array 158226031Sstas * 159226031Sstas * @param array array to get length of 160226031Sstas * 161226031Sstas * @return length of array 162226031Sstas */ 163226031Sstas 164226031Sstassize_t 165226031Sstasheim_array_get_length(heim_array_t array) 166226031Sstas{ 167226031Sstas return array->len; 168226031Sstas} 169226031Sstas 170226031Sstas/** 171226031Sstas * Copy value of array 172226031Sstas * 173226031Sstas * @param array array copy object from 174226031Sstas * @param idx index of object, 0 based, must be smaller then 175226031Sstas * heim_array_get_length() 176226031Sstas * 177226031Sstas * @return a retained copy of the object 178226031Sstas */ 179226031Sstas 180226031Sstasheim_object_t 181226031Sstasheim_array_copy_value(heim_array_t array, size_t idx) 182226031Sstas{ 183226031Sstas if (idx >= array->len) 184226031Sstas heim_abort("index too large"); 185226031Sstas return heim_retain(array->val[idx]); 186226031Sstas} 187226031Sstas 188226031Sstas/** 189226031Sstas * Delete value at idx 190226031Sstas * 191226031Sstas * @param array the array to modify 192226031Sstas * @param idx the key to delete 193226031Sstas */ 194226031Sstas 195226031Sstasvoid 196226031Sstasheim_array_delete_value(heim_array_t array, size_t idx) 197226031Sstas{ 198226031Sstas heim_object_t obj; 199226031Sstas if (idx >= array->len) 200226031Sstas heim_abort("index too large"); 201226031Sstas obj = array->val[idx]; 202226031Sstas 203226031Sstas array->len--; 204226031Sstas 205226031Sstas if (idx < array->len) 206226031Sstas memmove(&array->val[idx], &array->val[idx + 1], 207226031Sstas (array->len - idx) * sizeof(array->val[0])); 208226031Sstas 209226031Sstas heim_release(obj); 210226031Sstas} 211226031Sstas 212226031Sstas#ifdef __BLOCKS__ 213226031Sstas/** 214226031Sstas * Get value at idx 215226031Sstas * 216226031Sstas * @param array the array to modify 217226031Sstas * @param idx the key to delete 218226031Sstas */ 219226031Sstas 220226031Sstasvoid 221226128Sstasheim_array_filter(heim_array_t array, int (^block)(heim_object_t)) 222226031Sstas{ 223226031Sstas size_t n = 0; 224226031Sstas 225226031Sstas while (n < array->len) { 226226031Sstas if (block(array->val[n])) { 227226031Sstas heim_array_delete_value(array, n); 228226031Sstas } else { 229226031Sstas n++; 230226031Sstas } 231226031Sstas } 232226031Sstas} 233226031Sstas 234226031Sstas#endif /* __BLOCKS__ */ 235