1 /*
2 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "hdf_slist.h"
10 #include "hdf_log.h"
11
12 #define HDF_LOG_TAG utils_slist
13
HdfSListInit(struct HdfSList * list)14 void HdfSListInit(struct HdfSList *list)
15 {
16 if (list != NULL) {
17 list->root = NULL;
18 }
19 }
20
HdfSListIsEmpty(const struct HdfSList * list)21 bool HdfSListIsEmpty(const struct HdfSList *list)
22 {
23 return ((list == NULL) || (list->root == NULL));
24 }
25
HdfSListSearch(const struct HdfSList * list,uint32_t keyValue,HdfSListSearchComparer comparer)26 struct HdfSListNode *HdfSListSearch(const struct HdfSList *list, uint32_t keyValue, HdfSListSearchComparer comparer)
27 {
28 struct HdfSListIterator it;
29 if (comparer == NULL) {
30 return NULL;
31 }
32 HdfSListIteratorInit(&it, list);
33 while (HdfSListIteratorHasNext(&it)) {
34 struct HdfSListNode *listNode = HdfSListIteratorNext(&it);
35 if (comparer(listNode, keyValue)) {
36 return listNode;
37 }
38 }
39 return NULL;
40 }
41
HdfSListGetLast(const struct HdfSList * list)42 struct HdfSListNode *HdfSListGetLast(const struct HdfSList *list)
43 {
44 struct HdfSListNode *last = NULL;
45 struct HdfSListNode *iterator = NULL;
46 if (list == NULL) {
47 return NULL;
48 }
49
50 for (iterator = list->root; iterator != NULL; iterator = iterator->next) {
51 last = iterator;
52 }
53 return last;
54 }
55
HdfSListAdd(struct HdfSList * list,struct HdfSListNode * link)56 void HdfSListAdd(struct HdfSList *list, struct HdfSListNode *link)
57 {
58 if (list == NULL || link == NULL) {
59 return;
60 }
61 link->next = list->root;
62 list->root = link;
63 }
64
HdfSListAddTail(struct HdfSList * list,struct HdfSListNode * link)65 void HdfSListAddTail(struct HdfSList *list, struct HdfSListNode *link)
66 {
67 struct HdfSListNode *iterator = NULL;
68 if (list == NULL || link == NULL) {
69 return;
70 }
71
72 for (iterator = (struct HdfSListNode *)list; iterator->next; iterator = iterator->next) {
73 if (iterator->next == link) {
74 return;
75 }
76 }
77
78 link->next = NULL;
79 iterator->next = link;
80 }
81
HdfSListAddOrder(struct HdfSList * list,struct HdfSListNode * link,HdfSListAddComparer comparer)82 bool HdfSListAddOrder(struct HdfSList *list, struct HdfSListNode *link, HdfSListAddComparer comparer)
83 {
84 struct HdfSListNode *iterator = NULL;
85 if (list == NULL || link == NULL || comparer == NULL) {
86 HDF_LOGE("input is invalid");
87 return false;
88 }
89 for (iterator = list->root; iterator; iterator = iterator->next) {
90 if (iterator == link) {
91 HDF_LOGE("link is already in list");
92 return false;
93 }
94 }
95 if (comparer(link, list->root)) {
96 link->next = list->root;
97 list->root = link;
98 return true;
99 }
100 for (iterator = list->root; iterator && iterator->next; iterator = iterator->next) {
101 if (comparer(iterator, link) && comparer(link, iterator->next)) {
102 link->next = iterator->next;
103 iterator->next = link;
104 return true;
105 }
106 }
107 if ((list->root == NULL) || (iterator == NULL)) {
108 link->next = NULL;
109 list->root = link;
110 } else {
111 link->next = NULL;
112 iterator->next = link;
113 }
114 return true;
115 }
116
HdfSListRemove(struct HdfSList * list,struct HdfSListNode * link)117 void HdfSListRemove(struct HdfSList *list, struct HdfSListNode *link)
118 {
119 struct HdfSListNode *iterator = NULL;
120 if (list == NULL || link == NULL) {
121 return;
122 }
123
124 for (iterator = (struct HdfSListNode *)list; iterator; iterator = iterator->next) {
125 if (iterator->next == link) {
126 iterator->next = link->next;
127 return;
128 }
129 }
130 }
131
HdfSListFlush(struct HdfSList * list,HdfSListDeleter deleter)132 void HdfSListFlush(struct HdfSList *list, HdfSListDeleter deleter)
133 {
134 struct HdfSListIterator iterator;
135 if (list == NULL) {
136 return;
137 }
138
139 HdfSListIteratorInit(&iterator, list);
140 while (HdfSListIteratorHasNext(&iterator)) {
141 void *listNode = (void *)HdfSListIteratorNext(&iterator);
142 HdfSListIteratorRemove(&iterator);
143 if (deleter != NULL) {
144 deleter(listNode);
145 }
146 }
147 }
148
HdfSListCount(const struct HdfSList * list)149 int HdfSListCount(const struct HdfSList *list)
150 {
151 struct HdfSListNode *iterator = NULL;
152 int counter = 0;
153 if (list == NULL) {
154 return counter;
155 }
156
157 for (iterator = (struct HdfSListNode *)list; iterator->next; iterator = iterator->next) {
158 counter++;
159 }
160 return counter;
161 }
162
HdfSListPeek(const struct HdfSList * list)163 struct HdfSListNode *HdfSListPeek(const struct HdfSList *list)
164 {
165 if (list == NULL) {
166 return NULL;
167 }
168
169 return list->root;
170 }
171
HdfSListNext(const struct HdfSListNode * link)172 struct HdfSListNode *HdfSListNext(const struct HdfSListNode *link)
173 {
174 if (link == NULL) {
175 return NULL;
176 }
177
178 return link->next;
179 }
180
HdfSListPop(struct HdfSList * list)181 struct HdfSListNode *HdfSListPop(struct HdfSList *list)
182 {
183 struct HdfSListNode *first = NULL;
184 if (list == NULL || list->root == NULL) {
185 return NULL;
186 }
187 first = list->root;
188 list->root = first->next;
189 return first;
190 }
191
HdfSListIteratorInit(struct HdfSListIterator * iterator,const struct HdfSList * list)192 void HdfSListIteratorInit(struct HdfSListIterator *iterator, const struct HdfSList *list)
193 {
194 if (iterator == NULL || list == NULL) {
195 if (iterator != NULL) {
196 iterator->stepOnNext = 0;
197 iterator->prev = NULL;
198 iterator->curr = NULL;
199 }
200 return;
201 }
202 iterator->stepOnNext = 0;
203 iterator->prev = (struct HdfSListNode *)list;
204 iterator->curr = list->root;
205 }
206
HdfSListIteratorHasNext(const struct HdfSListIterator * iterator)207 bool HdfSListIteratorHasNext(const struct HdfSListIterator *iterator)
208 {
209 if ((iterator == NULL) || (iterator->curr == NULL) || (iterator->prev == NULL)) {
210 return false;
211 }
212
213 if (!iterator->stepOnNext) {
214 return iterator->curr != NULL;
215 }
216
217 if (iterator->prev->next != iterator->curr) {
218 // current item has been removed
219 return iterator->prev->next != NULL;
220 }
221
222 // current items has not been removed
223 return iterator->curr->next != NULL;
224 }
225
HdfSListIteratorNext(struct HdfSListIterator * iterator)226 struct HdfSListNode *HdfSListIteratorNext(struct HdfSListIterator *iterator)
227 {
228 if (iterator == NULL || iterator->curr == NULL || iterator->prev == NULL) {
229 return NULL;
230 }
231
232 if (iterator->stepOnNext) {
233 if (iterator->prev->next == iterator->curr) {
234 iterator->prev = iterator->curr;
235 iterator->curr = iterator->curr->next;
236 } else {
237 // curr was removed from the list, set it again but don't advance prev
238 iterator->curr = iterator->prev->next;
239 }
240 } else {
241 iterator->stepOnNext = 1;
242 }
243
244 return iterator->curr;
245 }
246
HdfSListIteratorRemove(struct HdfSListIterator * iterator)247 void HdfSListIteratorRemove(struct HdfSListIterator *iterator)
248 {
249 if (iterator == NULL || iterator->curr == NULL || iterator->prev == NULL) {
250 return;
251 }
252
253 iterator->curr = iterator->curr->next;
254 iterator->prev->next = iterator->curr;
255 iterator->stepOnNext = 0;
256 }
257
HdfSListIteratorInsert(struct HdfSListIterator * iterator,struct HdfSListNode * link)258 void HdfSListIteratorInsert(struct HdfSListIterator *iterator, struct HdfSListNode *link)
259 {
260 if (iterator == NULL || link == NULL) {
261 return;
262 }
263
264 link->next = iterator->curr;
265 iterator->prev->next = link;
266 iterator->prev = link;
267 }
268
269