1 /*
2 * Copyright (C) 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 "linked_list.h"
17
18 #include "securec.h"
19
20 #include "adaptor_log.h"
21 #include "adaptor_memory.h"
22
23 #ifdef IAM_TEST_ENABLE
24 #define IAM_STATIC
25 #else
26 #define IAM_STATIC static
27 #endif
28
InsertNode(LinkedList * list,void * data)29 IAM_STATIC ResultCode InsertNode(LinkedList *list, void *data)
30 {
31 if (list == NULL) {
32 LOG_ERROR("list is null");
33 return RESULT_BAD_PARAM;
34 }
35 if (list->size == UINT32_MAX) {
36 LOG_ERROR("reach limit");
37 return RESULT_REACH_LIMIT;
38 }
39 LinkedListNode *node = Malloc(sizeof(LinkedListNode));
40 if (node == NULL) {
41 LOG_ERROR("no memory");
42 return RESULT_NO_MEMORY;
43 }
44 node->data = data;
45 node->next = list->head;
46 list->head = node;
47 list->size++;
48 return RESULT_SUCCESS;
49 }
50
RemoveNode(LinkedList * list,void * condition,MatchFunc matchFunc,bool destroyNode)51 IAM_STATIC ResultCode RemoveNode(LinkedList *list, void *condition, MatchFunc matchFunc, bool destroyNode)
52 {
53 if (list == NULL) {
54 LOG_ERROR("list is null");
55 return RESULT_BAD_PARAM;
56 }
57 if (matchFunc == NULL) {
58 LOG_ERROR("matchFunc is null");
59 return RESULT_BAD_PARAM;
60 }
61 LinkedListNode *pre = NULL;
62 LinkedListNode *node = list->head;
63 while (node != NULL) {
64 if (matchFunc(node->data, condition)) {
65 break;
66 }
67 pre = node;
68 node = node->next;
69 }
70 if (node == NULL) {
71 return RESULT_NOT_FOUND;
72 }
73 if (pre == NULL) {
74 list->head = node->next;
75 } else {
76 pre->next = node->next;
77 }
78 list->size--;
79 node->next = NULL;
80 if (destroyNode) {
81 if (list->destroyDataFunc != NULL) {
82 list->destroyDataFunc(node->data);
83 }
84 Free(node);
85 }
86 return RESULT_SUCCESS;
87 }
88
GetSize(LinkedList * list)89 IAM_STATIC uint32_t GetSize(LinkedList *list)
90 {
91 if (list == NULL) {
92 LOG_ERROR("list is null");
93 return 0;
94 }
95 return list->size;
96 }
97
IteratorHasNext(LinkedListIterator * iterator)98 IAM_STATIC bool IteratorHasNext(LinkedListIterator *iterator)
99 {
100 if (iterator == NULL) {
101 LOG_ERROR("iterator is null");
102 return false;
103 }
104 return iterator->current != NULL;
105 }
106
IteratorNext(LinkedListIterator * iterator)107 IAM_STATIC void *IteratorNext(LinkedListIterator *iterator)
108 {
109 if (!IteratorHasNext(iterator)) {
110 LOG_ERROR("reach end");
111 return NULL;
112 }
113 LinkedListNode *current = iterator->current;
114 iterator->current = current->next;
115 return current->data;
116 }
117
CreateIterator(struct LinkedList * list)118 IAM_STATIC LinkedListIterator *CreateIterator(struct LinkedList *list)
119 {
120 if (list == NULL) {
121 LOG_ERROR("list is null");
122 return NULL;
123 }
124 LinkedListIterator *iterator = (LinkedListIterator *)Malloc(sizeof(LinkedListIterator));
125 if (iterator == NULL) {
126 LOG_ERROR("malloc failed");
127 return NULL;
128 }
129 iterator->current = list->head;
130 iterator->hasNext = IteratorHasNext;
131 iterator->next = IteratorNext;
132 return iterator;
133 }
134
DestroyIterator(LinkedListIterator * iterator)135 IAM_STATIC void DestroyIterator(LinkedListIterator *iterator)
136 {
137 if (iterator == NULL) {
138 LOG_ERROR("iterator is null");
139 return;
140 }
141 Free(iterator);
142 }
143
CreateLinkedList(DestroyDataFunc destroyDataFunc)144 LinkedList *CreateLinkedList(DestroyDataFunc destroyDataFunc)
145 {
146 if (destroyDataFunc == NULL) {
147 LOG_ERROR("destroyDataFunc is null");
148 return NULL;
149 }
150 LinkedList *list = Malloc(sizeof(LinkedList));
151 if (list == NULL) {
152 LOG_ERROR("no memory");
153 return NULL;
154 }
155 list->size = 0;
156 list->head = NULL;
157 list->destroyDataFunc = destroyDataFunc;
158 list->getSize = GetSize;
159 list->insert = InsertNode;
160 list->remove = RemoveNode;
161 list->createIterator = CreateIterator;
162 list->destroyIterator = DestroyIterator;
163 return list;
164 }
165
DestroyLinkedListNode(const LinkedList * list,LinkedListNode * node)166 IAM_STATIC void DestroyLinkedListNode(const LinkedList *list, LinkedListNode *node)
167 {
168 if (node == NULL) {
169 LOG_ERROR("node is null");
170 return;
171 }
172 if ((list != NULL) && (list->destroyDataFunc != NULL)) {
173 list->destroyDataFunc(node->data);
174 }
175 Free(node);
176 }
177
DestroyLinkedList(LinkedList * list)178 void DestroyLinkedList(LinkedList *list)
179 {
180 if (list == NULL) {
181 LOG_ERROR("list is null");
182 return;
183 }
184 while (list->head != NULL) {
185 LinkedListNode *node = list->head;
186 list->head = node->next;
187 DestroyLinkedListNode(list, node);
188 }
189 Free(list);
190 }
191