1/* 2 * Copyright (c) 2010 Kungliga Tekniska Högskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Portions Copyright (c) 2010 Apple Inc. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36#include "baselocl.h" 37 38/* 39 * 40 */ 41 42struct heim_array_data { 43 size_t len; 44 heim_object_t *val; 45}; 46 47static void 48array_dealloc(heim_object_t ptr) 49{ 50 heim_array_t array = ptr; 51 size_t n; 52 for (n = 0; n < array->len; n++) 53 heim_release(array->val[n]); 54 free(array->val); 55} 56 57static struct heim_type_data array_object = { 58 HEIM_TID_ARRAY, 59 "dict-object", 60 NULL, 61 array_dealloc, 62 NULL, 63 NULL, 64 NULL 65}; 66 67/** 68 * Allocate an array 69 * 70 * @return A new allocated array, free with heim_release() 71 */ 72 73heim_array_t 74heim_array_create(void) 75{ 76 heim_array_t array; 77 78 array = _heim_alloc_object(&array_object, sizeof(*array)); 79 if (array == NULL) 80 return NULL; 81 82 array->val = NULL; 83 array->len = 0; 84 85 return array; 86} 87 88/** 89 * Get type id of an dict 90 * 91 * @return the type id 92 */ 93 94heim_tid_t 95heim_array_get_type_id(void) 96{ 97 return HEIM_TID_ARRAY; 98} 99 100/** 101 * Append object to array 102 * 103 * @param array array to add too 104 * @param object the object to add 105 * 106 * @return zero if added, errno otherwise 107 */ 108 109int 110heim_array_append_value(heim_array_t array, heim_object_t object) 111{ 112 heim_object_t *ptr; 113 114 ptr = realloc(array->val, (array->len + 1) * sizeof(array->val[0])); 115 if (ptr == NULL) 116 return ENOMEM; 117 array->val = ptr; 118 array->val[array->len++] = heim_retain(object); 119 120 return 0; 121} 122 123/** 124 * Iterate over all objects in array 125 * 126 * @param array array to iterate over 127 * @param fn function to call on each object 128 * @param ctx context passed to fn 129 */ 130 131void 132heim_array_iterate_f(heim_array_t array, 133 void *ctx, 134 heim_array_iterator_f_t fn) 135{ 136 int stop = 0; 137 size_t n; 138 139 for (n = 0; n < array->len && !stop; n++) 140 fn(array->val[n], &stop, ctx); 141} 142 143#ifdef __BLOCKS__ 144/** 145 * Iterate over all objects in array 146 * 147 * @param array array to iterate over 148 * @param fn block to call on each object 149 */ 150 151void 152heim_array_iterate(heim_array_t array, heim_array_iterator_t fn) 153{ 154 int stop = 0; 155 size_t n; 156 157 for (n = 0; n < array->len && !stop; n++) 158 fn(array->val[n], &stop); 159} 160#endif 161 162/** 163 * Get length of array 164 * 165 * @param array array to get length of 166 * 167 * @return length of array 168 */ 169 170size_t 171heim_array_get_length(heim_array_t array) 172{ 173 return array->len; 174} 175 176/** 177 * Copy value of array 178 * 179 * @param array array copy object from 180 * @param idx index of object, 0 based, must be smaller then 181 * heim_array_get_length() 182 * 183 * @return a retained copy of the object 184 */ 185 186heim_object_t 187heim_array_copy_value(heim_array_t array, size_t idx) 188{ 189 if (idx >= array->len) 190 heim_abort("index too large"); 191 return heim_retain(array->val[idx]); 192} 193 194/** 195 * Delete value at idx 196 * 197 * @param array the array to modify 198 * @param idx the key to delete 199 */ 200 201void 202heim_array_delete_value(heim_array_t array, size_t idx) 203{ 204 heim_object_t obj; 205 if (idx >= array->len) 206 heim_abort("index too large"); 207 obj = array->val[idx]; 208 209 array->len--; 210 211 if (idx < array->len) 212 memmove(&array->val[idx], &array->val[idx + 1], 213 (array->len - idx) * sizeof(array->val[0])); 214 215 heim_release(obj); 216} 217 218#ifdef __BLOCKS__ 219/** 220 * Get value at idx 221 * 222 * @param array the array to modify 223 * @param idx the key to delete 224 */ 225 226void 227heim_array_filter(heim_array_t array, int (^block)(heim_object_t)) 228{ 229 size_t n = 0; 230 231 while (n < array->len) { 232 if (block(array->val[n])) { 233 heim_array_delete_value(array, n); 234 } else { 235 n++; 236 } 237 } 238} 239 240#endif /* __BLOCKS__ */ 241