97#include "containers/qlist.h"
101static void *get_at(qlist_t *list,
int index,
size_t *size,
bool newmem,
bool remove);
102static qlist_obj_t *get_obj(qlist_t *list,
int index);
103static bool remove_obj(qlist_t *list, qlist_obj_t *obj);
125 qlist_t *list = (qlist_t *) calloc(1,
sizeof(qlist_t));
132 if (options & QLIST_THREADSAFE) {
133 Q_MUTEX_NEW(list->qmutex,
true);
134 if (list->qmutex == NULL) {
192 size_t old = list->max;
276bool qlist_addat(qlist_t *list,
int index,
const void *data,
size_t size) {
278 if (data == NULL || size <= 0) {
286 if (list->max > 0 && list->num >= list->max) {
294 index = (list->num + index) + 1;
295 if (index < 0 || index > list->num) {
303 void *dup_data = malloc(size);
304 if (dup_data == NULL) {
309 memcpy(dup_data, data, size);
312 qlist_obj_t *obj = (qlist_obj_t *) malloc(
sizeof(qlist_obj_t));
319 obj->data = dup_data;
327 obj->next = list->first;
328 if (obj->next != NULL)
329 obj->next->prev = obj;
331 if (list->last == NULL)
333 }
else if (index == list->num) {
335 obj->prev = list->last;
336 if (obj->prev != NULL)
337 obj->prev->next = obj;
339 if (list->first == NULL)
343 qlist_obj_t *tgt = get_obj(list, index);
354 tgt->prev->next = obj;
355 obj->prev = tgt->prev;
360 list->datasum += size;
436void *
qlist_getat(qlist_t *list,
int index,
size_t *size,
bool newmem) {
437 return get_at(list, index, size, newmem,
false);
496 return get_at(list, index, size,
true,
true);
540 qlist_obj_t *obj = get_obj(list, index);
546 bool ret = remove_obj(list, obj);
589 qlist_obj_t *cont = NULL;
602 while (cont != NULL) {
603 if (newmem ==
true) {
604 obj->data = malloc(cont->size);
605 if (obj->data == NULL)
608 memcpy(obj->data, cont->data, cont->size);
610 obj->data = cont->data;
612 obj->size = cont->size;
613 obj->prev = cont->prev;
614 obj->next = cont->next;
643 return list->datasum;
654 for (obj = list->first; obj;) {
655 qlist_obj_t *next = obj->next;
656 obj->next = obj->prev;
662 list->first = list->last;
676 for (obj = list->first; obj;) {
677 qlist_obj_t *next = obj->next;
704 if (list->num <= 0) {
713 void *chunk = malloc(list->datasum);
722 for (obj = list->first; obj; obj = obj->next) {
723 memcpy(dp, obj->data, obj->size);
729 *size = list->datasum;
749 if (list->num <= 0) {
756 void *chunk = malloc(list->datasum + 1);
765 for (obj = list->first; obj; obj = obj->next) {
766 size_t size = obj->size;
768 if (*(
char *) (obj->data + (size - 1)) ==
'\0')
770 memcpy(dp, obj->data, size);
773 *((
char *) dp) =
'\0';
776 return (
char *) chunk;
798 for (i = 0, obj = list->first; obj; obj = obj->next, i++) {
799 fprintf(out,
"%d=", i);
800 _q_textout(out, obj->data, obj->size, MAX_HUMANOUT);
801 fprintf(out,
" (%zu)\n", obj->size);
818 Q_MUTEX_ENTER(list->qmutex);
827 Q_MUTEX_LEAVE(list->qmutex);
837 Q_MUTEX_DESTROY(list->qmutex);
844static void *get_at(qlist_t *list,
int index,
size_t *size,
bool newmem,
849 qlist_obj_t *obj = get_obj(list, index);
857 if (newmem ==
true) {
858 data = malloc(obj->size);
864 memcpy(data, obj->data, obj->size);
872 if (remove ==
true) {
873 if (remove_obj(list, obj) ==
false) {
885static qlist_obj_t *get_obj(qlist_t *list,
int index) {
888 index = list->num + index;
889 if (index >= list->num) {
898 if (index < list->num / 2) {
905 listidx = list->num - 1;
909 while (obj != NULL) {
910 if (listidx == index)
913 if (backward ==
false) {
927static bool remove_obj(qlist_t *list, qlist_obj_t *obj) {
932 if (obj->prev == NULL)
933 list->first = obj->next;
935 obj->prev->next = obj->next;
936 if (obj->next == NULL)
937 list->last = obj->prev;
939 obj->next->prev = obj->prev;
942 list->datasum -= obj->size;
void * qlist_getlast(qlist_t *list, size_t *size, bool newmem)
qlist->getlast(): Returns the last element in this list.
bool qlist_getnext(qlist_t *list, qlist_obj_t *obj, bool newmem)
qlist->getnext(): Get next element in this list.
void qlist_unlock(qlist_t *list)
qlist->unlock(): Leaves critical section.
char * qlist_tostring(qlist_t *list)
qlist->tostring(): Returns a string representation of this list, containing string representation of ...
void qlist_reverse(qlist_t *list)
qlist->reverse(): Reverse the order of elements.
bool qlist_removelast(qlist_t *list)
qlist->removelast(): Removes the last element in this list.
bool qlist_addat(qlist_t *list, int index, const void *data, size_t size)
qlist->addat(): Inserts a element at the specified position in this list.
void * qlist_poplast(qlist_t *list, size_t *size)
qlist->getlast(): Returns and remove the last element in this list.
bool qlist_addfirst(qlist_t *list, const void *data, size_t size)
qlist->addfirst(): Inserts a element at the beginning of this list.
void qlist_free(qlist_t *list)
qlist->free(): Free qlist_t.
bool qlist_debug(qlist_t *list, FILE *out)
qlist->debug(): Prints out stored elements for debugging purpose.
void * qlist_getat(qlist_t *list, int index, size_t *size, bool newmem)
qlist->getat(): Returns the element at the specified position in this list.
bool qlist_addlast(qlist_t *list, const void *data, size_t size)
qlist->addlast(): Appends a element to the end of this list.
size_t qlist_datasize(qlist_t *list)
qlist->size(): Returns the sum of total element size.
bool qlist_removefirst(qlist_t *list)
qlist->removefirst(): Removes the first element in this list.
size_t qlist_size(qlist_t *list)
qlist->size(): Returns the number of elements in this list.
void * qlist_popat(qlist_t *list, int index, size_t *size)
qlist->popat(): Returns and remove the element at the specified position in this list.
void * qlist_getfirst(qlist_t *list, size_t *size, bool newmem)
qlist->getfirst(): Returns the first element in this list.
void qlist_clear(qlist_t *list)
qlist->clear(): Removes all of the elements from this list.
void qlist_lock(qlist_t *list)
qlist->lock(): Enters critical section.
void * qlist_popfirst(qlist_t *list, size_t *size)
qlist->popfirst(): Returns and remove the first element in this list.
size_t qlist_setsize(qlist_t *list, size_t max)
qlist->setsize(): Limit maximum number of elements allowed in this list.
qlist_t * qlist(int options)
Create new qlist_t linked-list container.
void * qlist_toarray(qlist_t *list, size_t *size)
qlist->toarray(): Returns the serialized chunk containing all the elements in this list.
bool qlist_removeat(qlist_t *list, int index)
qlist->removeat(): Removes the element at the specified position in this list.