xref: /src/crypto/heimdal/base/array.c (revision 6a068746777241722b2b32c5d0bc443a2a64d80b)
17c450da7SStanislav Sedov /*
27c450da7SStanislav Sedov  * Copyright (c) 2010 Kungliga Tekniska Högskolan
37c450da7SStanislav Sedov  * (Royal Institute of Technology, Stockholm, Sweden).
47c450da7SStanislav Sedov  * All rights reserved.
57c450da7SStanislav Sedov  *
67c450da7SStanislav Sedov  * Portions Copyright (c) 2010 Apple Inc. All rights reserved.
77c450da7SStanislav Sedov  *
87c450da7SStanislav Sedov  * Redistribution and use in source and binary forms, with or without
97c450da7SStanislav Sedov  * modification, are permitted provided that the following conditions
107c450da7SStanislav Sedov  * are met:
117c450da7SStanislav Sedov  *
127c450da7SStanislav Sedov  * 1. Redistributions of source code must retain the above copyright
137c450da7SStanislav Sedov  *    notice, this list of conditions and the following disclaimer.
147c450da7SStanislav Sedov  *
157c450da7SStanislav Sedov  * 2. Redistributions in binary form must reproduce the above copyright
167c450da7SStanislav Sedov  *    notice, this list of conditions and the following disclaimer in the
177c450da7SStanislav Sedov  *    documentation and/or other materials provided with the distribution.
187c450da7SStanislav Sedov  *
197c450da7SStanislav Sedov  * 3. Neither the name of the Institute nor the names of its contributors
207c450da7SStanislav Sedov  *    may be used to endorse or promote products derived from this software
217c450da7SStanislav Sedov  *    without specific prior written permission.
227c450da7SStanislav Sedov  *
237c450da7SStanislav Sedov  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
247c450da7SStanislav Sedov  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
257c450da7SStanislav Sedov  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
267c450da7SStanislav Sedov  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
277c450da7SStanislav Sedov  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
287c450da7SStanislav Sedov  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
297c450da7SStanislav Sedov  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
307c450da7SStanislav Sedov  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
317c450da7SStanislav Sedov  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
327c450da7SStanislav Sedov  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
337c450da7SStanislav Sedov  * SUCH DAMAGE.
347c450da7SStanislav Sedov  */
357c450da7SStanislav Sedov 
367c450da7SStanislav Sedov #include "baselocl.h"
377c450da7SStanislav Sedov 
387c450da7SStanislav Sedov /*
397c450da7SStanislav Sedov  *
407c450da7SStanislav Sedov  */
417c450da7SStanislav Sedov 
427c450da7SStanislav Sedov struct heim_array_data {
437c450da7SStanislav Sedov     size_t len;
447c450da7SStanislav Sedov     heim_object_t *val;
457c450da7SStanislav Sedov };
467c450da7SStanislav Sedov 
477c450da7SStanislav Sedov static void
array_dealloc(heim_object_t ptr)487c450da7SStanislav Sedov array_dealloc(heim_object_t ptr)
497c450da7SStanislav Sedov {
507c450da7SStanislav Sedov     heim_array_t array = ptr;
517c450da7SStanislav Sedov     size_t n;
527c450da7SStanislav Sedov     for (n = 0; n < array->len; n++)
537c450da7SStanislav Sedov 	heim_release(array->val[n]);
547c450da7SStanislav Sedov     free(array->val);
557c450da7SStanislav Sedov }
567c450da7SStanislav Sedov 
577c450da7SStanislav Sedov struct heim_type_data array_object = {
587c450da7SStanislav Sedov     HEIM_TID_ARRAY,
597c450da7SStanislav Sedov     "dict-object",
607c450da7SStanislav Sedov     NULL,
617c450da7SStanislav Sedov     array_dealloc,
627c450da7SStanislav Sedov     NULL,
637c450da7SStanislav Sedov     NULL,
647c450da7SStanislav Sedov     NULL
657c450da7SStanislav Sedov };
667c450da7SStanislav Sedov 
677c450da7SStanislav Sedov /**
687c450da7SStanislav Sedov  * Allocate an array
697c450da7SStanislav Sedov  *
707c450da7SStanislav Sedov  * @return A new allocated array, free with heim_release()
717c450da7SStanislav Sedov  */
727c450da7SStanislav Sedov 
737c450da7SStanislav Sedov heim_array_t
heim_array_create(void)747c450da7SStanislav Sedov heim_array_create(void)
757c450da7SStanislav Sedov {
767c450da7SStanislav Sedov     heim_array_t array;
777c450da7SStanislav Sedov 
787c450da7SStanislav Sedov     array = _heim_alloc_object(&array_object, sizeof(*array));
797c450da7SStanislav Sedov     if (array == NULL)
807c450da7SStanislav Sedov 	return NULL;
817c450da7SStanislav Sedov 
827c450da7SStanislav Sedov     array->val = NULL;
837c450da7SStanislav Sedov     array->len = 0;
847c450da7SStanislav Sedov 
857c450da7SStanislav Sedov     return array;
867c450da7SStanislav Sedov }
877c450da7SStanislav Sedov 
887c450da7SStanislav Sedov /**
897c450da7SStanislav Sedov  * Get type id of an dict
907c450da7SStanislav Sedov  *
917c450da7SStanislav Sedov  * @return the type id
927c450da7SStanislav Sedov  */
937c450da7SStanislav Sedov 
947c450da7SStanislav Sedov heim_tid_t
heim_array_get_type_id(void)957c450da7SStanislav Sedov heim_array_get_type_id(void)
967c450da7SStanislav Sedov {
977c450da7SStanislav Sedov     return HEIM_TID_ARRAY;
987c450da7SStanislav Sedov }
997c450da7SStanislav Sedov 
1007c450da7SStanislav Sedov /**
1017c450da7SStanislav Sedov  * Append object to array
1027c450da7SStanislav Sedov  *
1037c450da7SStanislav Sedov  * @param array array to add too
1047c450da7SStanislav Sedov  * @param object the object to add
1057c450da7SStanislav Sedov  *
1067c450da7SStanislav Sedov  * @return zero if added, errno otherwise
1077c450da7SStanislav Sedov  */
1087c450da7SStanislav Sedov 
1097c450da7SStanislav Sedov int
heim_array_append_value(heim_array_t array,heim_object_t object)1107c450da7SStanislav Sedov heim_array_append_value(heim_array_t array, heim_object_t object)
1117c450da7SStanislav Sedov {
1127c450da7SStanislav Sedov     heim_object_t *ptr;
1137c450da7SStanislav Sedov 
1147c450da7SStanislav Sedov     ptr = realloc(array->val, (array->len + 1) * sizeof(array->val[0]));
1157c450da7SStanislav Sedov     if (ptr == NULL)
1167c450da7SStanislav Sedov 	return ENOMEM;
1177c450da7SStanislav Sedov     array->val = ptr;
1187c450da7SStanislav Sedov     array->val[array->len++] = heim_retain(object);
1197c450da7SStanislav Sedov 
1207c450da7SStanislav Sedov     return 0;
1217c450da7SStanislav Sedov }
1227c450da7SStanislav Sedov 
1237c450da7SStanislav Sedov /**
1247c450da7SStanislav Sedov  * Iterate over all objects in array
1257c450da7SStanislav Sedov  *
1267c450da7SStanislav Sedov  * @param array array to iterate over
1277c450da7SStanislav Sedov  * @param fn function to call on each object
1287c450da7SStanislav Sedov  * @param ctx context passed to fn
1297c450da7SStanislav Sedov  */
1307c450da7SStanislav Sedov 
1317c450da7SStanislav Sedov void
heim_array_iterate_f(heim_array_t array,heim_array_iterator_f_t fn,void * ctx)1327c450da7SStanislav Sedov heim_array_iterate_f(heim_array_t array, heim_array_iterator_f_t fn, void *ctx)
1337c450da7SStanislav Sedov {
1347c450da7SStanislav Sedov     size_t n;
1357c450da7SStanislav Sedov     for (n = 0; n < array->len; n++)
1367c450da7SStanislav Sedov 	fn(array->val[n], ctx);
1377c450da7SStanislav Sedov }
1387c450da7SStanislav Sedov 
1397c450da7SStanislav Sedov #ifdef __BLOCKS__
1407c450da7SStanislav Sedov /**
1417c450da7SStanislav Sedov  * Iterate over all objects in array
1427c450da7SStanislav Sedov  *
1437c450da7SStanislav Sedov  * @param array array to iterate over
1447c450da7SStanislav Sedov  * @param fn block to call on each object
1457c450da7SStanislav Sedov  */
1467c450da7SStanislav Sedov 
1477c450da7SStanislav Sedov void
1487c450da7SStanislav Sedov heim_array_iterate(heim_array_t array, void (^fn)(heim_object_t))
1497c450da7SStanislav Sedov {
1507c450da7SStanislav Sedov     size_t n;
1517c450da7SStanislav Sedov     for (n = 0; n < array->len; n++)
1527c450da7SStanislav Sedov 	fn(array->val[n]);
1537c450da7SStanislav Sedov }
1547c450da7SStanislav Sedov #endif
1557c450da7SStanislav Sedov 
1567c450da7SStanislav Sedov /**
1577c450da7SStanislav Sedov  * Get length of array
1587c450da7SStanislav Sedov  *
1597c450da7SStanislav Sedov  * @param array array to get length of
1607c450da7SStanislav Sedov  *
1617c450da7SStanislav Sedov  * @return length of array
1627c450da7SStanislav Sedov  */
1637c450da7SStanislav Sedov 
1647c450da7SStanislav Sedov size_t
heim_array_get_length(heim_array_t array)1657c450da7SStanislav Sedov heim_array_get_length(heim_array_t array)
1667c450da7SStanislav Sedov {
1677c450da7SStanislav Sedov     return array->len;
1687c450da7SStanislav Sedov }
1697c450da7SStanislav Sedov 
1707c450da7SStanislav Sedov /**
1717c450da7SStanislav Sedov  * Copy value of array
1727c450da7SStanislav Sedov  *
1737c450da7SStanislav Sedov  * @param array array copy object from
1747c450da7SStanislav Sedov  * @param idx index of object, 0 based, must be smaller then
1757c450da7SStanislav Sedov  *        heim_array_get_length()
1767c450da7SStanislav Sedov  *
1777c450da7SStanislav Sedov  * @return a retained copy of the object
1787c450da7SStanislav Sedov  */
1797c450da7SStanislav Sedov 
1807c450da7SStanislav Sedov heim_object_t
heim_array_copy_value(heim_array_t array,size_t idx)1817c450da7SStanislav Sedov heim_array_copy_value(heim_array_t array, size_t idx)
1827c450da7SStanislav Sedov {
1837c450da7SStanislav Sedov     if (idx >= array->len)
1847c450da7SStanislav Sedov 	heim_abort("index too large");
1857c450da7SStanislav Sedov     return heim_retain(array->val[idx]);
1867c450da7SStanislav Sedov }
1877c450da7SStanislav Sedov 
1887c450da7SStanislav Sedov /**
1897c450da7SStanislav Sedov  * Delete value at idx
1907c450da7SStanislav Sedov  *
1917c450da7SStanislav Sedov  * @param array the array to modify
1927c450da7SStanislav Sedov  * @param idx the key to delete
1937c450da7SStanislav Sedov  */
1947c450da7SStanislav Sedov 
1957c450da7SStanislav Sedov void
heim_array_delete_value(heim_array_t array,size_t idx)1967c450da7SStanislav Sedov heim_array_delete_value(heim_array_t array, size_t idx)
1977c450da7SStanislav Sedov {
1987c450da7SStanislav Sedov     heim_object_t obj;
1997c450da7SStanislav Sedov     if (idx >= array->len)
2007c450da7SStanislav Sedov 	heim_abort("index too large");
2017c450da7SStanislav Sedov     obj = array->val[idx];
2027c450da7SStanislav Sedov 
2037c450da7SStanislav Sedov     array->len--;
2047c450da7SStanislav Sedov 
2057c450da7SStanislav Sedov     if (idx < array->len)
2067c450da7SStanislav Sedov 	memmove(&array->val[idx], &array->val[idx + 1],
2077c450da7SStanislav Sedov 		(array->len - idx) * sizeof(array->val[0]));
2087c450da7SStanislav Sedov 
2097c450da7SStanislav Sedov     heim_release(obj);
2107c450da7SStanislav Sedov }
2117c450da7SStanislav Sedov 
2127c450da7SStanislav Sedov #ifdef __BLOCKS__
2137c450da7SStanislav Sedov /**
2147c450da7SStanislav Sedov  * Get value at idx
2157c450da7SStanislav Sedov  *
2167c450da7SStanislav Sedov  * @param array the array to modify
2177c450da7SStanislav Sedov  * @param idx the key to delete
2187c450da7SStanislav Sedov  */
2197c450da7SStanislav Sedov 
2207c450da7SStanislav Sedov void
221813b7899SStanislav Sedov heim_array_filter(heim_array_t array, int (^block)(heim_object_t))
2227c450da7SStanislav Sedov {
2237c450da7SStanislav Sedov     size_t n = 0;
2247c450da7SStanislav Sedov 
2257c450da7SStanislav Sedov     while (n < array->len) {
2267c450da7SStanislav Sedov 	if (block(array->val[n])) {
2277c450da7SStanislav Sedov 	    heim_array_delete_value(array, n);
2287c450da7SStanislav Sedov 	} else {
2297c450da7SStanislav Sedov 	    n++;
2307c450da7SStanislav Sedov 	}
2317c450da7SStanislav Sedov     }
2327c450da7SStanislav Sedov }
2337c450da7SStanislav Sedov 
2347c450da7SStanislav Sedov #endif /* __BLOCKS__ */
235