Final fix memleaks in GkClient codes, same for Timer codes.
[asterisk/asterisk.git] / addons / ooh323c / src / dlist.c
1 /*
2  * Copyright (C) 1997-2005 by Objective Systems, Inc.
3  *
4  * This software is furnished under an open source license and may be 
5  * used and copied only in accordance with the terms of this license. 
6  * The text of the license may generally be found in the root 
7  * directory of this installation in the COPYING file.  It 
8  * can also be viewed online at the following URL:
9  *
10  *   http://www.obj-sys.com/open/license.html
11  *
12  * Any redistributions of this file including modified versions must 
13  * maintain this copyright notice.
14  *
15  *****************************************************************************/
16
17 #include "asterisk.h"
18 #include "asterisk/lock.h"
19
20 #include "ooasn1.h"
21
22 void dListInit (DList* pList)
23 {
24    if (pList) {
25       pList->count = 0;
26       pList->head = (DListNode*) 0;
27       pList->tail = (DListNode*) 0;
28    }
29 }
30
31 DListNode* dListAppend (OOCTXT* pctxt, DList* pList, void* pData)
32 {
33    DListNode* pListNode = (DListNode*) 
34       memAlloc (pctxt, sizeof(DListNode));
35
36    if (0 != pListNode) {
37       pListNode->data = pData;
38       pListNode->next = (DListNode*) 0;
39       if (0 != pList->tail) {
40          pList->tail->next = pListNode;
41          pListNode->prev = pList->tail;
42       }
43       if (0 == pList->head) {
44          pList->head = pListNode;
45          pListNode->prev = (DListNode*) 0;
46       }
47       pList->tail = pListNode;
48       pList->count++;
49    }
50
51    return pListNode;
52 }
53
54 DListNode* dListAppendNode (OOCTXT* pctxt, DList* pList, void* pData)
55 {
56    DListNode* pListNode = 
57       (DListNode*) (((char*)pData) - sizeof(DListNode));
58
59    if (0 != pListNode) {
60       pListNode->data = pData;
61       pListNode->next = (DListNode*) 0;
62       if (0 != pList->tail) {
63          pList->tail->next = pListNode;
64          pListNode->prev = pList->tail;
65       }
66       if (0 == pList->head) {
67          pList->head = pListNode;
68          pListNode->prev = (DListNode*) 0;
69       }
70       pList->tail = pListNode;
71       pList->count++;
72    }
73
74    return pListNode;
75 }
76
77 /* Delete the head node from the list and return the data item stored   */
78 /* in that node..                                                       */
79
80 void* dListDeleteHead (OOCTXT* pctxt, DList* pList)
81 {
82    DListNode* pNode = (0 != pList) ? pList->head : 0;
83    if (0 != pNode) {
84       void* pdata = pNode->data;
85       dListRemove (pList, pNode);
86       memFreePtr (pctxt, pNode);
87       return pdata;
88    }
89    return 0;
90 }
91
92 /* Free all nodes, but not the data */
93 void dListFreeNodes (OOCTXT* pctxt, DList* pList)
94 {
95    DListNode* pNode, *pNextNode;
96
97    for (pNode = pList->head; pNode != 0; pNode = pNextNode) {
98       pNextNode = pNode->next;
99       memFreePtr (pctxt, pNode);
100    }
101    pList->count = 0;
102    pList->head = pList->tail = 0;
103 }
104
105 /* Free all nodes and their data */
106 void dListFreeAll (OOCTXT* pctxt, DList* pList)
107 {
108    DListNode* pNode, *pNextNode;
109
110    for (pNode = pList->head; pNode != 0; pNode = pNextNode) {
111       pNextNode = pNode->next;
112       
113       memFreePtr (pctxt, pNode->data);
114       memFreePtr (pctxt, pNode);
115    }
116    pList->count = 0;
117    pList->head = pList->tail = 0;
118 }
119
120 /* Remove node from list. Node is not freed */
121 void dListRemove (DList* pList, DListNode* node)
122 {
123    if(node->next != 0) {
124       node->next->prev = node->prev;
125    }
126    else { /* tail */
127       pList->tail = node->prev;
128    }
129    if(node->prev != 0) {
130       node->prev->next = node->next;
131    }
132    else { /* head */
133       pList->head = node->next;
134    }
135    pList->count--;
136 }
137
138 void dListFindAndRemove(struct OOCTXT* pctxt, DList* pList, void *data)
139 {
140    DListNode *pNode, *pNextNode;
141    for(pNode = pList->head; pNode !=0; pNode = pNextNode){
142       pNextNode = pNode->next;
143       if(pNode->data == data) /* pointer comparison*/
144          break;
145    }
146    if(pNode) {
147       dListRemove(pList, pNode);
148       memFreePtr(pctxt, pNode);
149    }
150 }
151     
152 DListNode* dListFindByIndex (DList* pList, int index) 
153 {
154    DListNode* curNode;
155    int i;
156
157    if(index >= (int)pList->count) return 0;
158    for(i = 0, curNode = pList->head; i < index && curNode != 0; i++) {
159       curNode = curNode->next;
160    }
161    return curNode;
162 }
163
164 /* Insert item before given node */
165
166 DListNode* dListInsertBefore 
167 (OOCTXT* pctxt, DList* pList, DListNode* node, const void* pData)
168 {
169    DListNode* pListNode = (DListNode*) memAlloc (pctxt, sizeof(DListNode));
170   
171    if (0 != pListNode) {
172       pListNode->data = (void*)pData;
173
174       if (node == 0) { /* insert before end (as last element) */
175          pListNode->next = (DListNode*) 0;
176          if (0 != pList->tail) {
177             pList->tail->next = pListNode;
178             pListNode->prev = pList->tail;
179          }
180          if (0 == pList->head) {
181             pList->head = pListNode;
182             pListNode->prev = (DListNode*) 0;
183          }
184          pList->tail = pListNode;
185       }
186       else if (node == pList->head) { /* insert as head (head case) */
187          pListNode->next = pList->head;
188          pListNode->prev = (DListNode*) 0;
189          if(pList->head != 0) {
190             pList->head->prev = pListNode;
191          }
192          if(pList->tail == 0) {
193             pList->tail = pListNode;
194          }
195          pList->head = pListNode;
196       }
197       else { /* other cases */
198          pListNode->next = node;
199          pListNode->prev = node->prev;
200          node->prev = pListNode;
201          /* here, pListNode->prev always should be non-zero,
202           * because if pListNode->prev is zero - it is head case (see above).
203           */
204          pListNode->prev->next = pListNode;
205       }
206
207       pList->count++;
208    }
209
210    return pListNode;
211 }
212
213 /* Insert item after given node */
214
215 DListNode* dListInsertAfter 
216 (OOCTXT* pctxt, DList* pList, DListNode* node, const void* pData)
217 {
218    DListNode* pListNode = (DListNode*) memAlloc (pctxt, sizeof(DListNode));
219
220    if (0 != pListNode) {
221       pListNode->data = (void*)pData;
222
223       if (node == 0) { /* insert as head (as first element) */
224          pListNode->next = pList->head;
225          pListNode->prev = (DListNode*) 0;
226          if (pList->head != 0) {
227             pList->head->prev = pListNode;
228          }
229          if (pList->tail == 0) {
230             pList->tail = pListNode;
231          }
232          pList->head = pListNode;
233       }
234       else if (node == pList->tail) { /* insert as tail (as last element) */
235          pListNode->next = (DListNode*) 0;
236          if (0 != pList->tail) {
237             pList->tail->next = pListNode;
238             pListNode->prev = pList->tail;
239          }
240          if (0 == pList->head) {
241             pList->head = pListNode;
242             pListNode->prev = (DListNode*) 0;
243          }
244          pList->tail = pListNode;
245       }
246       else { /* other cases */
247          pListNode->next = node->next;
248          pListNode->prev = node;
249          node->next = pListNode;
250          /* here, pListNode->next always should be non-zero,
251           * because if pListNode->next is zero - it is tail case (see above).
252           */
253          pListNode->next->prev = pListNode;
254       }
255
256       pList->count++;
257    }
258
259    return pListNode;
260 }
261