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