/* This software is licensed by the MIT License, see LICENSE file */ /* Copyright © 2022 Gregory Lirent */ #include "include.h" static void lnode_cut(list_t* s, lnode_t* cur) { vnode_free(&cur->node, cur->type); if (!is_null(cur->prev)) { cur->prev->next = cur->next; } else s->first = cur->next; if (!is_null(cur->next)) { cur->next->prev = cur->prev; } else s->last = cur->prev; free(cur); } /*#####################################################################################################################*/ int libcdsb_list_get(vtype_list* x, ssize_t i, void* _, list_access_callback callback, bool cut) { ldir_t dir; lnode_t* c; size_t n; if (i < 0) { n = ~i; dir = LD_PREV; } else { n = i; dir = LD_NEXT; } c = ldir_dir((lnode_t*)x, dir); while (n && !is_null(c)) { c = ldir_dir(c, dir); --n; } if (n || is_null(c)) return -1; i = (callback) ? callback(vnode_peek(&c->node, c->type), i, c->type, _) : 0; if (cut) lnode_cut(x, c); return i; } int libcdsb_list_find(vtype_list* x, const void* v, vtype t, void* _, list_access_callback callback, bool r, bool cut) { ldir_t dir; lnode_t* c; ssize_t i; int cmp; dir = r ? LD_PREV : LD_NEXT; c = ldir_dir((lnode_t*)x, dir); i = 0; while (!is_null(c)) { cmp = vtype_compare(vnode_peek(&c->node, c->type), c->type, v, t); if (cmp == 0) { i = (callback) ? callback(vnode_peek(&c->node, c->type), (r)?~i:i, c->type, _) : 0; if (cut) lnode_cut(x, c); return i; } c = ldir_dir(c, dir); ++i; } return -1; } int libcdsb_list_foreach(vtype_list* x, void* data, list_access_callback callback, bool flush) { lnode_t* n; lnode_t* c; size_t i; int r; c = x->first; i = 0; while (!is_null(c)) { if ((r = callback(vnode_peek(&c->node, c->type), i, c->type, data)) != 0) break; n = c->next; if (flush) { vnode_free(&c->node, c->type); free(c); } c = n; ++i; } if (flush) { while(!is_null(c)) { n = c->next; vnode_free(&c->node, c->type); free(c); c = n; } memset(x, 0, sizeof(*x)); } return 0; }