• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "platform/include/list.h"
17 #include <stdlib.h>
18 #include "platform/include/dl_list.h"
19 #include "platform/include/platform_def.h"
20 
21 typedef struct ListNode {
22     DL_LIST node;
23     List *list;  // Used in func ListGetNextNode, might de deleted in future version.
24     void *data;
25 } ListNodeInternal;
26 
27 typedef struct List {
28     DL_LIST dlList;
29     int len;
30     FreeDataCb cb;
31 } ListInternal;
32 
ListGetFirstNodeInt(const List * list)33 static ListNode *ListGetFirstNodeInt(const List *list)
34 {
35     ASSERT(list);
36     if (list->len == 0) {
37         return NULL;
38     }
39 
40     return DL_LIST_ENTRY(list->dlList.pstNext, ListNode, node);
41 }
42 
ListCreate(FreeDataCb cb)43 List *ListCreate(FreeDataCb cb)
44 {
45     List *newList = (List *)calloc(1, (sizeof(List)));
46     if (newList != NULL) {
47         DL_ListInit(&newList->dlList);
48         newList->cb = cb;
49     }
50     return newList;
51 }
52 
ListFreeNode(List * list,ListNode * node)53 NO_SANITIZE("cfi") static ListNode *ListFreeNode(List *list, ListNode *node)
54 {
55     ASSERT(list);
56     ASSERT(node);
57     ListNode *next = ListGetNextNode(node);
58     DL_ListDelete(&node->node);
59     if (list->cb) {
60         list->cb(node->data);
61     }
62     free(node);
63     list->len--;
64 
65     return next;
66 }
67 
ListClear(List * list)68 void ListClear(List *list)
69 {
70     ASSERT(list);
71     if (list->len > 0) {
72         for (ListNode *node = ListGetFirstNode(list); node;) {
73             node = ListFreeNode(list, node);
74         }
75     }
76     list->len = 0;
77 }
78 
ListDelete(List * list)79 void ListDelete(List *list)
80 {
81     if (list == NULL) {
82         return;
83     }
84 
85     ListClear(list);
86     free(list);
87 }
88 
ListGetSize(const List * list)89 int32_t ListGetSize(const List *list)
90 {
91     ASSERT(list);
92     return list->len;
93 }
94 
ListAddFirst(List * list,void * data)95 void ListAddFirst(List *list, void *data)
96 {
97     ASSERT(list);
98     ASSERT(data);
99     ListNode *node = (ListNode *)calloc(1, sizeof(ListNode));
100     if (node != NULL) {
101         node->data = data;
102         node->list = list;
103         DL_ListHeadInsert(&list->dlList, &node->node);
104         list->len++;
105     }
106 }
107 
ListAddLast(List * list,void * data)108 void ListAddLast(List *list, void *data)
109 {
110     ASSERT(list);
111     ASSERT(data);
112     ListNode *node = (ListNode *)calloc(1, sizeof(ListNode));
113     if (node != NULL) {
114         node->data = data;
115         node->list = list;
116         DL_ListTailInsert(&list->dlList, &node->node);
117         list->len++;
118     }
119 }
120 
ListForEachData(const List * list,const ListCmpFunc cmp,void * parameter)121 void *ListForEachData(const List *list, const ListCmpFunc cmp, void *parameter)
122 {
123     ASSERT(list);
124     ASSERT(cmp);
125     if (list->len == 0) {
126         return NULL;
127     }
128 
129     for (ListNode *node = ListGetFirstNodeInt(list); node;) {
130         ListNode *next = ListGetNextNode(node);
131         if (cmp(node->data, parameter)) {
132             return node->data;
133         }
134         node = next;
135     }
136     return NULL;
137 }
138 
ListGetFirstNode(const List * list)139 ListNode *ListGetFirstNode(const List *list)
140 {
141     ASSERT(list);
142     if (list->len == 0) {
143         return NULL;
144     }
145 
146     return DL_LIST_ENTRY(list->dlList.pstNext, ListNode, node);
147 }
148 
ListGetLastNode(const List * list)149 ListNode *ListGetLastNode(const List *list)
150 {
151     ASSERT(list);
152     if (list->len == 0) {
153         return NULL;
154     }
155     return DL_LIST_ENTRY(list->dlList.pstPrev, ListNode, node);
156 }
157 
ListGetNextNode(const ListNode * listNode)158 ListNode *ListGetNextNode(const ListNode *listNode)
159 {
160     ASSERT(listNode);
161     if (listNode == ListGetLastNode(listNode->list)) {
162         return NULL;
163     }
164     return DL_LIST_ENTRY(listNode->node.pstNext, ListNode, node);
165 }
166 
ListGetNodeData(const ListNode * node)167 void *ListGetNodeData(const ListNode *node)
168 {
169     ASSERT(node);
170     return node->data;
171 }
172 
ListRemoveNode(List * list,void * data)173 bool ListRemoveNode(List *list, void *data)
174 {
175     ASSERT(list);
176     ASSERT(data);
177     if (list->len == 0) {
178         return false;
179     }
180     for (ListNode *node = ListGetFirstNode(list); node; node = ListGetNextNode(node)) {
181         if (node->data == data) {
182             ListFreeNode(list, node);
183             return true;
184         }
185     }
186     return false;
187 }
188 
ListRemoveFirst(List * list)189 bool ListRemoveFirst(List *list)
190 {
191     ASSERT(list);
192     if (list->len == 0) {
193         return false;
194     }
195 
196     ListNode *first = ListGetFirstNode(list);
197     if (!ListRemoveNode(list, first->data)) {
198         return false;
199     }
200     return true;
201 }
202 
ListRemoveLast(List * list)203 bool ListRemoveLast(List *list)
204 {
205     ASSERT(list);
206     if (list->len == 0) {
207         return false;
208     }
209 
210     ListNode *last = ListGetLastNode(list);
211     if (!ListRemoveNode(list, last->data)) {
212         return false;
213     }
214     return true;
215 }
216 
ListIsEmpty(const List * list)217 bool ListIsEmpty(const List* list)
218 {
219     ASSERT(list);
220     return (list->len == 0);
221 }
222