| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include <axutil_array_list.h> |
| #include <axutil_utils.h> |
| #include <string.h> |
| |
| struct axutil_array_list |
| { |
| |
| /**The number of elements in this list. */ |
| int size; |
| |
| /**Current capacity of this list. */ |
| int capacity; |
| |
| /** Where the data is stored. */ |
| void **data; |
| }; |
| |
| AXIS2_EXTERN struct axutil_array_list *AXIS2_CALL |
| axutil_array_list_create( |
| const axutil_env_t * env, |
| int capacity) |
| { |
| axutil_array_list_t *array_list = NULL; |
| |
| array_list = AXIS2_MALLOC(env->allocator, sizeof(axutil_array_list_t)); |
| if(!array_list) |
| { |
| AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); |
| AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); |
| return NULL; |
| } |
| |
| array_list->size = 0; |
| array_list->capacity = 0; |
| array_list->data = NULL; |
| |
| /* Check capacity, and set the default if error */ |
| if(capacity <= 0) |
| capacity = AXIS2_ARRAY_LIST_DEFAULT_CAPACITY; |
| array_list->data = AXIS2_MALLOC(env->allocator, sizeof(void *) * capacity); |
| if(!array_list->data) |
| { |
| axutil_array_list_free(array_list, env); |
| AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); |
| AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); |
| return NULL; |
| } |
| array_list->capacity = capacity; |
| |
| return array_list; |
| } |
| |
| AXIS2_EXTERN axis2_status_t AXIS2_CALL |
| axutil_array_list_ensure_capacity( |
| struct axutil_array_list * array_list, |
| const axutil_env_t * env, |
| int min_capacity) |
| { |
| AXIS2_PARAM_CHECK(env->error, array_list, AXIS2_FAILURE); |
| if(min_capacity > array_list->capacity) |
| { |
| int new_capacity = (array_list->capacity * 2 > min_capacity) ? (array_list->capacity * 2) |
| : min_capacity; |
| void **data = (void **)AXIS2_MALLOC(env->allocator, sizeof(void *) * new_capacity); |
| if(!data) |
| { |
| AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); |
| AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); |
| return AXIS2_FAILURE; |
| } |
| memcpy(data, array_list->data, sizeof(void *) * array_list->capacity); |
| |
| AXIS2_FREE(env->allocator, array_list->data); |
| |
| array_list->data = data; |
| array_list->capacity = new_capacity; |
| } |
| return AXIS2_SUCCESS; |
| } |
| |
| AXIS2_EXTERN int AXIS2_CALL |
| axutil_array_list_size( |
| struct axutil_array_list *array_list, |
| const axutil_env_t * env) |
| { |
| /* Don't use AXIS2_PARAM_CHECK to verify array_list, as it clobbers |
| env->error->status_code on no error destroying the information |
| therein that an error has already occurred. */ |
| if(!array_list) |
| return 0; |
| return array_list->size; |
| } |
| |
| AXIS2_EXTERN axis2_bool_t AXIS2_CALL |
| axutil_array_list_is_empty( |
| struct axutil_array_list * array_list, |
| const axutil_env_t * env) |
| { |
| AXIS2_PARAM_CHECK(env->error, array_list, AXIS2_FAILURE); |
| return array_list->size == 0; |
| } |
| |
| AXIS2_EXTERN axis2_bool_t AXIS2_CALL |
| axutil_array_list_contains( |
| struct axutil_array_list * array_list, |
| const axutil_env_t * env, |
| void *e) |
| { |
| AXIS2_PARAM_CHECK(env->error, array_list, AXIS2_FAILURE); |
| return axutil_array_list_index_of(array_list, env, e) != -1; |
| } |
| |
| AXIS2_EXTERN int AXIS2_CALL |
| axutil_array_list_index_of( |
| struct axutil_array_list *array_list, |
| const axutil_env_t * env, |
| void *e) |
| { |
| int i = 0; |
| |
| AXIS2_PARAM_CHECK(env->error, array_list, AXIS2_FAILURE); |
| for(i = 0; i < array_list->size; i++) |
| if(e == array_list->data[i]) |
| return i; |
| return -1; |
| } |
| |
| AXIS2_EXTERN void *AXIS2_CALL |
| axutil_array_list_get( |
| struct axutil_array_list *array_list, |
| const axutil_env_t * env, |
| int index) |
| { |
| /* Don't use AXIS2_PARAM_CHECK to verify array_list, as it clobbers |
| env->error->status_code on no error destroying the information |
| therein that an error has already occurred. */ |
| if(axutil_array_list_check_bound_exclusive(array_list, env, index)) |
| return array_list->data[index]; |
| else |
| return NULL; |
| } |
| |
| AXIS2_EXTERN void *AXIS2_CALL |
| axutil_array_list_set( |
| struct axutil_array_list *array_list, |
| const axutil_env_t * env, |
| int index, |
| void *e) |
| { |
| void *result = NULL; |
| |
| AXIS2_PARAM_CHECK(env->error, array_list, NULL); |
| if(axutil_array_list_check_bound_exclusive(array_list, env, index)) |
| { |
| result = array_list->data[index]; |
| array_list->data[index] = e; |
| } |
| return result; |
| } |
| |
| AXIS2_EXTERN axis2_status_t AXIS2_CALL |
| axutil_array_list_add( |
| struct axutil_array_list * array_list, |
| const axutil_env_t * env, |
| const void *e) |
| { |
| AXIS2_PARAM_CHECK(env->error, array_list, AXIS2_FAILURE); |
| if(array_list->size == array_list->capacity) |
| if(axutil_array_list_ensure_capacity(array_list, env, array_list->size + 1) |
| != AXIS2_SUCCESS) |
| return AXIS2_FAILURE; |
| array_list->data[array_list->size++] = (void *)e; |
| return AXIS2_SUCCESS; |
| } |
| |
| AXIS2_EXTERN axis2_status_t AXIS2_CALL |
| axutil_array_list_add_at( |
| struct axutil_array_list * array_list, |
| const axutil_env_t * env, |
| const int index, |
| const void *e) |
| { |
| int i = 0; |
| AXIS2_PARAM_CHECK(env->error, array_list, AXIS2_FAILURE); |
| |
| if(!axutil_array_list_check_bound_inclusive(array_list, env, index)) |
| return AXIS2_FAILURE; |
| if(array_list->size == array_list->capacity) |
| { |
| if(axutil_array_list_ensure_capacity(array_list, env, array_list->size + 1) |
| != AXIS2_SUCCESS) |
| return AXIS2_FAILURE; |
| } |
| if(index != array_list->size) |
| { |
| for(i = array_list->size; i > index; i--) |
| array_list->data[i] = array_list->data[i - 1]; |
| } |
| array_list->data[index] = (void *)e; |
| array_list->size++; |
| return AXIS2_SUCCESS; |
| } |
| |
| AXIS2_EXTERN void *AXIS2_CALL |
| axutil_array_list_remove( |
| struct axutil_array_list *array_list, |
| const axutil_env_t * env, |
| int index) |
| { |
| void *result = NULL; |
| int i = 0; |
| AXIS2_PARAM_CHECK(env->error, array_list, NULL); |
| |
| if(axutil_array_list_check_bound_exclusive(array_list, env, index)) |
| { |
| result = array_list->data[index]; |
| for(i = index; i < array_list->size - 1; i++) |
| array_list->data[i] = array_list->data[i + 1]; |
| array_list->size--; |
| } |
| |
| return result; |
| } |
| |
| AXIS2_EXTERN axis2_bool_t AXIS2_CALL |
| axutil_array_list_check_bound_inclusive( |
| struct axutil_array_list * array_list, |
| const axutil_env_t * env, |
| int index) |
| { |
| /* Don't use AXIS2_PARAM_CHECK to verify array_list, as it clobbers |
| env->error->status_code on no error destroying the information |
| therein that an error has already occurred. */ |
| if(!array_list || index < 0 || index > array_list->size) |
| { |
| AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INDEX_OUT_OF_BOUNDS, AXIS2_FAILURE); |
| return AXIS2_FALSE; |
| } |
| return AXIS2_TRUE; |
| } |
| |
| AXIS2_EXTERN axis2_bool_t AXIS2_CALL |
| axutil_array_list_check_bound_exclusive( |
| struct axutil_array_list * array_list, |
| const axutil_env_t * env, |
| int index) |
| { |
| /* Don't use AXIS2_PARAM_CHECK to verify array_list, as it clobbers |
| env->error->status_code on no error destroying the information |
| therein that an error has already occurred. */ |
| if(!array_list || index < 0 || index >= array_list->size) |
| { |
| AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INDEX_OUT_OF_BOUNDS, AXIS2_FAILURE); |
| return AXIS2_FALSE; |
| } |
| return AXIS2_TRUE; |
| } |
| |
| AXIS2_EXTERN void AXIS2_CALL |
| axutil_array_list_free( |
| struct axutil_array_list *array_list, |
| const axutil_env_t * env) |
| { |
| AXIS2_PARAM_CHECK_VOID(env->error, array_list); |
| |
| if(array_list->data) |
| { |
| AXIS2_FREE(env->allocator, array_list->data); |
| } |
| AXIS2_FREE(env->allocator, array_list); |
| return; |
| } |
| |
| AXIS2_EXTERN void AXIS2_CALL |
| axutil_array_list_free_void_arg( |
| void *array_list, |
| const axutil_env_t * env) |
| { |
| axutil_array_list_t *array_list_l = NULL; |
| |
| AXIS2_PARAM_CHECK_VOID(env->error, array_list); |
| |
| array_list_l = (axutil_array_list_t *)array_list; |
| axutil_array_list_free(array_list_l, env); |
| return; |
| } |
| |