diff options
Diffstat (limited to 'addons/ooh323c/src/dlist.c')
-rw-r--r-- | addons/ooh323c/src/dlist.c | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/addons/ooh323c/src/dlist.c b/addons/ooh323c/src/dlist.c new file mode 100644 index 000000000..52fc87d42 --- /dev/null +++ b/addons/ooh323c/src/dlist.c @@ -0,0 +1,256 @@ +/* + * Copyright (C) 1997-2005 by Objective Systems, Inc. + * + * This software is furnished under an open source license and may be + * used and copied only in accordance with the terms of this license. + * The text of the license may generally be found in the root + * directory of this installation in the COPYING file. It + * can also be viewed online at the following URL: + * + * http://www.obj-sys.com/open/license.html + * + * Any redistributions of this file including modified versions must + * maintain this copyright notice. + * + *****************************************************************************/ + +#include "ooasn1.h" + +void dListInit (DList* pList) +{ + if (pList) { + pList->count = 0; + pList->head = (DListNode*) 0; + pList->tail = (DListNode*) 0; + } +} + +DListNode* dListAppend (OOCTXT* pctxt, DList* pList, void* pData) +{ + DListNode* pListNode = (DListNode*) + memAlloc (pctxt, sizeof(DListNode)); + + if (0 != pListNode) { + pListNode->data = pData; + pListNode->next = (DListNode*) 0; + if (0 != pList->tail) { + pList->tail->next = pListNode; + pListNode->prev = pList->tail; + } + if (0 == pList->head) { + pList->head = pListNode; + pListNode->prev = (DListNode*) 0; + } + pList->tail = pListNode; + pList->count++; + } + + return pListNode; +} + +DListNode* dListAppendNode (OOCTXT* pctxt, DList* pList, void* pData) +{ + DListNode* pListNode = + (DListNode*) (((char*)pData) - sizeof(DListNode)); + + if (0 != pListNode) { + pListNode->data = pData; + pListNode->next = (DListNode*) 0; + if (0 != pList->tail) { + pList->tail->next = pListNode; + pListNode->prev = pList->tail; + } + if (0 == pList->head) { + pList->head = pListNode; + pListNode->prev = (DListNode*) 0; + } + pList->tail = pListNode; + pList->count++; + } + + return pListNode; +} + +/* Delete the head node from the list and return the data item stored */ +/* in that node.. */ + +void* dListDeleteHead (OOCTXT* pctxt, DList* pList) +{ + DListNode* pNode = (0 != pList) ? pList->head : 0; + if (0 != pNode) { + void* pdata = pNode->data; + dListRemove (pList, pNode); + memFreePtr (pctxt, pNode); + return pdata; + } + return 0; +} + +/* Free all nodes, but not the data */ +void dListFreeNodes (OOCTXT* pctxt, DList* pList) +{ + DListNode* pNode, *pNextNode; + + for (pNode = pList->head; pNode != 0; pNode = pNextNode) { + pNextNode = pNode->next; + memFreePtr (pctxt, pNode); + } + pList->count = 0; + pList->head = pList->tail = 0; +} + +/* Free all nodes and their data */ +void dListFreeAll (OOCTXT* pctxt, DList* pList) +{ + DListNode* pNode, *pNextNode; + + for (pNode = pList->head; pNode != 0; pNode = pNextNode) { + pNextNode = pNode->next; + + memFreePtr (pctxt, pNode->data); + memFreePtr (pctxt, pNode); + } + pList->count = 0; + pList->head = pList->tail = 0; +} + +/* Remove node from list. Node is not freed */ +void dListRemove (DList* pList, DListNode* node) +{ + if(node->next != 0) { + node->next->prev = node->prev; + } + else { /* tail */ + pList->tail = node->prev; + } + if(node->prev != 0) { + node->prev->next = node->next; + } + else { /* head */ + pList->head = node->next; + } + pList->count--; +} + +void dListFindAndRemove(DList* pList, void *data) +{ + DListNode *pNode, *pNextNode; + for(pNode = pList->head; pNode !=0; pNode = pNextNode){ + pNextNode = pNode->next; + if(pNode->data == data) /* pointer comparison*/ + break; + } + if(pNode) + dListRemove(pList, pNode); +} + +DListNode* dListFindByIndex (DList* pList, int index) +{ + DListNode* curNode; + int i; + + if(index >= (int)pList->count) return 0; + for(i = 0, curNode = pList->head; i < index && curNode != 0; i++) { + curNode = curNode->next; + } + return curNode; +} + +/* Insert item before given node */ + +DListNode* dListInsertBefore +(OOCTXT* pctxt, DList* pList, DListNode* node, const void* pData) +{ + DListNode* pListNode = (DListNode*) memAlloc (pctxt, sizeof(DListNode)); + + if (0 != pListNode) { + pListNode->data = (void*)pData; + + if (node == 0) { /* insert before end (as last element) */ + pListNode->next = (DListNode*) 0; + if (0 != pList->tail) { + pList->tail->next = pListNode; + pListNode->prev = pList->tail; + } + if (0 == pList->head) { + pList->head = pListNode; + pListNode->prev = (DListNode*) 0; + } + pList->tail = pListNode; + } + else if (node == pList->head) { /* insert as head (head case) */ + pListNode->next = pList->head; + pListNode->prev = (DListNode*) 0; + if(pList->head != 0) { + pList->head->prev = pListNode; + } + if(pList->tail == 0) { + pList->tail = pListNode; + } + pList->head = pListNode; + } + else { /* other cases */ + pListNode->next = node; + pListNode->prev = node->prev; + node->prev = pListNode; + /* here, pListNode->prev always should be non-zero, + * because if pListNode->prev is zero - it is head case (see above). + */ + pListNode->prev->next = pListNode; + } + + pList->count++; + } + + return pListNode; +} + +/* Insert item after given node */ + +DListNode* dListInsertAfter +(OOCTXT* pctxt, DList* pList, DListNode* node, const void* pData) +{ + DListNode* pListNode = (DListNode*) memAlloc (pctxt, sizeof(DListNode)); + + if (0 != pListNode) { + pListNode->data = (void*)pData; + + if (node == 0) { /* insert as head (as first element) */ + pListNode->next = pList->head; + pListNode->prev = (DListNode*) 0; + if (pList->head != 0) { + pList->head->prev = pListNode; + } + if (pList->tail == 0) { + pList->tail = pListNode; + } + pList->head = pListNode; + } + else if (node == pList->tail) { /* insert as tail (as last element) */ + pListNode->next = (DListNode*) 0; + if (0 != pList->tail) { + pList->tail->next = pListNode; + pListNode->prev = pList->tail; + } + if (0 == pList->head) { + pList->head = pListNode; + pListNode->prev = (DListNode*) 0; + } + pList->tail = pListNode; + } + else { /* other cases */ + pListNode->next = node->next; + pListNode->prev = node; + node->next = pListNode; + /* here, pListNode->next always should be non-zero, + * because if pListNode->next is zero - it is tail case (see above). + */ + pListNode->next->prev = pListNode; + } + + pList->count++; + } + + return pListNode; +} + |