19e5e4605892de81d369fcbe0329d30bd2c74c3a
[ossec-hids.git] / src / shared / list_op.c
1 /* @(#) $Id$ */
2
3 /* Copyright (C) 2009 Trend Micro Inc.
4  * All right reserved.
5  *
6  * This program is a free software; you can redistribute it
7  * and/or modify it under the terms of the GNU General Public
8  * License (version 2) as published by the FSF - Free Software
9  * Foundation
10  */
11
12 /* Common API for dealing with lists */ 
13
14
15 #include "shared.h"
16
17
18 /* Create the list 
19  * Return NULL on error
20  */
21 OSList *OSList_Create()
22 {
23     OSList *my_list;
24
25     my_list = calloc(1, sizeof(OSList));
26     if(!my_list)
27         return(NULL);
28     
29     my_list->first_node = NULL;
30     my_list->last_node = NULL;
31     my_list->cur_node = NULL;
32     my_list->currently_size = 0;
33     my_list->max_size = 0;
34     my_list->free_data_function = NULL;
35     
36     return(my_list);
37 }
38
39
40 /* Set the maximum number of elements
41  * in the list. Returns 0 on error or
42  * 1 on success.
43  */
44 int OSList_SetMaxSize(OSList *list, int max_size)
45 {
46     if(!list)
47     {
48         return(0);
49     }
50     
51     /* Minimum size is 1 */
52     if(max_size <= 1)
53     {
54         return(0);
55     }
56
57     list->max_size = max_size;
58
59     return(1);
60 }
61
62
63 /* Set the pointer to the function to free the memory
64  * data.
65  */
66 int OSList_SetFreeDataPointer(OSList *list, void *free_data_function)
67 {
68     if(!list)
69     {
70         return(0);
71     }
72     
73     list->free_data_function = free_data_function;
74     return(1);
75 }
76
77
78 /* Get first node from list
79  * Returns null on invalid list
80  */
81 OSListNode *OSList_GetFirstNode(OSList *list)
82 {
83     list->cur_node = list->first_node;
84     return(list->first_node);
85 }
86
87
88 /* Get last node from list
89  * Returns null on invalid list
90  */
91 OSListNode *OSList_GetLastNode(OSList *list)
92 {
93     list->cur_node = list->last_node;
94     return(list->last_node);
95 }
96
97
98 /* Get next node from list
99  * Returns null on invalid list or at
100  * the end of the list
101  */
102 OSListNode *OSList_GetNextNode(OSList *list)
103 {
104     if(list->cur_node == NULL)
105         return(NULL);
106         
107     list->cur_node = list->cur_node->next;
108     
109     return(list->cur_node);
110 }
111   
112
113 /* Get the prev node from the list
114  * Returns NULL at the beginning
115  */
116 OSListNode *OSList_GetPrevNode(OSList *list)
117 {
118     if(list->cur_node == NULL)
119         return(NULL);
120
121     list->cur_node = list->cur_node->prev;
122
123     return(list->cur_node);
124 }
125     
126
127 /* Get the currently node.
128  * Returns null when no currently node is available
129  */  
130 OSListNode *OSList_GetCurrentlyNode(OSList *list)
131 {
132     return(list->cur_node);
133 }
134
135
136 /* Delete first node from list */
137 void OSList_DeleteOldestNode(OSList *list)
138 {
139     OSListNode *next;
140     
141     if(list->first_node)
142     {
143         next = list->first_node->next;
144         if(next)
145             next->prev = NULL;
146         else
147             list->last_node = next;    
148         
149         free(list->first_node);
150         list->first_node = next;
151     }
152     else
153     {
154         merror("%s: No Oldest node to delete", __local_name);
155     }
156
157     return;
158 }
159
160
161 /* Delete this node from list
162  * Pointer goes to the next node available.
163  */
164 void OSList_DeleteThisNode(OSList *list, OSListNode *thisnode)
165 {
166     OSListNode *prev;
167     OSListNode *next;
168
169     if(thisnode == NULL)
170         return;
171
172     prev = thisnode->prev;
173     next = thisnode->next;
174
175     /* Setting the previous node of the next one
176      * and the next node of the previous one.. :)
177      */
178     if(prev && next)
179     {
180         prev->next = next;
181         next->prev = prev;
182     }
183     else if(prev)
184     {
185         prev->next = NULL;
186         list->last_node = prev;
187     }
188     else if(next)
189     {
190         next->prev = NULL;
191         list->first_node = next;
192     }
193     else
194     {
195         list->last_node = NULL;
196         list->first_node = NULL;
197     }
198
199
200     /* Freeing the node memory */
201     free(thisnode);
202
203     /* Setting the currently node to the next one */
204     list->cur_node = next;
205
206     list->currently_size--;
207 }
208
209
210 /* Delete currently node from list
211  * Pointer goes to the next node available.
212  * Returns void
213  */
214 void OSList_DeleteCurrentlyNode(OSList *list)
215 {
216     OSListNode *prev;
217     OSListNode *next;
218    
219     if(list->cur_node == NULL)
220         return;
221     
222     prev = list->cur_node->prev;
223     next = list->cur_node->next;
224
225      
226     /* Setting the previous node of the next one
227      * and the next node of the previous one.. :)
228      */
229     if(prev && next)
230     {
231         prev->next = next;
232         next->prev = prev;
233     }
234     else if(prev)
235     {
236         prev->next = NULL;
237         list->last_node = prev;
238     }
239     else if(next)
240     {
241         next->prev = NULL;
242         list->first_node = next;
243     }
244     else
245     {
246         list->last_node = NULL;
247         list->first_node = NULL;
248     }
249             
250     /* Freeing the node memory */
251     free(list->cur_node);
252
253     /* Setting the currently node to the next one */
254     list->cur_node = next;
255
256     list->currently_size--;
257 }
258
259
260 /* Add data to the list
261  * Returns 1 on success and 0 on failure
262  */
263 int OSList_AddData(OSList *list, void *data)
264 {
265     OSListNode *newnode;    
266
267
268     /* Allocating memory for new node */
269     newnode = calloc(1, sizeof(OSListNode));
270     if(!newnode)
271     {
272         merror(MEM_ERROR, __local_name);
273         return(0);
274     }
275
276     newnode->prev = list->last_node;
277     newnode->next = NULL;
278     newnode->data = data;
279
280
281     /* If we don't havea first node, assign it */
282     if(!list->first_node)
283     {
284         list->first_node = newnode;
285     }
286     
287     /* If we have a last node, set the next to new node */
288     if(list->last_node)
289     {
290         list->last_node->next = newnode;
291     }
292     
293     
294     /* newnode become last node */
295     list->last_node = newnode;
296
297     /* Increment list size */
298     list->currently_size++;
299     
300     /* if currently_size higher than the maximum size, remove the
301      * oldest node (first one)
302      */
303     if(list->max_size)
304     {
305         if(list->currently_size > list->max_size)
306         {
307             /* Remove first node */
308             newnode = list->first_node->next;
309
310             newnode->prev = NULL;
311
312             /* Clearing any internal memory using the pointer */
313             if(list->free_data_function)
314             {
315                 list->free_data_function(list->first_node->data);
316             }
317             
318             /* Clearing the memory */
319             free(list->first_node);
320             
321             /* First node become the ex first->next */
322             list->first_node = newnode;
323
324             /* Reduce list size */
325             list->currently_size--;
326         }
327     }
328     
329     return(1);
330 }
331
332 /* EOF */