forked from lei.chen/myxce
169 lines
2.5 KiB
C
169 lines
2.5 KiB
C
#include <errno.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "utils.h"
|
|
#include "xlist.h"
|
|
|
|
int xlist_init(xlist_t* l, int delta)
|
|
{
|
|
if ((l == NULL) || (delta <= 0)) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
l->delta = delta;
|
|
l->data = NULL;
|
|
l->count = 0;
|
|
l->caps = 0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int xlist_ensure(xlist_t* l)
|
|
{
|
|
void* p;
|
|
int nc, i;
|
|
|
|
if (l->count < l->caps) {
|
|
return 1;
|
|
}
|
|
|
|
nc = l->caps + l->delta;
|
|
p = (void*)realloc(l->data, nc * sizeof(void*));
|
|
if (p == NULL) {
|
|
return -ENOMEM;
|
|
}
|
|
|
|
l->data = p;
|
|
for (i = l->caps; i < nc; i++) {
|
|
l->data[i] = NULL;
|
|
}
|
|
|
|
l->caps = nc;
|
|
|
|
return 1;
|
|
}
|
|
|
|
int xlist_store(xlist_t* l, void* data)
|
|
{
|
|
int rc;
|
|
int idx;
|
|
|
|
if (l == NULL) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
rc = xlist_ensure(l);
|
|
if (rc < 0) {
|
|
return rc;
|
|
}
|
|
|
|
idx = l->count;
|
|
l->data[idx] = data;
|
|
l->count++;
|
|
|
|
return idx;
|
|
}
|
|
|
|
void* xlist_get(xlist_t* l, int idx)
|
|
{
|
|
if ((l == NULL) || (idx < 0)) {
|
|
errno = EINVAL;
|
|
return NULL;
|
|
}
|
|
|
|
if (idx >= l->caps) {
|
|
errno = 0;
|
|
return NULL;
|
|
}
|
|
|
|
return (void*)l->data[idx];
|
|
}
|
|
|
|
void xlist_clear(xlist_t* l)
|
|
{
|
|
if (l == NULL) {
|
|
return;
|
|
}
|
|
|
|
l->count = 0;
|
|
}
|
|
|
|
int xlist_iter(xlist_t* l, xlist_iter_fn_t fn, void* data)
|
|
{
|
|
int i;
|
|
|
|
if ((l == NULL) || (fn == NULL)) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
for (i = 0; i < l->count; i++) {
|
|
(*fn)((void*)l->data[i], data);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int xlist_del(xlist_t* l, void* data)
|
|
{
|
|
int i, j;
|
|
|
|
if (l == NULL) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
j = -1;
|
|
i = 0;
|
|
while (i < l->count) {
|
|
if (l->data[i] == data) {
|
|
for (j = i + 1; j < l->count; j++) {
|
|
l->data[j - 1] = l->data[j];
|
|
}
|
|
|
|
l->count--;
|
|
} else {
|
|
i++;
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
void* xlist_find(xlist_t* l, xlist_find_fn_t fn, ...)
|
|
{
|
|
int i;
|
|
va_list ap;
|
|
void* it = NULL;
|
|
|
|
if ((l == NULL) || (fn == NULL)) {
|
|
errno = EINVAL;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
va_start(ap, fn);
|
|
for (i = 0; i < l->count; i++) {
|
|
va_list ap1;
|
|
int rc;
|
|
|
|
va_copy(ap1, ap);
|
|
rc = fn((void*)l->data[i], ap1);
|
|
va_end(ap1);
|
|
|
|
if (rc) {
|
|
it = (void*)l->data[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
return it;
|
|
}
|
|
|
|
void xlist_fini(xlist_t* l)
|
|
{
|
|
if (l == NULL) {
|
|
return;
|
|
}
|
|
|
|
FREEUP(l->data);
|
|
return;
|
|
}
|