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