Commit | Line | Data |
---|---|---|
a7868768 BA |
1 | /** |
2 | * @file List.c | |
3 | */ | |
4 | ||
5 | #include "cgds/List.h" | |
6 | ||
7 | //////////////// | |
8 | // List logic // | |
9 | //////////////// | |
10 | ||
11 | void _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 | ||
19 | List* _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 | ||
26 | List* 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 | 38 | bool list_empty(List* list) |
a7868768 | 39 | { |
e45132ac | 40 | return (list->size == 0); |
a7868768 BA |
41 | } |
42 | ||
43 | UInt list_size(List* list) | |
44 | { | |
e45132ac | 45 | return list->size; |
a7868768 BA |
46 | } |
47 | ||
48 | void* _list_get(ListCell* listCell) | |
49 | { | |
e45132ac | 50 | return listCell->data; |
a7868768 BA |
51 | } |
52 | ||
53 | void _list_set(List* list, ListCell* listCell, void* data) | |
54 | { | |
e45132ac | 55 | memcpy(listCell->data, data, list->dataSize); |
a7868768 BA |
56 | } |
57 | ||
58 | void _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 | ||
70 | void _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 | ||
85 | void _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 | ||
100 | void _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 | ||
108 | void _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 | ||
116 | void 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 | ||
131 | void list_remove_front(List* list) | |
132 | { | |
e45132ac | 133 | list_remove(list, list->head); |
a7868768 BA |
134 | } |
135 | ||
136 | void list_remove_back(List* list) | |
137 | { | |
e45132ac | 138 | list_remove(list, list->tail); |
a7868768 BA |
139 | } |
140 | ||
141 | void 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 | ||
154 | void 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 | ||
164 | ListIterator* 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 | ||
173 | void listI_reset_head(ListIterator* listI) | |
174 | { | |
e45132ac | 175 | listI->current = listI->list->head; |
a7868768 BA |
176 | } |
177 | ||
178 | void listI_reset_tail(ListIterator* listI) | |
179 | { | |
e45132ac | 180 | listI->current = listI->list->tail; |
a7868768 BA |
181 | } |
182 | ||
1ff641f9 | 183 | bool listI_has_data(ListIterator* listI) |
a7868768 | 184 | { |
e45132ac | 185 | return (listI->current != NULL); |
a7868768 BA |
186 | } |
187 | ||
188 | void listI_remove(ListIterator* listI, Direction direction) | |
189 | { | |
e45132ac BA |
190 | ListCell* toTrash = listI->current; |
191 | switch (direction) | |
192 | { | |
1d60b10a BA |
193 | case FORWARD: |
194 | listI->current = listI->current->next; | |
195 | break; | |
196 | case BACKWARD: | |
197 | listI->current = listI->current->prev; | |
198 | break; | |
e45132ac BA |
199 | } |
200 | list_remove(listI->list, toTrash); | |
a7868768 BA |
201 | } |
202 | ||
203 | void listI_move_next(ListIterator* listI) | |
204 | { | |
e45132ac BA |
205 | if (listI->current != NULL) |
206 | listI->current = listI->current->next; | |
a7868768 BA |
207 | } |
208 | ||
209 | void listI_move_prev(ListIterator* listI) | |
210 | { | |
e45132ac BA |
211 | if (listI->current != NULL) |
212 | listI->current = listI->current->prev; | |
a7868768 BA |
213 | } |
214 | ||
215 | void listI_destroy(ListIterator* listI) | |
216 | { | |
e45132ac | 217 | safe_free(listI); |
a7868768 | 218 | } |