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