1 /* Copyright (C) 2009 Trend Micro Inc.
4 * This program is a free software; you can redistribute it
5 * and/or modify it under the terms of the GNU General Public
6 * License (version 2) as published by the FSF - Free Software
10 /* Common API for dealing with lists */
16 * Returns NULL on error
18 OSList *OSList_Create()
22 my_list = (OSList *) calloc(1, sizeof(OSList));
27 my_list->first_node = NULL;
28 my_list->last_node = NULL;
29 my_list->cur_node = NULL;
30 my_list->currently_size = 0;
31 my_list->max_size = 0;
32 my_list->free_data_function = NULL;
37 /* Set the maximum number of elements in the list
38 * Returns 0 on error or 1 on success
40 int OSList_SetMaxSize(OSList *list, int max_size)
46 /* Minimum size is 1 */
51 list->max_size = max_size;
56 /* Set the pointer to the function to free the memory data */
57 int OSList_SetFreeDataPointer(OSList *list, void (free_data_function)(void *))
63 list->free_data_function = free_data_function;
67 /* Get first node from list
68 * Returns null on invalid list
70 OSListNode *OSList_GetFirstNode(OSList *list)
72 list->cur_node = list->first_node;
73 return (list->first_node);
76 /* Get last node from list
77 * Returns null on invalid list
79 OSListNode *OSList_GetLastNode(OSList *list)
81 list->cur_node = list->last_node;
82 return (list->last_node);
85 /* Get next node from list
86 * Returns null on invalid list or at the end of the list
88 OSListNode *OSList_GetNextNode(OSList *list)
90 if (list->cur_node == NULL) {
94 list->cur_node = list->cur_node->next;
96 return (list->cur_node);
99 /* Get the prev node from the list
100 * Returns NULL at the beginning
102 OSListNode *OSList_GetPrevNode(OSList *list)
104 if (list->cur_node == NULL) {
108 list->cur_node = list->cur_node->prev;
110 return (list->cur_node);
113 /* Get the currently node
114 * Returns null when no currently node is available
116 OSListNode *OSList_GetCurrentlyNode(OSList *list)
118 return (list->cur_node);
121 /* Delete first node from list */
122 void OSList_DeleteOldestNode(OSList *list)
126 if (list->first_node) {
127 next = list->first_node->next;
131 list->last_node = next;
134 free(list->first_node);
135 list->first_node = next;
137 merror("%s: No Oldest node to delete", __local_name);
143 /* Delete this node from list
144 * Pointer goes to the next node available
146 void OSList_DeleteThisNode(OSList *list, OSListNode *thisnode)
151 if (thisnode == NULL) {
155 prev = thisnode->prev;
156 next = thisnode->next;
158 /* Setting the previous node of the next one
159 * and the next node of the previous one.. :)
166 list->last_node = prev;
169 list->first_node = next;
171 list->last_node = NULL;
172 list->first_node = NULL;
175 /* Free the node memory */
178 /* Set the currently node to the next one */
179 list->cur_node = next;
181 list->currently_size--;
184 /* Delete current node from list
185 * Pointer goes to the next node available
187 void OSList_DeleteCurrentlyNode(OSList *list)
192 if (list->cur_node == NULL) {
196 prev = list->cur_node->prev;
197 next = list->cur_node->next;
199 /* Setting the previous node of the next one
200 * and the next node of the previous one.. :)
207 list->last_node = prev;
210 list->first_node = next;
212 list->last_node = NULL;
213 list->first_node = NULL;
216 /* Free the node memory */
217 free(list->cur_node);
219 /* Set the current node to the next one */
220 list->cur_node = next;
222 list->currently_size--;
225 /* Add data to the list
226 * Returns 1 on success and 0 on failure
228 int OSList_AddData(OSList *list, void *data)
232 /* Allocate memory for new node */
233 newnode = (OSListNode *) calloc(1, sizeof(OSListNode));
235 merror(MEM_ERROR, __local_name, errno, strerror(errno));
239 newnode->prev = list->last_node;
240 newnode->next = NULL;
241 newnode->data = data;
243 /* If we don't have a first node, assign it */
244 if (!list->first_node) {
245 list->first_node = newnode;
248 /* If we have a last node, set the next to new node */
249 if (list->last_node) {
250 list->last_node->next = newnode;
253 /* newnode becomes last node */
254 list->last_node = newnode;
256 /* Increment list size */
257 list->currently_size++;
259 /* Ff currently_size higher than the maximum size, remove the
260 * oldest node (first one)
262 if (list->max_size) {
263 if (list->currently_size > list->max_size && list->first_node->next) {
264 /* Remove first node */
265 newnode = list->first_node->next;
267 newnode->prev = NULL;
269 /* Clear any internal memory using the pointer */
270 if (list->free_data_function) {
271 list->free_data_function(list->first_node->data);
274 /* Clear the memory */
275 free(list->first_node);
277 /* First node become the ex first->next */
278 list->first_node = newnode;
280 /* Reduce list size */
281 list->currently_size--;