#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)-offsetof(VectorHeader,buf))) #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; } pvoid ctl_array_getEntryX(ppvoid v, uint index){ return pVoid(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)); } }