/* singularly linked-list */ #ifndef OSCAM_LLIST_H_ #define OSCAM_LLIST_H_ typedef struct llnode LL_NODE; struct llnode { void *obj; LL_NODE *nxt; }; typedef struct llist LLIST; struct llist { //void *obj; LL_NODE *initial; LL_NODE *last; int32_t count; CS_MUTEX_LOCK lock; int32_t flag; uint32_t version; // updated on every modification of the list - exception is on prepends and appends as this should not have impacts on iterations! }; typedef struct lliter LL_ITER; struct lliter { LLIST *l; LL_NODE *cur, *prv; uint32_t ll_version; }; typedef struct llistlockiter LL_LOCKITER; struct llistlockiter { LLIST *l; int32_t writelock; LL_ITER it; }; LLIST *ll_create(const char *name); // create llist, return ptr to llist void ll_destroy(LLIST **pl); // same as ll_clear_abstract() but frees up LLIST mem as well void ll_destroy_data(LLIST **pl); // same as ll_clear_data() but frees up obj allocations as well void ll_destroy_free_data(LLIST **pl); // same as ll_clear_data() but frees up obj allocations as well. More, really free node without use GBC void ll_clear(LLIST *l); // frees up all llnodes nodes but not data held in obj ptrs void ll_clear_data(LLIST *l); // same as ll_clear_data() but frees up obj allocations as well void **ll_sort(const LLIST *l, void *compare, int32_t *size); // sorts the list, compare = int func(const T *a, const T *b) LL_NODE *ll_append(LLIST *l, void *obj); // append obj to llist LL_NODE *ll_prepend(LLIST *l, void *obj); // prepend obj to llist // clones a list, duplicates data LLIST *ll_clone(LLIST *l, uint32_t copysize); // New type of lock, list is locked during iterate! create=lock, destroy=unlock LL_LOCKITER *ll_li_create(LLIST *l, int32_t writelock); void ll_li_destroy(LL_LOCKITER *li); void *ll_li_next(LL_LOCKITER *li); // Old Iterators: LL_ITER ll_iter_create(LLIST *l); // return ptr to iterator obj void *ll_iter_next(LL_ITER *it); // iterate to and return next llnode obj, returns NULL at end void *ll_iter_next_remove(LL_ITER *it); // iterate to and return next llnode obj, returns NULL at end, removing it void *ll_iter_peek(const LL_ITER *it, int32_t offset); // return obj at offset from iterator but do not iterate void ll_iter_reset(LL_ITER *it); // reset itrerator to first llnode void ll_iter_insert(LL_ITER *it, void *obj); // insert obj at iterator node void *ll_iter_remove(LL_ITER *it); // remove llnode at iterator, returns ptr to the llnode obj removed void ll_iter_remove_data(LL_ITER *it); // remove llnode and free llnode obj void *ll_iter_move(LL_ITER *it, int32_t offset); // moves the iterator position int32_t ll_iter_move_first(LL_ITER *it); // moves an entry to top static inline int32_t ll_count(const LLIST *l) // return number of items in list { if(!l || l->flag) { return 0; } return l->count; } void *ll_has_elements(const LLIST *l); // returns first obj if has one void *ll_last_element(const LLIST *l); int32_t ll_contains(const LLIST *l, const void *obj); const void *ll_contains_data(const LLIST *l, const void *obj, uint32_t size); int32_t ll_remove(LLIST *l, const void *obj); void ll_remove_data(LLIST *l, void *obj); int32_t ll_remove_all(LLIST *l, const LLIST *elements_to_remove); // removes all elements from l where elements are in elements_to_remove void ll_putall(LLIST *dest, LLIST *src); void *ll_remove_first(LLIST *l); void ll_remove_first_data(LLIST *l); #endif