blob: a40ecf9bb7c5a94b24e3bb95fa400f9d31c2dd1f [file] [log] [blame]
/*
* 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;
}