Now using 2 spaces instead of tabs. Fix copyright years. Improve documentation
[cgds.git] / src / List.c
CommitLineData
a7868768
BA
1/**
2 * @file List.c
3 */
4
5#include "cgds/List.h"
6
7////////////////
8// List logic //
9////////////////
10
11void _list_init(List* list, size_t dataSize)
12{
e45132ac
BA
13 list->size = 0;
14 list->dataSize = dataSize;
15 list->head = NULL;
16 list->tail = NULL;
a7868768
BA
17}
18
19List* _list_new(size_t dataSize)
20{
e45132ac
BA
21 List* list = (List*) safe_malloc(sizeof (List));
22 _list_init(list, dataSize);
23 return list;
a7868768
BA
24}
25
26List* list_copy(List* list)
27{
e45132ac
BA
28 List* listCopy = _list_new(list->dataSize);
29 ListCell* listCell = list->head;
30 while (listCell != NULL)
31 {
32 _list_insert_back(listCopy, listCell->data);
33 listCell = listCell->next;
34 }
35 return listCopy;
a7868768
BA
36}
37
1ff641f9 38bool list_empty(List* list)
a7868768 39{
e45132ac 40 return (list->size == 0);
a7868768
BA
41}
42
43UInt list_size(List* list)
44{
e45132ac 45 return list->size;
a7868768
BA
46}
47
48void* _list_get(ListCell* listCell)
49{
e45132ac 50 return listCell->data;
a7868768
BA
51}
52
53void _list_set(List* list, ListCell* listCell, void* data)
54{
e45132ac 55 memcpy(listCell->data, data, list->dataSize);
a7868768
BA
56}
57
58void _list_insert_first_element(List* list, void* data)
59{
e45132ac
BA
60 ListCell* newListCell = (ListCell*) safe_malloc(sizeof (ListCell));
61 newListCell->data = safe_malloc(list->dataSize);
62 memcpy(newListCell->data, data, list->dataSize);
63 newListCell->prev = NULL;
64 newListCell->next = NULL;
65 list->head = newListCell;
66 list->tail = newListCell;
67 list->size = 1;
a7868768
BA
68}
69
70void _list_insert_before(List* list, ListCell* listCell, void* data)
71{
e45132ac
BA
72 ListCell* newListCell = (ListCell*) safe_malloc(sizeof (ListCell));
73 newListCell->data = safe_malloc(list->dataSize);
74 memcpy(newListCell->data, data, list->dataSize);
75 newListCell->prev = listCell->prev;
76 newListCell->next = listCell;
77 if (listCell->prev != NULL)
78 listCell->prev->next = newListCell;
79 else
80 list->head = newListCell;
81 listCell->prev = newListCell;
82 list->size++;
a7868768
BA
83}
84
85void _list_insert_after(List* list, ListCell* listCell, void* data)
86{
e45132ac
BA
87 ListCell* newListCell = (ListCell*) safe_malloc(sizeof (ListCell));
88 newListCell->data = safe_malloc(list->dataSize);
89 memcpy(newListCell->data, data, list->dataSize);
90 newListCell->prev = listCell;
91 newListCell->next = listCell->next;
92 if (listCell->next != NULL)
93 listCell->next->prev = newListCell;
94 else
95 list->tail = newListCell;
96 listCell->next = newListCell;
97 list->size++;
a7868768
BA
98}
99
100void _list_insert_front(List* list, void* data)
101{
e45132ac
BA
102 if (list->head != NULL)
103 _list_insert_before(list, list->head, data);
104 else
105 _list_insert_first_element(list, data);
a7868768
BA
106}
107
108void _list_insert_back(List* list, void* data)
109{
e45132ac
BA
110 if (list->tail != NULL)
111 _list_insert_after(list, list->tail, data);
112 else
113 _list_insert_first_element(list, data);
a7868768
BA
114}
115
116void list_remove(List* list, ListCell* listCell)
117{
e45132ac
BA
118 if (listCell->prev != NULL)
119 listCell->prev->next = listCell->next;
120 else
121 list->head = listCell->next;
122 if (listCell->next != NULL)
123 listCell->next->prev = listCell->prev;
124 else
125 list->tail = listCell->prev;
126 safe_free(listCell->data);
127 safe_free(listCell);
128 list->size--;
a7868768
BA
129}
130
131void list_remove_front(List* list)
132{
e45132ac 133 list_remove(list, list->head);
a7868768
BA
134}
135
136void list_remove_back(List* list)
137{
e45132ac 138 list_remove(list, list->tail);
a7868768
BA
139}
140
141void list_clear(List* list)
142{
e45132ac
BA
143 ListCell* current = list->head;
144 while (current != NULL)
145 {
146 safe_free(current->data);
147 ListCell* nextListCell = current->next;
148 safe_free(current);
149 current = nextListCell;
150 }
151 _list_init(list, list->dataSize);
a7868768
BA
152}
153
154void list_destroy(List* list)
155{
e45132ac
BA
156 list_clear(list);
157 safe_free(list);
a7868768
BA
158}
159
160////////////////////
161// Iterator logic //
162////////////////////
163
164ListIterator* list_get_iterator(List* list)
165{
e45132ac
BA
166 ListIterator* listI = (ListIterator*) safe_malloc(sizeof (ListIterator));
167 listI->list = list;
168 listI->current = NULL;
169 listI_reset_head(listI);
170 return listI;
a7868768
BA
171}
172
173void listI_reset_head(ListIterator* listI)
174{
e45132ac 175 listI->current = listI->list->head;
a7868768
BA
176}
177
178void listI_reset_tail(ListIterator* listI)
179{
e45132ac 180 listI->current = listI->list->tail;
a7868768
BA
181}
182
1ff641f9 183bool listI_has_data(ListIterator* listI)
a7868768 184{
e45132ac 185 return (listI->current != NULL);
a7868768
BA
186}
187
188void listI_remove(ListIterator* listI, Direction direction)
189{
e45132ac
BA
190 ListCell* toTrash = listI->current;
191 switch (direction)
192 {
193 case FORWARD:
194 listI->current = listI->current->next;
195 break;
196 case BACKWARD:
197 listI->current = listI->current->prev;
198 break;
199 }
200 list_remove(listI->list, toTrash);
a7868768
BA
201}
202
203void listI_move_next(ListIterator* listI)
204{
e45132ac
BA
205 if (listI->current != NULL)
206 listI->current = listI->current->next;
a7868768
BA
207}
208
209void listI_move_prev(ListIterator* listI)
210{
e45132ac
BA
211 if (listI->current != NULL)
212 listI->current = listI->current->prev;
a7868768
BA
213}
214
215void listI_destroy(ListIterator* listI)
216{
e45132ac 217 safe_free(listI);
a7868768 218}