/*----------------------------------------darray.c-------------------------*/#include "darray.h"#define ARRAY_HEAD 0#define ARRAY_TAIL -1#define MIN_PRE_ALLOCATE_NR 10struct _DArray{ void** data; size_t size; size_t alloc_size; void* data_destroy_ctx; DataDestroyFunc data_destroy; };DArray* darray_create(DataDestroyFunc data_destroy, void* ctx){ DArray* this = (DArray*)malloc(sizeof(DArray)); if(NULL == this) { return NULL; } this->data = NULL; this->size = 0; this->alloc_size = 0; this->data_destroy = data_destroy; this->data_destroy_ctx = ctx; return this;}static Ret darray_expand(DArray* this, size_t need){ return_val_if_fail(this != NULL, RET_INVALID_PARAMETER); if(this->size + need > this->alloc_size) { size_t alloc_size = this->alloc_size + (this->alloc_size >> 1) + MIN_PRE_ALLOCATE_NR; void** data = (void **)realloc(this->data, sizeof(void*) * alloc_size); if(NULL != data) { this->data = data; this->alloc_size = alloc_size; } } return ((this->size + need) <= this->alloc_size) ? RET_OK : RET_FAIL; }Ret darray_insert(DArray* this, size_t index, void* data){ Ret ret = RET_OOM; size_t cursor = index; return_val_if_fail(this != NULL, RET_INVALID_PARAMETER); cursor = (cursor < this->size) ? cursor : this->size; if(darray_expand(this, 1) == RET_OK) { size_t i = 0; for(i = this->size; i > cursor; i--) { this->data[i] = this->data[i-1]; } this->data[cursor] = data; this->size++; ret = RET_OK; } return ret;}Ret darray_prepend(DArray* this, void* data){ return (RET_OK == darray_insert(this, ARRAY_HEAD, data)) ? RET_OK : RET_FAIL;}Ret darray_append(DArray* this, void* data){ return (RET_OK == darray_insert(this, ARRAY_TAIL, data)) ? RET_OK : RET_FAIL;}static void darray_destroy_data(DArray* this, void* data){ if(this->data_destroy != NULL) { this->data_destroy(this->data_destroy_ctx, data); } return;}static Ret darray_shrink(DArray* this){ Ret ret = RET_OK; return_val_if_fail(this != NULL, RET_INVALID_PARAMETER); if((this->size < (this->alloc_size >> 1)) && (this->size > MIN_PRE_ALLOCATE_NR)) { size_t alloc_size = this->size + (this->size >> 1); void** data = (void ** )realloc(this->data, sizeof(void *) * alloc_size); if(data != NULL) { this->data = data; this->alloc_size = alloc_size; } else { ret = RET_OOM; } } return ret;}Ret darray_delete(DArray* this, size_t index){ size_t i = 0; Ret ret = RET_OK; return_val_if_fail(this != NULL && this->size > index, RET_INVALID_PARAMETER); darray_destroy_data(this, this->data[index]); for(i = index; (i+1) < this->size; i++) { this->data[i] = this->data[i+1]; } this->size--; ret = darray_shrink(this); return ret; }Ret darray_get_by_index(DArray* this, size_t index, void** data){ return_val_if_fail(this != NULL && this->size > index, RET_INVALID_PARAMETER); *data = this->data[index]; return RET_OK;}Ret darray_set_by_index(DArray* this, size_t index, void* data){ return_val_if_fail(this != NULL && this->size > index, RET_INVALID_PARAMETER); this->data[index] = data; return RET_OK;}int darray_find(DArray* this, DataCompareFunc cmp, void* ctx){ size_t i = 0; return_val_if_fail(this != NULL, RET_INVALID_PARAMETER); for(; i < this->size; i++) { if(0 == cmp(ctx, this->data[i])) { return i; } } return -1; }size_t darray_length(DArray* this){ return this->size;}Ret darray_foreach(DArray* this, DataVisitFunc visit, void* ctx){ size_t i = 0; return_val_if_fail(this != NULL, RET_INVALID_PARAMETER); for(i = 0; i < this->size; i++) { visit(ctx, this->data[i]); } return RET_OK;}Ret darray_sort(DArray* this, DataSortFunc sort, DataCompareFunc cmp){ return_val_if_fail(this != NULL, RET_INVALID_PARAMETER); return(sort(this->data, this->size, cmp));}void darray_destroy(DArray* this){ return_void_if_fail(this != NULL); if(this->data_destroy != NULL) { size_t i = 0; for(; i < this->size; i++) { if(this->data[i] != NULL) { this->data_destroy(this->data_destroy_ctx, this->data[i]); this->data[i] = NULL; } } } free(this); }