81#include "containers/qvector.h"
85static void *get_at(qvector_t *vector,
int index,
bool newmem);
86static bool remove_at(qvector_t *vector,
int index);
113qvector_t *
qvector(
size_t max,
size_t objsize,
int options) {
119 qvector_t *vector = (qvector_t *)calloc(1,
sizeof(qvector_t));
120 if (vector == NULL) {
129 vector->objsize = objsize;
131 void *data = malloc(max * objsize);
140 vector->objsize = objsize;
145 if (options & QVECTOR_THREADSAFE) {
146 Q_MUTEX_NEW(vector->qmutex,
true);
147 if (vector->qmutex == NULL) {
155 if (options & QVECTOR_RESIZE_DOUBLE) {
156 vector->options |= QVECTOR_RESIZE_DOUBLE;
157 }
else if (options & QVECTOR_RESIZE_LINEAR) {
158 vector->options |= QVECTOR_RESIZE_LINEAR;
162 vector->initnum = max;
165 vector->options |= QVECTOR_RESIZE_EXACT;
230 return vector->addat(vector, 0, data);
256 return vector->addat(vector, vector->num, data);
301 index += vector->num;
303 if (index > vector->num) {
308 vector->lock(vector);
311 if (vector->num >= vector->max) {
312 size_t newmax = vector->max + 1;
313 if (vector->options & QVECTOR_RESIZE_DOUBLE) {
314 newmax = (vector->max + 1) * 2;
315 }
else if (vector->options & QVECTOR_RESIZE_LINEAR) {
316 newmax = vector->max + vector->initnum;
318 newmax = vector->max + 1;
320 bool result = vector->resize(vector, newmax);
323 vector->unlock(vector);
331 for (i = vector->num; i > index; i--) {
332 void *dst = (
unsigned char *)vector->data + vector->objsize * i;
333 void *src = (
unsigned char *)vector->data + vector->objsize * (i - 1);
335 memcpy(dst, src, vector->objsize);
338 void *add = (
unsigned char *)vector->data + index * vector->objsize;
339 memcpy(add, data, vector->objsize);
342 vector->unlock(vector);
368 return vector->getat(vector, 0, newmem);
392 return vector->getat(vector, -1, newmem);
420 vector->lock(vector);
421 void *data = get_at(vector, index, newmem);
422 vector->unlock(vector);
449 return vector->setat(vector, 0, data);
474 return vector->setat(vector, -1, data);
500 vector->lock(vector);
501 void *old_data = get_at(vector, index,
false);
502 if (old_data == NULL) {
505 memcpy(old_data, data, vector->objsize);
506 vector->unlock(vector);
522 return vector->popat(vector, 0);
536 return vector->popat(vector, -1);
564 vector->lock(vector);
565 void *data = get_at(vector, index,
true);
570 bool result = remove_at(vector, index);
571 if (result ==
false) {
573 vector->unlock(vector);
578 vector->unlock(vector);
593 return vector->removeat(vector, 0);
607 return vector->removeat(vector, -1);
622 vector->lock(vector);
623 bool result = remove_at(vector, index);
628 vector->unlock(vector);
654 Q_MUTEX_ENTER(vector->qmutex);
663 Q_MUTEX_LEAVE(vector->qmutex);
672 vector->lock(vector);
674 vector->unlock(vector);
683 vector->clear(vector);
684 Q_MUTEX_DESTROY(vector->qmutex);
686 if (vector->data != NULL) {
709 vector->lock(vector);
711 for (i = 0; i < vector->num; i++) {
712 void *data = (
unsigned char *)vector->data + i * vector->objsize;
713 fprintf(out,
"%d=", i);
714 _q_textout(out, data, vector->objsize, MAX_HUMANOUT);
715 fprintf(out,
" (%zu)\n", vector->objsize);
717 vector->unlock(vector);
743 vector->lock(vector);
752 vector->unlock(vector);
756 void *newdata = realloc(vector->data, newmax * vector->objsize);
757 if (newdata == NULL) {
759 vector->unlock(vector);
763 vector->data = newdata;
764 vector->max = newmax;
765 if (vector->num > newmax) {
766 vector->num = newmax;
769 vector->unlock(vector);
784 if (vector->num <= 0) {
792 vector->lock(vector);
794 void *array = malloc(vector->num * vector->objsize);
796 vector->unlock(vector);
801 memcpy(array, vector->data, vector->num * vector->objsize);
807 vector->unlock(vector);
820 vector->lock(vector);
822 if (vector->num <= 1) {
823 vector->unlock(vector);
829 void *tmp = malloc(vector->objsize);
835 for (i = 0, j = vector->num - 1; i < j; i++, j--) {
836 void *data1 = (
unsigned char *)vector->data + i * vector->objsize;
837 void *data2 = (
unsigned char *)vector->data + j * vector->objsize;
839 memcpy(tmp, data1, vector->objsize);
840 memcpy(data1, data2, vector->objsize);
841 memcpy(data2, tmp, vector->objsize);
845 vector->unlock(vector);
881 vector->lock(vector);
883 if (obj->index >= vector->num) {
886 vector->unlock(vector);
890 void *data = (
unsigned char *)vector->data + (obj->index) * vector->objsize;
892 void *dump = malloc(vector->objsize);
896 vector->unlock(vector);
899 memcpy(dump, data, vector->objsize);
908 vector->unlock(vector);
914static void *get_at(qvector_t *vector,
int index,
bool newmem) {
916 index += vector->num;
918 if (index >= vector->num) {
919 if (vector->num == 0) {
928 void *src_data = (
unsigned char *)vector->data + index * vector->objsize;
930 void *dump_data = malloc(vector->objsize);
931 if (dump_data == NULL) {
935 memcpy(dump_data, src_data, vector->objsize);
943static bool remove_at(qvector_t *vector,
int index) {
945 index += vector->num;
947 if (index >= vector->num) {
948 if (vector->num == 0) {
957 void *src = (
unsigned char *)vector->data + (index + 1) * vector->objsize;
958 void *dst = (
unsigned char *)vector->data + index * vector->objsize;
959 int size = (vector->num - (index + 1)) * vector->objsize;
960 memcpy(dst, src, size);
bool qvector_addfirst(qvector_t *vector, const void *data)
qvector->addfirst(): Insert an element at the beginning of this vector.
bool qvector_removefirst(qvector_t *vector)
qvector->removefirst(): Removes the first element in this vector.
void qvector_reverse(qvector_t *vector)
qvector->reverse(): Reverse the order of element in this vector.
void * qvector_getat(qvector_t *vector, int index, bool newmem)
qvector->getat(): Returns the element at the specified position in this vector.
void * qvector_poplast(qvector_t *vector)
qvector->poplast(): Returns the last element of this vector.
bool qvector_debug(qvector_t *vector, FILE *out)
qvector->debug(): Prints stored elements for debugging purposes.
void qvector_lock(qvector_t *vector)
qvector->lock(): Enters critical section.
bool qvector_resize(qvector_t *vector, size_t newmax)
qvector->resize(): Changes the allocated memory space size.
void * qvector_getfirst(qvector_t *vector, bool newmem)
qvector->getfirst(): Returns the first element in this vector.
void * qvector_popfirst(qvector_t *vector)
qvector->popfirst(): Returns and removes the first element in this vector.
void * qvector_getlast(qvector_t *vector, bool newmem)
qvector->getlast(): Returns the last element in this vector.
bool qvector_addat(qvector_t *vector, int index, const void *data)
qvector->addat(): Insert an element at the specified position in this vector.
void qvector_free(qvector_t *vector)
qvector->free(): Free this vector.
void qvector_clear(qvector_t *vector)
qvector->clear(): Remove all the elemnts in this vector.
qvector_t * qvector(size_t max, size_t objsize, int options)
Create a new qvector_t container.
void qvector_unlock(qvector_t *vector)
qvector->unlock(): Leaves critical section.
void * qvector_toarray(qvector_t *vector, size_t *size)
qvector->toarray(): Returns an array containing all the elements in this vector.
bool qvector_setlast(qvector_t *vector, const void *data)
qvector->setlast(): Set the last element with a new value in this vector.
bool qvector_getnext(qvector_t *vector, qvector_obj_t *obj, bool newmem)
qvector->getnext(): Get next element in this vector.
bool qvector_setfirst(qvector_t *vector, const void *data)
qvector->setfirst(): Set the first element with a new value in this vector.
bool qvector_removelast(qvector_t *vector)
qvector->removelast(): Removes the last element in this vector.
bool qvector_removeat(qvector_t *vector, int index)
qvector->removeat(): Removes the element at the specified position in this vector.
void * qvector_popat(qvector_t *vector, int index)
qvector->popat(): Returns and removes the element at the specified position in this vector.
bool qvector_setat(qvector_t *vector, int index, const void *data)
qvector->setat(): Set new value to the specified position in this vector.
size_t qvector_size(qvector_t *vector)
qvector->size(): Get the number of elements in this vector.
bool qvector_addlast(qvector_t *vector, const void *data)
qvector->addlast(): Insert an element at the end of this vector.