#include "list.h" #include <string.h> struct ListNodeStruct; struct ListHeaderStruct; struct ListNodeStruct{ struct ListHeaderStruct *head; struct ListNodeStruct *prev; struct ListNodeStruct *next; char buf[]; }; struct ListHeaderStruct{ size_t size; uint count; struct ListNodeStruct data; }; typedef struct ListNodeStruct ListNode; typedef struct ListHeaderStruct ListHeader; #define getHeader(X) (*(ListHeader**)(pChar(X)-offsetof(ListNode,buf))) #define getNode(X) ((ListNode*)(pChar(X)-offsetof(ListNode,buf))) #define getNodeSize(X) ((X)->size+sizeof(ListNode)) /******************** private functions *******************/ #define nodeConnect(a,b) \ do{\ (a)->next = (b);\ (b)->prev = (a);\ }while(0) #define addNodeFront(lllll) \ do{\ ListNode *tzzzmp = (ListNode*)ctl_malloc(getNodeSize(lllll));\ tzzzmp->head = (lllll);\ nodeConnect(tzzzmp, (lllll)->data.next);\ nodeConnect(&(lllll)->data, tzzzmp);\ (lllll)->count++;\ }while(0) #define addNodeBack(lllll) \ do{\ ListNode *tzzzmp = (ListNode*)ctl_malloc(getNodeSize(lllll));\ tzzzmp->head = (lllll);\ nodeConnect((lllll)->data.prev, tzzzmp);\ nodeConnect(tzzzmp, &(lllll)->data);\ (lllll)->count++;\ }while(0) #define delNodeFront(lllll) \ do{\ ListNode *tzzzmp = (lllll)->data.next;\ tzzzmp->head = (lllll);\ nodeConnect(&(lllll)->data, tzzzmp->next);\ ctl_free(tzzzmp);\ (lllll)->count--;\ }while(0) #define delNodeBack(lllll) \ do{\ ListNode *tzzzmp = (lllll)->data.prev;\ tzzzmp->head = (lllll);\ nodeConnect(tzzzmp->prev, &(lllll)->data);\ ctl_free(tzzzmp);\ (lllll)->count--;\ }while(0) /***************** initalize & destructure ****************/ pvoid ctl_list_initX(ppvoid l, size_t size, uint count){ ListHeader *tmp = (ListHeader*)ctl_malloc(sizeof(ListHeader)); tmp->size = size; tmp->data.head = tmp; tmp->data.prev = &tmp->data; tmp->data.next = &tmp->data; for(tmp->count = 0; tmp->count < count; tmp->count++){ addNodeBack(tmp); } if(l != NULL){ *l = tmp->data.buf; } return tmp->data.buf; } pvoid ctl_list_freeX(ppvoid l){ ListHeader* tmp = getHeader(*l); while(tmp->data.next != &tmp->data){ ListNode *ntmp = tmp->data.next; tmp->data.next = tmp->data.next->next; ctl_free(ntmp); } ctl_free(tmp); *l = NULL; return NULL; } /**************** about get??? methods ********************/ int ctl_list_getSizeX(ppcvoid l){ return getHeader(*l)->count; } int ctl_list_getEntrySizeX(ppcvoid l){ return getHeader(*l)->size; } pvoid ctl_list_getFrontX(ppvoid l){ return getHeader(*l)->data.next->buf; } pvoid ctl_list_getBackX(ppvoid l){ return getHeader(*l)->data.prev->buf; } pvoid ctl_list_getBeginX(ppvoid l){ return getHeader(*l)->data.next->buf; } pvoid ctl_list_getEndX(ppvoid l){ return *l; } /**************** about set??? methods ********************/ int ctl_list_setSizeX(ppvoid l, uint count){ ListHeader *tmp = getHeader(*l); while(tmp->count > count){ delNodeBack(tmp); } while(tmp->count < count){ addNodeBack(tmp); } return tmp->count; } pvoid ctl_list_setFrontX(ppvoid l, pcvoid data){ ListHeader *tmp = getHeader(*l); memcpy(tmp->data.next->buf, data, tmp->size); return tmp->data.next->buf; } pvoid ctl_list_setBackX(ppvoid l, pcvoid data){ ListHeader *tmp = getHeader(*l); memcpy(tmp->data.prev->buf, data, tmp->size); return tmp->data.prev->buf; } /**************** about add/del front/back ****************/ int ctl_list_addFrontX(ppvoid l, pcvoid data){ ListHeader* tmp = getHeader(*l); addNodeFront(tmp); ctl_list_setFrontX(l, data); return tmp->count; } int ctl_list_delFrontX(ppvoid l){ ListHeader *tmp = getHeader(*l); delNodeFront(tmp); return tmp->count; } int ctl_list_addBackX(ppvoid l, pcvoid data){ ListHeader* tmp = getHeader(*l); addNodeBack(tmp); ctl_list_setBackX(l, data); return tmp->count; } int ctl_list_delBackX(ppvoid l){ ListHeader *tmp = getHeader(*l); delNodeBack(tmp); return tmp->count; } /************** about list's special methods **************/ int ctl_list_rmX(ppvoid l, pvoid i1, pvoid i2){ ListHeader *tmp = getHeader(*l ); ListNode* n1 = getNode (i1); ListNode* n2 = getNode (i2); nodeConnect(n1->prev, n2); int ret = 0; while(n1 != n2){ ListNode* ntmp = n1; n1 = n1->next; ctl_free(ntmp); ret++; } tmp->count -= ret; return ret; } pvoid ctl_list_copyX(ppvoid l, pvoid i1, pvoid i2, ppvoid out){ ListHeader* tmp = getHeader(*l); pvoid *p0 = ctl_list_init(NULL, tmp->size, 0); ListHeader* tmp2 = getHeader(p0); ListNode* n1 = getNode(i1); ListNode* n2 = getNode(i2); while(n1 != n2){ char *c = tmp2->data.buf; ctl_list_addBack(&c, n1->buf); n1 = n1->next; tmp2->count++; } if(out != NULL){ *out = tmp2->data.buf; } return tmp2->data.buf; } pvoid ctl_list_moveX(ppvoid l, pvoid i1, pvoid i2, ppvoid out){ ListHeader* tmp = getHeader(*l); pvoid *p0 = ctl_list_init(NULL, tmp->size, 0); ListHeader* tmp2 = getHeader(p0); ListNode* n1 = getNode(i1); ListNode* n3 = getNode(i2); ListNode* n0 = n1->prev; ListNode* n2 = n3->prev; ListNode* ni; for(ni = n1; ni != n3; ni = ni->next){ tmp ->count--; tmp2->count++; } nodeConnect(&tmp2->data, n1); nodeConnect(n2, &tmp2->data); nodeConnect(n0, n3); if(out != NULL){ *out = tmp2->data.buf; } return tmp2->data.buf; } int ctl_list_swapX(ppvoid li, pvoid i1, pvoid i2, ppvoid lj, pvoid j1, pvoid j2){ ListHeader* hi = getHeader(*li),* hj = getHeader(*lj); ListNode * ni1 = getNode ( i1),* nj1 = getNode ( j1), *i; ListNode * ni3 = getNode ( i2),* nj3 = getNode ( j2), *j; int count1 = 0, count2 = 0; for(i = ni1; i != ni3; i = i->next){ count1++; } for(j = nj1; j != nj3; j = j->next){ count2++; } ListNode* ni0 = ni1->prev,* ni2 = ni3->prev; ListNode* nj0 = nj1->prev,* nj2 = nj3->prev; nodeConnect(ni0, nj1); nodeConnect(nj0, ni1); nodeConnect(ni2, nj3); nodeConnect(nj2, ni3); hi->size += (count2 - count1); hj->size += (count1 - count2); return count1; } /******************** about iterator **********************/ pvoid ctl_list_iterGetEntryX(pvoid i){ return i; } pvoid ctl_list_iterGetNextX(pvoid i){ return getNode(i)->next->buf; } pvoid ctl_list_iterGetPrevX(pvoid i){ return getNode(i)->prev->buf; } pvoid ctl_list_iterSetEntryX(pvoid i, pcvoid data){ memcpy(i, data, getNode(i)->head->size); return i; } pvoid ctl_list_iterDelX(pvoid i){ ListNode* n = getNode(i); nodeConnect(n->prev, n->next); n->head->count--; return n->next->buf; } pvoid ctl_list_iterDelPrevX(pvoid i){ ctl_list_iterDelX(ppVoid(getNode(i)->prev->buf)); return i; } pvoid ctl_list_iterDelNextX(pvoid i){ ctl_list_iterDelX(ppVoid(getNode(i)->next->buf)); return i; }