Imported Upstream version 1.0.1
[platform/upstream/iotivity.git] / resource / csdk / connectivity / common / src / ulinklist.c
1 /* ****************************************************************
2  *
3  * Copyright 2015 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ******************************************************************/
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include "ulinklist.h"
23 #include "logger.h"
24 #include "oic_malloc.h"
25 #include "caadapterutils.h"
26
27 /**
28  * Logging tag for module name.
29  */
30 #define TAG "ULINKLIST"
31
32 u_linklist_t *u_linklist_create()
33 {
34     u_linklist_t *header = (u_linklist_t *)OICMalloc(sizeof(u_linklist_t));
35     if (!header)
36     {
37         OIC_LOG(ERROR, TAG, "Out of memory");
38         return NULL;
39     }
40     header->list=NULL;
41     header->size=0;
42     return header;
43 }
44
45 CAResult_t u_linklist_add_head(u_linklist_t *linklist, void *data)
46 {
47     VERIFY_NON_NULL(linklist, TAG, "list is null");
48     VERIFY_NON_NULL(data, TAG, "data is null");
49
50     u_linklist_data_t *add_node = NULL;
51     add_node = (u_linklist_data_t *) OICMalloc(sizeof(u_linklist_data_t));
52     if (NULL == add_node)
53     {
54         OIC_LOG(DEBUG, TAG, "LinklistAdd FAIL, memory allocation failed");
55         return CA_MEMORY_ALLOC_FAILED;
56     }
57     add_node->data = data;
58     add_node->next = linklist->list;
59     linklist->list = add_node;
60     linklist->size += 1;
61     return CA_STATUS_OK;
62 }
63
64 CAResult_t u_linklist_add(u_linklist_t *linklist, void *data)
65 {
66     VERIFY_NON_NULL(linklist, TAG, "list is null");
67     VERIFY_NON_NULL(data, TAG, "data is null");
68
69     u_linklist_data_t *add_node = NULL;
70     u_linklist_data_t *node = linklist->list;
71     add_node = (u_linklist_data_t *) OICMalloc(sizeof(u_linklist_data_t));
72     if (NULL == add_node)
73     {
74         OIC_LOG(DEBUG, TAG, "LinklistAdd FAIL, memory allocation failed");
75         return CA_MEMORY_ALLOC_FAILED;
76     }
77
78     add_node->data = data;
79     add_node->next = NULL;
80
81     if (NULL == node)
82     {
83         linklist->list = add_node;
84         linklist->size += 1;
85     }
86     else
87     {
88         //else loop through the list and find the last node, insert next to it
89         while (true)
90         {
91             if(node->next == NULL)
92             {
93                 node->next = add_node;
94                 linklist->size += 1;
95                 break;
96             }
97             node = node->next;
98         };
99     }
100
101     return CA_STATUS_OK;
102 }
103
104 CAResult_t u_linklist_free(u_linklist_t **linklist)
105 {
106     VERIFY_NON_NULL(linklist, TAG, "linklist is null");
107     if (!(*linklist))
108     {
109         OIC_LOG(DEBUG, TAG, "List is already Empty");
110         return CA_STATUS_OK;
111     }
112
113     u_linklist_data_t *free_node=NULL;
114     while((*linklist)->size)
115     {
116         free_node = (*linklist)->list;
117         (*linklist)->list = (*linklist)->list->next;
118
119         if(free_node != NULL)
120         {
121             OICFree(free_node);
122             free_node=NULL;
123         }
124
125         (*linklist)->size -= 1;
126     }
127
128     OICFree(*linklist);
129     *linklist=NULL;
130
131     return CA_STATUS_OK;
132 }
133
134 CAResult_t u_linklist_remove(u_linklist_t *linklist, u_linklist_iterator_t **iter)
135 {
136     VERIFY_NON_NULL(linklist, TAG, "list is null");
137     VERIFY_NON_NULL(iter, TAG, "iterator is null");
138
139     if (NULL == *iter)
140     {
141         return CA_STATUS_INVALID_PARAM;
142     }
143
144     // When node to be deleted is head node
145     if (linklist->list == *iter)
146     {
147         // store address of next node
148         linklist->list = linklist->list->next;
149
150         // free memory
151         linklist->size -=1;
152         OICFree(*iter);
153
154         *iter = linklist->list;
155
156         return CA_STATUS_OK;
157     }
158
159
160     // When not first node, follow the normal deletion process find the previous node
161     u_linklist_data_t *prev = linklist->list;
162     while(NULL != prev->next && prev->next != *iter)
163     {
164         prev = prev->next;
165     }
166
167     // Check if node really exists in Linked List
168     if (NULL == prev->next)
169     {
170         OIC_LOG(ERROR, TAG, " Given node is not present in Linked List\n");
171         return CA_STATUS_FAILED;
172     }
173
174     // Remove node from Linked List
175     prev->next = prev->next->next;
176     linklist->size -=1;
177     OICFree(*iter);
178     *iter = prev->next;
179
180     return CA_STATUS_OK;
181 }
182
183
184 uint32_t u_linklist_length(const u_linklist_t *linklist)
185 {
186     if (NULL == linklist)
187     {
188         OIC_LOG(ERROR, TAG, "linklist is NULL");
189         return 0;
190     }
191     return linklist->size;
192 }
193
194 void u_linklist_init_iterator(const u_linklist_t *linklist, u_linklist_iterator_t **iter)
195 {
196     VERIFY_NON_NULL_VOID(linklist, TAG, "list is null");
197     VERIFY_NON_NULL_VOID(iter, TAG, "iterator is null");
198
199     *iter = linklist->list;
200 }
201
202 void *u_linklist_get_data(const u_linklist_iterator_t *iter)
203 {
204     VERIFY_NON_NULL_RET(iter, TAG, "iterator is null", NULL);
205
206     return iter->data;
207 }
208
209 void *u_linklist_get_next(u_linklist_iterator_t **iter)
210 {
211     VERIFY_NON_NULL_RET(iter, TAG, "iterator is null", NULL);
212     *iter = (*iter)->next;
213
214     if (NULL != *iter)
215     {
216         return (*iter)->data;
217     }
218     else
219     {
220         return NULL;
221     }
222 }