#include "queue.h" #include <stdlib.h> #include <string.h> #include <stddef.h> struct QueueHeadStruct; struct QueueNodeStruct; struct QueueNodeStruct{ struct QueueHeadStruct* head; struct QueueNodeStruct* next; char buf[]; }; struct QueueHeadStruct{ uint size; struct QueueNodeStruct* first; struct QueueNodeStruct* last ; struct QueueNodeStruct data; }; typedef struct QueueNodeStruct QueueNode; typedef struct QueueHeadStruct QueueHead; #define getHead(X) (((QueueNode*)(pChar(X)-offsetof(QueueNode, buf)))->head) #define getSize(X) (sizeof(QueueNode) + (getHead(X)->size)) pvoid ctl_queue_initX(ppvoid q, uint size){ QueueHead* head = (QueueHead*)ctl_malloc(sizeof(QueueHead)); head->size = size; head->first = NULL; head->last = NULL; head->data.head = head; head->data.next = NULL; if(q != NULL){ *q = pVoid(head->data.buf); } return pVoid(head->data.buf); } pvoid ctl_queue_freeX(ppvoid q){ QueueHead* head = getHead(*q); QueueNode* node; QueueNode* temp; for(node = head->first; node != NULL; node = temp){ temp = node->next; free(node); } free(head); *q = NULL; return NULL; } uint ctl_queue_getEntrySizeX(ppcvoid q){ return getHead(*q)->size; } pcvoid ctl_queue_getX(ppcvoid q){ return *q; } int ctl_queue_isEmptyX(ppcvoid q){ return (getHead(*q)->first == NULL ? 1 : 0); } pcvoid ctl_queue_addX(ppvoid q, pcvoid data){ QueueHead* head = getHead(*q); if(head->first == NULL){ head->first = (QueueNode*)ctl_malloc(getSize(*q)); head->last = head->first; *q = pVoid(head->first->buf); }else{ head->last->next = (QueueNode*)ctl_malloc(getSize(*q)); head->last = head->last->next; } head->last->head = head; head->last->next = NULL; memcpy(head->last->buf, data, head->size); return pVoid(head->last->buf); } int ctl_queue_delX(ppvoid q){ QueueHead* head = getHead(*q); QueueNode* temp = head->first; head->first = head->first->next; free(temp); if(head->first == NULL){ head->last = NULL; *q = pVoid(head->data.buf); return 1; }else{ *q = pVoid(head->first->buf); return 0; } } pvoid ctl_queue_copyX(ppcvoid q, ppvoid q2){ ctl_queue_initX(q2, getHead(q)->size); if(!ctl_queue_isEmpty(q)){ QueueNode* node = getHead(q)->first; for( ; node != NULL; node = node->next){ ctl_queue_addX(q2, node->buf); } } return *q2; }