Merge branch 'master' into cloud-interface
[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         //Size is more but no node in linked list
117         if(!(*linklist)->list)
118         {
119             OIC_LOG(ERROR, TAG, "Trying to free Empty List!!");
120             return CA_STATUS_FAILED;
121         }
122
123         free_node = (*linklist)->list;
124         (*linklist)->list = (*linklist)->list->next;
125         OICFree(free_node);
126         free_node=NULL;
127         (*linklist)->size -= 1;
128     }
129
130     OICFree(*linklist);
131     *linklist=NULL;
132
133     return CA_STATUS_OK;
134 }
135
136 CAResult_t u_linklist_remove(u_linklist_t *linklist, u_linklist_iterator_t **iter)
137 {
138     VERIFY_NON_NULL(linklist, TAG, "list is null");
139     VERIFY_NON_NULL(iter, TAG, "iterator is null");
140
141     if (NULL == *iter)
142     {
143         return CA_STATUS_INVALID_PARAM;
144     }
145
146     // When node to be deleted is head node
147     if (linklist->list == *iter)
148     {
149         // store address of next node
150         linklist->list = linklist->list->next;
151
152         // free memory
153         linklist->size -=1;
154         OICFree(*iter);
155
156         *iter = linklist->list;
157
158         return CA_STATUS_OK;
159     }
160
161
162     // When not first node, follow the normal deletion process find the previous node
163     u_linklist_data_t *prev = linklist->list;
164     while(NULL != prev->next && prev->next != *iter)
165     {
166         prev = prev->next;
167     }
168
169     // Check if node really exists in Linked List
170     if (NULL == prev->next)
171     {
172         OIC_LOG(ERROR, TAG, " Given node is not present in Linked List\n");
173         return CA_STATUS_FAILED;
174     }
175
176     // Remove node from Linked List
177     prev->next = prev->next->next;
178     linklist->size -=1;
179     OICFree(*iter);
180     *iter = prev->next;
181
182     return CA_STATUS_OK;
183 }
184
185
186 uint32_t u_linklist_length(const u_linklist_t *linklist)
187 {
188     if (NULL == linklist)
189     {
190         OIC_LOG(ERROR, TAG, "linklist is NULL");
191         return 0;
192     }
193     return linklist->size;
194 }
195
196 void u_linklist_init_iterator(const u_linklist_t *linklist, u_linklist_iterator_t **iter)
197 {
198     VERIFY_NON_NULL_VOID(linklist, TAG, "list is null");
199     VERIFY_NON_NULL_VOID(iter, TAG, "iterator is null");
200
201     *iter = linklist->list;
202 }
203
204 void *u_linklist_get_data(const u_linklist_iterator_t *iter)
205 {
206     VERIFY_NON_NULL_RET(iter, TAG, "iterator is null", NULL);
207
208     return iter->data;
209 }
210
211 void *u_linklist_get_next(u_linklist_iterator_t **iter)
212 {
213     VERIFY_NON_NULL_RET(iter, TAG, "iterator is null", NULL);
214     *iter = (*iter)->next;
215
216     if (NULL != *iter)
217     {
218         return (*iter)->data;
219     }
220     else
221     {
222         return NULL;
223     }
224 }