/* * 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 #include #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; }