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 42 struct heim_array_data { 43 size_t len; 44 heim_object_t *val; 45 }; 46 47 static void 48 array_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 57 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 73 heim_array_t 74 heim_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 94 heim_tid_t 95 heim_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 109 int 110 heim_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 131 void 132 heim_array_iterate_f(heim_array_t array, heim_array_iterator_f_t fn, void *ctx) 133 { 134 size_t n; 135 for (n = 0; n < array->len; n++) 136 fn(array->val[n], ctx); 137 } 138 139 #ifdef __BLOCKS__ 140 /** 141 * Iterate over all objects in array 142 * 143 * @param array array to iterate over 144 * @param fn block to call on each object 145 */ 146 147 void 148 heim_array_iterate(heim_array_t array, void (^fn)(heim_object_t)) 149 { 150 size_t n; 151 for (n = 0; n < array->len; n++) 152 fn(array->val[n]); 153 } 154 #endif 155 156 /** 157 * Get length of array 158 * 159 * @param array array to get length of 160 * 161 * @return length of array 162 */ 163 164 size_t 165 heim_array_get_length(heim_array_t array) 166 { 167 return array->len; 168 } 169 170 /** 171 * Copy value of array 172 * 173 * @param array array copy object from 174 * @param idx index of object, 0 based, must be smaller then 175 * heim_array_get_length() 176 * 177 * @return a retained copy of the object 178 */ 179 180 heim_object_t 181 heim_array_copy_value(heim_array_t array, size_t idx) 182 { 183 if (idx >= array->len) 184 heim_abort("index too large"); 185 return heim_retain(array->val[idx]); 186 } 187 188 /** 189 * Delete value at idx 190 * 191 * @param array the array to modify 192 * @param idx the key to delete 193 */ 194 195 void 196 heim_array_delete_value(heim_array_t array, size_t idx) 197 { 198 heim_object_t obj; 199 if (idx >= array->len) 200 heim_abort("index too large"); 201 obj = array->val[idx]; 202 203 array->len--; 204 205 if (idx < array->len) 206 memmove(&array->val[idx], &array->val[idx + 1], 207 (array->len - idx) * sizeof(array->val[0])); 208 209 heim_release(obj); 210 } 211 212 #ifdef __BLOCKS__ 213 /** 214 * Get value at idx 215 * 216 * @param array the array to modify 217 * @param idx the key to delete 218 */ 219 220 void 221 heim_array_filter(heim_array_t array, int (^block)(heim_object_t)) 222 { 223 size_t n = 0; 224 225 while (n < array->len) { 226 if (block(array->val[n])) { 227 heim_array_delete_value(array, n); 228 } else { 229 n++; 230 } 231 } 232 } 233 234 #endif /* __BLOCKS__ */ 235