• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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