diff options
Diffstat (limited to 'libcnary/node_list.c')
-rw-r--r-- | libcnary/node_list.c | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/libcnary/node_list.c b/libcnary/node_list.c new file mode 100644 index 0000000..8464af2 --- /dev/null +++ b/libcnary/node_list.c @@ -0,0 +1,130 @@ +/* + * node_list.c + * + * Created on: Mar 8, 2011 + * Author: posixninja + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "list.h" +#include "node.h" +#include "node_list.h" + +void node_list_destroy(node_list_t* list) { + if(list != NULL) { + list_destroy((list_t*) list); + } +} + +node_list_t* node_list_create(node_t* node) { + node_list_t* list = (node_list_t*) malloc(sizeof(node_list_t)); + if(list == NULL) { + return NULL; + } + memset(list, '\0', sizeof(node_list_t)); + + // Initialize structure + list_init((list_t*) list); + list->count = 0; + return list; +} + +int node_list_add(node_list_t* list, node_t* node) { + if (!list || !node) return -1; + + // Find the last element in the list + node_t* last = list->end; + + // Setup our new node as the new last element + node->next = NULL; + node->prev = last; + + // Set the next element of our old "last" element + last->next = node; + + // Set the lists prev to the new last element + list->end = node; + + // Increment our node count for this list + list->count++; + return 0; +} + +int node_list_insert(node_list_t* list, unsigned int index, node_t* node) { + if (!list || !node) return -1; + if (index >= list->count) { + return node_list_add(list, node); + } + + // Get the first element in the list + node_t* cur = list->begin; + + unsigned int pos = 0; + node_t* prev = NULL; + + if (index > 0) { + while (pos < index) { + prev = cur; + cur = cur->next; + pos++; + } + } + + if (prev) { + // Set previous node + node->prev = prev; + // Set next node of our new node to next node of the previous node + node->next = prev->next; + // Set next node of previous node to our new node + prev->next = node; + } else { + node->prev = NULL; + // get old first element in list + node->next = list->begin; + // set new node as first element in list + list->begin = node; + } + + if (node->next == NULL) { + // Set the lists prev to the new last element + list->end = node; + } else { + // set prev of the new next element to our node + node->next->prev = node; + } + + // Increment our node count for this list + list->count++; + return 0; +} + +int node_list_remove(node_list_t* list, node_t* node) { + if (!list || !node) return -1; + if (list->count == 0) return -1; + + node_t* n; + for (n = list->begin; n; n = n->next) { + if (node == n) { + node_t* newnode = node->next; + if (node->prev) { + node->prev->next = newnode; + if (newnode) { + newnode->prev = node->prev; + } + } else { + // we just removed the first element + if (newnode) { + newnode->prev = NULL; + } + list->begin = newnode; + } + list->count--; + return 0; + } + } + return -1; +} + |