summaryrefslogtreecommitdiffstats
path: root/libcnary/node_list.c
diff options
context:
space:
mode:
Diffstat (limited to 'libcnary/node_list.c')
-rw-r--r--libcnary/node_list.c130
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 @@
1/*
2 * node_list.c
3 *
4 * Created on: Mar 8, 2011
5 * Author: posixninja
6 */
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11
12#include "list.h"
13#include "node.h"
14#include "node_list.h"
15
16void node_list_destroy(node_list_t* list) {
17 if(list != NULL) {
18 list_destroy((list_t*) list);
19 }
20}
21
22node_list_t* node_list_create(node_t* node) {
23 node_list_t* list = (node_list_t*) malloc(sizeof(node_list_t));
24 if(list == NULL) {
25 return NULL;
26 }
27 memset(list, '\0', sizeof(node_list_t));
28
29 // Initialize structure
30 list_init((list_t*) list);
31 list->count = 0;
32 return list;
33}
34
35int node_list_add(node_list_t* list, node_t* node) {
36 if (!list || !node) return -1;
37
38 // Find the last element in the list
39 node_t* last = list->end;
40
41 // Setup our new node as the new last element
42 node->next = NULL;
43 node->prev = last;
44
45 // Set the next element of our old "last" element
46 last->next = node;
47
48 // Set the lists prev to the new last element
49 list->end = node;
50
51 // Increment our node count for this list
52 list->count++;
53 return 0;
54}
55
56int node_list_insert(node_list_t* list, unsigned int index, node_t* node) {
57 if (!list || !node) return -1;
58 if (index >= list->count) {
59 return node_list_add(list, node);
60 }
61
62 // Get the first element in the list
63 node_t* cur = list->begin;
64
65 unsigned int pos = 0;
66 node_t* prev = NULL;
67
68 if (index > 0) {
69 while (pos < index) {
70 prev = cur;
71 cur = cur->next;
72 pos++;
73 }
74 }
75
76 if (prev) {
77 // Set previous node
78 node->prev = prev;
79 // Set next node of our new node to next node of the previous node
80 node->next = prev->next;
81 // Set next node of previous node to our new node
82 prev->next = node;
83 } else {
84 node->prev = NULL;
85 // get old first element in list
86 node->next = list->begin;
87 // set new node as first element in list
88 list->begin = node;
89 }
90
91 if (node->next == NULL) {
92 // Set the lists prev to the new last element
93 list->end = node;
94 } else {
95 // set prev of the new next element to our node
96 node->next->prev = node;
97 }
98
99 // Increment our node count for this list
100 list->count++;
101 return 0;
102}
103
104int node_list_remove(node_list_t* list, node_t* node) {
105 if (!list || !node) return -1;
106 if (list->count == 0) return -1;
107
108 node_t* n;
109 for (n = list->begin; n; n = n->next) {
110 if (node == n) {
111 node_t* newnode = node->next;
112 if (node->prev) {
113 node->prev->next = newnode;
114 if (newnode) {
115 newnode->prev = node->prev;
116 }
117 } else {
118 // we just removed the first element
119 if (newnode) {
120 newnode->prev = NULL;
121 }
122 list->begin = newnode;
123 }
124 list->count--;
125 return 0;
126 }
127 }
128 return -1;
129}
130