85#include "containers/qvector.h"
89static void *get_at(qvector_t *vector,
int index,
bool newmem);
90static bool remove_at(qvector_t *vector,
int index);
117qvector_t *
qvector(
size_t max,
size_t objsize,
int options) {
123 qvector_t *vector = (qvector_t *)calloc(1,
sizeof(qvector_t));
124 if (vector == NULL) {
133 vector->objsize = objsize;
135 void *data = malloc(max * objsize);
144 vector->objsize = objsize;
149 if (options & QVECTOR_THREADSAFE) {
150 Q_MUTEX_NEW(vector->qmutex,
true);
151 if (vector->qmutex == NULL) {
159 if (options & QVECTOR_RESIZE_DOUBLE) {
160 vector->options |= QVECTOR_RESIZE_DOUBLE;
161 }
else if (options & QVECTOR_RESIZE_LINEAR) {
162 vector->options |= QVECTOR_RESIZE_LINEAR;
166 vector->initnum = max;
169 vector->options |= QVECTOR_RESIZE_EXACT;
175 vector->addat = qvector_addat;
234 return vector->addat(vector, 0, data);
260 return vector->addat(vector, vector->num, data);
296bool qvector_addat(qvector_t *vector,
int index,
const void *data) {
305 index += vector->num;
307 if (index > vector->num) {
312 vector->lock(vector);
315 if (vector->num >= vector->max) {
316 size_t newmax = vector->max + 1;
317 if (vector->options & QVECTOR_RESIZE_DOUBLE) {
318 newmax = (vector->max + 1) * 2;
319 }
else if (vector->options & QVECTOR_RESIZE_LINEAR) {
320 newmax = vector->max + vector->initnum;
322 newmax = vector->max + 1;
324 bool result = vector->resize(vector, newmax);
327 vector->unlock(vector);
335 for (i = vector->num; i > index; i--) {
336 void *dst = (
unsigned char *)vector->data + vector->objsize * i;
337 void *src = (
unsigned char *)vector->data + vector->objsize * (i - 1);
339 memcpy(dst, src, vector->objsize);
342 void *add = (
unsigned char *)vector->data + index * vector->objsize;
343 memcpy(add, data, vector->objsize);
346 vector->unlock(vector);
372 return vector->getat(vector, 0, newmem);
396 return vector->getat(vector, -1, newmem);
424 vector->lock(vector);
425 void *data = get_at(vector, index, newmem);
426 vector->unlock(vector);
453 return vector->setat(vector, 0, data);
478 return vector->setat(vector, -1, data);
504 vector->lock(vector);
505 void *old_data = get_at(vector, index,
false);
506 if (old_data == NULL) {
509 memcpy(old_data, data, vector->objsize);
510 vector->unlock(vector);
526 return vector->popat(vector, 0);
540 return vector->popat(vector, -1);
568 vector->lock(vector);
569 void *data = get_at(vector, index,
true);
574 bool result = remove_at(vector, index);
575 if (result ==
false) {
577 vector->unlock(vector);
582 vector->unlock(vector);
597 return vector->removeat(vector, 0);
611 return vector->removeat(vector, -1);
626 vector->lock(vector);
627 bool result = remove_at(vector, index);
632 vector->unlock(vector);
658 Q_MUTEX_ENTER(vector->qmutex);
667 Q_MUTEX_LEAVE(vector->qmutex);
676 vector->lock(vector);
678 vector->unlock(vector);
687 vector->clear(vector);
688 Q_MUTEX_DESTROY(vector->qmutex);
690 if (vector->data != NULL) {
713 vector->lock(vector);
715 for (i = 0; i < vector->num; i++) {
716 void *data = (
unsigned char *)vector->data + i * vector->objsize;
717 fprintf(out,
"%d=", i);
718 _q_textout(out, data, vector->objsize, MAX_HUMANOUT);
719 fprintf(out,
" (%zu)\n", vector->objsize);
721 vector->unlock(vector);
747 vector->lock(vector);
756 vector->unlock(vector);
760 void *newdata = realloc(vector->data, newmax * vector->objsize);
761 if (newdata == NULL) {
763 vector->unlock(vector);
767 vector->data = newdata;
768 vector->max = newmax;
769 if (vector->num > newmax) {
770 vector->num = newmax;
773 vector->unlock(vector);
788 if (vector->num <= 0) {
796 vector->lock(vector);
798 void *array = malloc(vector->num * vector->objsize);
800 vector->unlock(vector);
805 memcpy(array, vector->data, vector->num * vector->objsize);
811 vector->unlock(vector);
824 vector->lock(vector);
826 if (vector->num <= 1) {
827 vector->unlock(vector);
833 void *tmp = malloc(vector->objsize);
839 for (i = 0, j = vector->num - 1; i < j; i++, j--) {
840 void *data1 = (
unsigned char *)vector->data + i * vector->objsize;
841 void *data2 = (
unsigned char *)vector->data + j * vector->objsize;
843 memcpy(tmp, data1, vector->objsize);
844 memcpy(data1, data2, vector->objsize);
845 memcpy(data2, tmp, vector->objsize);
849 vector->unlock(vector);
885 vector->lock(vector);
887 if (obj->index >= vector->num) {
890 vector->unlock(vector);
894 void *data = (
unsigned char *)vector->data + (obj->index) * vector->objsize;
896 void *dump = malloc(vector->objsize);
900 vector->unlock(vector);
903 memcpy(dump, data, vector->objsize);
912 vector->unlock(vector);
918static void *get_at(qvector_t *vector,
int index,
bool newmem) {
920 index += vector->num;
922 if (index >= vector->num) {
923 if (vector->num == 0) {
932 void *src_data = (
unsigned char *)vector->data + index * vector->objsize;
934 void *dump_data = malloc(vector->objsize);
935 if (dump_data == NULL) {
939 memcpy(dump_data, src_data, vector->objsize);
947static bool remove_at(qvector_t *vector,
int index) {
949 index += vector->num;
951 if (index >= vector->num) {
952 if (vector->num == 0) {
962 for (i = index + 1; i < vector->num; i++) {
963 void *src = (
unsigned char *)vector->data + i * vector->objsize;
964 void *dst = (
unsigned char *)vector->data + (i - 1) * vector->objsize;
966 memcpy(dst, src, vector->objsize);
bool qvector_addfirst(qvector_t *vector, const void *data)
qvector->addfirst(): Insert a 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 out stored elements for debugging purpose.
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->addat(): Inserts a element at the specified position in this vector.
void * qvector_popfirst(qvector_t *vector)
qvector->popfirst(): Returns and remove the first element in this vector.
void * qvector_getlast(qvector_t *vector, bool newmem)
qvector->getlast(): Returns the last element 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 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 contains 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 remove the element at 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 a element at the end of this vector.