Path: blob/main/crypto/krb5/src/ccapi/common/cci_array_internal.c
39536 views
/* ccapi/common/cci_array_internal.c */1/*2* Copyright 2006, 2007 Massachusetts Institute of Technology.3* All Rights Reserved.4*5* Export of this software from the United States of America may6* require a specific license from the United States Government.7* It is the responsibility of any person or organization contemplating8* export to obtain such a license before exporting.9*10* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and11* distribute this software and its documentation for any purpose and12* without fee is hereby granted, provided that the above copyright13* notice appear in all copies and that both that copyright notice and14* this permission notice appear in supporting documentation, and that15* the name of M.I.T. not be used in advertising or publicity pertaining16* to distribution of the software without specific, written prior17* permission. Furthermore if you modify this software you must label18* your software as modified software and not distribute it in such a19* fashion that it might be confused with the original M.I.T. software.20* M.I.T. makes no representations about the suitability of21* this software for any purpose. It is provided "as is" without express22* or implied warranty.23*/2425#include "cci_common.h"26#include "cci_array_internal.h"2728#ifdef WIN3229#include "k5-platform.h"30#endif3132/* ------------------------------------------------------------------------ */3334struct cci_array_d {35cci_array_object_t *objects;36cc_uint64 count;37cc_uint64 max_count;3839cci_array_object_release_t object_release;40};4142struct cci_array_d cci_array_initializer = { NULL, 0, 0, NULL };4344#define CCI_ARRAY_COUNT_INCREMENT 164546/* ------------------------------------------------------------------------ */4748static cc_int32 cci_array_resize (cci_array_t io_array,49cc_uint64 in_new_count)50{51cc_int32 err = ccNoError;52cc_uint64 new_max_count = 0;5354if (!io_array) { err = cci_check_error (ccErrBadParam); }5556if (!err) {57cc_uint64 old_max_count = io_array->max_count;58new_max_count = io_array->max_count;5960if (in_new_count > old_max_count) {61/* Expand the array */62while (in_new_count > new_max_count) {63new_max_count += CCI_ARRAY_COUNT_INCREMENT;64}6566} else if ((in_new_count + CCI_ARRAY_COUNT_INCREMENT) < old_max_count) {67/* Shrink the array, but never drop below CC_ARRAY_COUNT_INCREMENT */68while ((in_new_count + CCI_ARRAY_COUNT_INCREMENT) < new_max_count &&69(new_max_count > CCI_ARRAY_COUNT_INCREMENT)) {70new_max_count -= CCI_ARRAY_COUNT_INCREMENT;71}72}73}7475if (!err && io_array->max_count != new_max_count) {76cci_array_object_t *objects = io_array->objects;7778if (!objects) {79objects = malloc (new_max_count * sizeof (*objects));80} else {81objects = realloc (objects, new_max_count * sizeof (*objects));82}83if (!objects) { err = cci_check_error (ccErrNoMem); }8485if (!err) {86io_array->objects = objects;87io_array->max_count = new_max_count;88}89}9091return cci_check_error (err);92}9394#ifdef TARGET_OS_MAC95#pragma mark -96#endif9798/* ------------------------------------------------------------------------ */99100cc_int32 cci_array_new (cci_array_t *out_array,101cci_array_object_release_t in_array_object_release)102{103cc_int32 err = ccNoError;104cci_array_t array = NULL;105106if (!out_array) { err = cci_check_error (ccErrBadParam); }107108if (!err) {109array = malloc (sizeof (*array));110if (array) {111*array = cci_array_initializer;112array->object_release = in_array_object_release;113} else {114err = cci_check_error (ccErrNoMem);115}116}117118if (!err) {119*out_array = array;120array = NULL;121}122123cci_array_release (array);124125return cci_check_error (err);126}127128/* ------------------------------------------------------------------------ */129130cc_int32 cci_array_release (cci_array_t io_array)131{132cc_int32 err = ccNoError;133134if (!err && io_array) {135cc_uint64 i;136137if (io_array->object_release) {138for (i = 0; i < io_array->count; i++) {139io_array->object_release (io_array->objects[i]);140}141}142free (io_array->objects);143free (io_array);144}145146return err;147}148149/* ------------------------------------------------------------------------ */150151cc_uint64 cci_array_count (cci_array_t in_array)152{153return in_array ? in_array->count : 0;154}155156/* ------------------------------------------------------------------------ */157158cci_array_object_t cci_array_object_at_index (cci_array_t io_array,159cc_uint64 in_position)160{161if (io_array && in_position < io_array->count) {162return io_array->objects[in_position];163} else {164if (!io_array) {165cci_debug_printf ("%s() got NULL array", __FUNCTION__);166} else {167cci_debug_printf ("%s() got bad index %lld (count = %lld)", __FUNCTION__,168in_position, io_array->count);169}170return NULL;171}172}173174#ifdef TARGET_OS_MAC175#pragma mark -176#endif177178/* ------------------------------------------------------------------------ */179180cc_int32 cci_array_insert (cci_array_t io_array,181cci_array_object_t in_object,182cc_uint64 in_position)183{184cc_int32 err = ccNoError;185186if (!io_array ) { err = cci_check_error (ccErrBadParam); }187if (!in_object) { err = cci_check_error (ccErrBadParam); }188189if (!err) {190/* Don't try to insert past the end and don't overflow the array */191if (in_position > io_array->count || io_array->count == UINT64_MAX) {192err = cci_check_error (ccErrBadParam);193}194}195196if (!err) {197err = cci_array_resize (io_array, io_array->count + 1);198}199200if (!err) {201cc_uint64 move_count = io_array->count - in_position;202203if (move_count > 0) {204memmove (&io_array->objects[in_position + 1], &io_array->objects[in_position],205move_count * sizeof (*io_array->objects));206}207208io_array->objects[in_position] = in_object;209io_array->count++;210}211212return cci_check_error (err);213}214215/* ------------------------------------------------------------------------ */216217cc_int32 cci_array_remove (cci_array_t io_array,218cc_uint64 in_position)219{220cc_int32 err = ccNoError;221222if (!io_array) { err = cci_check_error (ccErrBadParam); }223224if (!err && in_position >= io_array->count) {225err = cci_check_error (ccErrBadParam);226}227228if (!err) {229cc_uint64 move_count = io_array->count - in_position - 1;230cci_array_object_t object = io_array->objects[in_position];231232if (move_count > 0) {233memmove (&io_array->objects[in_position], &io_array->objects[in_position + 1],234move_count * sizeof (*io_array->objects));235}236io_array->count--;237238if (io_array->object_release) { io_array->object_release (object); }239240cci_array_resize (io_array, io_array->count);241}242243return cci_check_error (err);244}245246/* ------------------------------------------------------------------------ */247248cc_int32 cci_array_move (cci_array_t io_array,249cc_uint64 in_position,250cc_uint64 in_new_position,251cc_uint64 *out_real_new_position)252{253cc_int32 err = ccNoError;254255if (!io_array ) { err = cci_check_error (ccErrBadParam); }256if (!out_real_new_position) { err = cci_check_error (ccErrBadParam); }257258if (!err && in_position >= io_array->count) {259err = cci_check_error (ccErrBadParam);260}261262if (!err && in_new_position > io_array->count) {263err = cci_check_error (ccErrBadParam);264}265if (!err) {266cc_uint64 move_from = 0;267cc_uint64 move_to = 0;268cc_uint64 move_count = 0;269cc_uint64 real_new_position = 0;270271if (in_position < in_new_position) {272/* shift right, making an empty space so the273* actual new position is one less in_new_position */274move_from = in_position + 1;275move_to = in_position;276move_count = in_new_position - in_position - 1;277real_new_position = in_new_position - 1;278279} else if (in_position > in_new_position) {280/* shift left */281move_from = in_new_position;282move_to = in_new_position + 1;283move_count = in_position - in_new_position;284real_new_position = in_new_position;285286} else {287real_new_position = in_new_position;288}289290if (move_count > 0) {291cci_array_object_t object = io_array->objects[in_position];292293memmove (&io_array->objects[move_to], &io_array->objects[move_from],294move_count * sizeof (*io_array->objects));295io_array->objects[real_new_position] = object;296}297298*out_real_new_position = real_new_position;299}300301return cci_check_error (err);302}303304/* ------------------------------------------------------------------------ */305306cc_int32 cci_array_push_front (cci_array_t io_array,307cc_uint64 in_position)308{309cc_uint64 real_new_position = 0;310return cci_array_move (io_array, in_position, 0, &real_new_position);311}312313314