aboutsummaryrefslogtreecommitdiffstats
path: root/src/array.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/array.c')
-rw-r--r--src/array.c158
1 files changed, 158 insertions, 0 deletions
diff --git a/src/array.c b/src/array.c
new file mode 100644
index 0000000..2920320
--- /dev/null
+++ b/src/array.c
@@ -0,0 +1,158 @@
+#include "array.h"
+#include "utility.h"
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+
+typedef struct{
+ size_t size;
+ uint use_count;
+ uint mem_count;
+
+ char buf[];
+} VectorHeader;
+
+#define getHeader(X) ((VectorHeader*)(pChar(X)-sizeof(VectorHeader)))
+#define getTotal2(X,Y) ((Y)*(X)+sizeof(VectorHeader))
+#define getTotal(X) getTotal2((X)->mem_count,(X)->size)
+
+/********************** initalize *************************/
+pvoid ctl_array_initX(ppvoid v, size_t size, uint count){
+ VectorHeader *tmp;
+
+ int mem = 0;
+ if(count >= 1)
+ for(mem = 1; mem < count; mem *= 2);
+
+ tmp = (VectorHeader*)ctl_malloc(getTotal2(mem, size));
+
+ tmp->size = size;
+ tmp->use_count = count;
+ tmp->mem_count = mem;
+ if(v != NULL){
+ *v = pVoid(tmp->buf);
+ }
+ return pVoid(tmp->buf);
+}
+
+/******************** destructure *************************/
+pvoid ctl_array_freeX(ppvoid v){
+ free(pVoid(getHeader(*v)));
+ *v = NULL;
+ return NULL;
+}
+
+/******************** methods about get??? ****************/
+int ctl_array_getSizeX(ppvoid v){
+ return getHeader(*v)->use_count;
+}
+
+pcvoid ctl_array_getEntryX(ppvoid v, uint index){
+ return pcVoid(pChar(*v) + getHeader(*v)->size * index);
+}
+
+int ctl_array_getEntrySizeX(ppvoid v){
+ return getHeader(*v)->size;
+}
+
+/******************** methods about set??? ****************/
+int ctl_array_setSizeX(ppvoid v, uint count){
+ VectorHeader *tmp = getHeader(*v);
+
+ int mem = 0;
+ if(count >= 1)
+ for(mem = 1; mem < count; mem *= 2);
+ tmp->use_count = count;
+ tmp->mem_count = mem;
+
+ tmp = (VectorHeader*)ctl_realloc(pVoid(tmp), getTotal(tmp));
+ *v = pVoid(tmp->buf);
+
+ return tmp->use_count;
+}
+pvoid ctl_array_setEntryX(ppvoid v, uint index, pcvoid data){
+ VectorHeader *tmp = getHeader(*v);
+ memcpy(pVoid(tmp->buf + index * tmp->size), data, tmp->size);
+}
+
+/************** add/del element on the back ***************/
+int ctl_array_addBackX(ppvoid v, pcvoid entry){
+ VectorHeader *tmp = getHeader(*v);
+
+ if(tmp->use_count + 1 > tmp->mem_count){
+ if(tmp->mem_count == 0) tmp->mem_count = 1;
+ else tmp->mem_count *= 2;
+ tmp = (VectorHeader*)realloc(pVoid(tmp), getTotal(tmp));
+ *v = pVoid(tmp->buf);
+ }
+ memcpy(tmp->buf + tmp->size * tmp->use_count, entry, tmp->size);
+ tmp->use_count++;
+ return tmp->use_count;
+}
+int ctl_array_delBackX(ppvoid v){
+ VectorHeader *tmp = getHeader(*v);
+
+ if((tmp->use_count - 1) * 2 < tmp->mem_count){
+ tmp->mem_count /= 2;
+ tmp = (VectorHeader*)realloc(pVoid(tmp), getTotal(tmp));
+ *v = pVoid(tmp->buf);
+ }
+
+ tmp->use_count--;
+ return tmp->use_count;
+}
+//int ctl_array_addFrontX(ppvoid v, pcvoid entry);
+//int ctl_array_delFrontX(ppvoid v);
+
+int ctl_array_catX(ppvoid v, ppcvoid v2){
+ int count0 = getHeader(*v)->use_count;
+ int count2 = getHeader(*v2)->use_count;
+ ctl_array_setSize(v, count0 + count2);
+ int i;
+ for(i = 0; i < count2; i++)
+ ctl_array_setEntry(v, count0 + i, ctl_array_getEntry(v2, i));
+ return count0 + count2;
+}
+pvoid ctl_array_copyX(ppvoid v, ppcvoid v2){
+ VectorHeader* tmp = getHeader(*v2);
+ VectorHeader* p = (VectorHeader*)malloc(getTotal(tmp));
+ memcpy(pVoid(p), pVoid(tmp), getTotal(tmp));
+ if(v != NULL){
+ if(*v != NULL){
+ ctl_array_free(v);
+ }
+ *v = p->buf;
+ }
+ return p->buf;
+}
+int ctl_array_replaceX( ppvoid v , uint start1, uint length1,
+ ppcvoid v2, uint start2, int length2){
+ int end1 = (int)start1 + length1 - 1;
+ int end2 = (int)start2 + abs(length2) - 1, step2 = 1;
+ if(length2 < 0){
+ length2 *= -1;
+ step2 *= -1;
+ ctl_swap(int, start2, end2);
+ }
+ if (length1 < length2){ // need increase size
+ int sz0 = ctl_array_getSize(v);
+ int delta = length2 - length1;
+ ctl_array_setSize(v, sz0 + delta);
+ int i;
+ for(i = sz0 + delta - 1; i - delta > end1; i--){
+ ctl_array_setEntry(v, i, ctl_array_getEntry(v, i - delta));
+ }
+ }else if(length1 > length2){ // need decrease size
+ int sz0 = ctl_array_getSize(v);
+ int delta = length1 - length2;
+ int i;
+ for(i = end1 - delta + 1; i + delta < sz0; i++){
+ ctl_array_setEntry(v, i, ctl_array_getEntry(v, i + delta));
+ }
+ ctl_array_setSize(v, sz0 - delta);
+ }
+ for(end2 += step2; start2 != end2; start2 += step2, start1 += 1){
+ ctl_array_setEntry(v, start1, ctl_array_getEntry(v2, start2));
+ }
+}