replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / csdk / connectivity / common / src / uqueue.c
1 /******************************************************************
2  *
3  * Copyright 2014 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 "uqueue.h"
21
22 #include <stddef.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include "logger.h"
26 #include "oic_malloc.h"
27
28 /**
29  * @def NO_MESSAGES
30  * @brief Number of messages in the queue
31  */
32 #define NO_MESSAGES 0
33
34 /**
35  * @def TAG
36  * @brief Logging tag for module name
37  */
38 #define TAG "UQUEUE"
39
40 u_queue_t *u_queue_create()
41 {
42     u_queue_t *queuePtr = (u_queue_t *) OICMalloc(sizeof(u_queue_t));
43     if (NULL == queuePtr)
44     {
45         OIC_LOG(DEBUG, TAG, "QueueCreate FAIL");
46         return NULL;
47     }
48
49     queuePtr->count = NO_MESSAGES;
50     queuePtr->element = NULL;
51
52     return queuePtr;
53 }
54
55 CAResult_t u_queue_add_element(u_queue_t *queue, u_queue_message_t *message)
56 {
57     u_queue_element *element = NULL;
58     u_queue_element *ptr = NULL;
59
60     if (NULL == queue)
61     {
62         OIC_LOG(DEBUG, TAG, "QueueAddElement FAIL, Invalid Queue");
63         return CA_STATUS_FAILED;
64     }
65
66     if (NULL == message)
67     {
68         OIC_LOG(DEBUG, TAG, "QueueAddElement : FAIL, NULL Message");
69         return CA_STATUS_FAILED;
70     }
71
72     element = (u_queue_element *) OICMalloc(sizeof(u_queue_element));
73     if (NULL == element)
74     {
75         OIC_LOG(DEBUG, TAG, "QueueAddElement FAIL, memory allocation failed");
76         return CA_MEMORY_ALLOC_FAILED;
77     }
78
79     element->message = message;
80     element->next = NULL;
81
82     ptr = queue->element;
83
84     if (NULL != ptr)
85     {
86         while (NULL != ptr->next)
87         {
88             ptr = ptr->next;
89         }
90
91         ptr->next = element;
92         queue->count++;
93
94         OIC_LOG_V(DEBUG, TAG, "Queue Count : %d", queue->count);
95     }
96     else
97     {
98         if (NO_MESSAGES != queue->count)
99         {
100             OIC_LOG(DEBUG, TAG, "QueueAddElement : FAIL, count is not zero");
101
102             /* error in queue, free the allocated memory*/
103             OICFree(element);
104             return CA_STATUS_FAILED;
105         }
106
107         queue->element = element;
108         queue->count++;
109         OIC_LOG_V(DEBUG, TAG, "Queue Count : %d", queue->count);
110     }
111
112     return CA_STATUS_OK;
113 }
114
115 u_queue_message_t *u_queue_get_element(u_queue_t *queue)
116 {
117     u_queue_element *element = NULL;
118     u_queue_message_t *message = NULL;
119
120     if (NULL == queue)
121     {
122         OIC_LOG(DEBUG, TAG, "QueueGetElement FAIL, Invalid Queue");
123         return NULL;
124     }
125
126     element = queue->element;
127
128     if (NULL == element)
129     {
130         return NULL;
131     }
132
133     queue->element = element->next;
134     queue->count--;
135
136     message = element->message;
137     OICFree(element);
138     return message;
139 }
140
141 CAResult_t u_queue_remove_element(u_queue_t *queue)
142 {
143     u_queue_element *next = NULL;
144     u_queue_element *remove = NULL;
145
146     if (NULL == queue)
147     {
148         OIC_LOG(DEBUG, TAG, "QueueRemoveElement FAIL, Invalid Queue");
149         return CA_STATUS_FAILED;
150     }
151
152     remove = queue->element;
153
154     if (NULL == remove)
155     {
156         OIC_LOG(DEBUG, TAG, "QueueRemoveElement : no messages");
157         return CA_STATUS_OK;
158     }
159
160     next = remove->next;
161
162     OICFree(remove->message);
163     OICFree(remove);
164
165     queue->element = next;
166     queue->count--;
167
168     return CA_STATUS_OK;
169 }
170
171 uint32_t u_queue_get_size(u_queue_t *queue)
172 {
173     if (NULL == queue)
174     {
175         OIC_LOG(DEBUG, TAG, "QueueGetSize FAIL, Invalid Queue");
176         return NO_MESSAGES;
177     }
178
179     return queue->count;
180 }
181
182 CAResult_t u_queue_reset(u_queue_t *queue)
183 {
184     if (NULL == queue)
185     {
186         OIC_LOG(DEBUG, TAG, "QueueReset FAIL, Invalid Queue");
187         return CA_STATUS_FAILED;
188     }
189
190     if (NO_MESSAGES == queue->count)
191     {
192         OIC_LOG(DEBUG, TAG, "QueueReset, no elements in the queue");
193         return CA_STATUS_OK;
194     }
195
196     while (NULL != queue->element)
197     {
198        u_queue_remove_element(queue);
199     }
200
201     if (NO_MESSAGES != queue->count)
202     {
203         OIC_LOG(DEBUG, TAG, "QueueReset : FAIL, count is non zero");
204         return CA_STATUS_FAILED;
205     }
206
207     return CA_STATUS_OK;
208
209 }
210
211 CAResult_t u_queue_delete(u_queue_t *queue)
212 {
213     CAResult_t error = CA_STATUS_FAILED;
214
215     if (NULL == queue)
216     {
217         OIC_LOG(DEBUG, TAG, "QueueDelete FAIL, Invalid Queue");
218         return CA_STATUS_FAILED;
219     }
220
221     error = u_queue_reset(queue);
222     if (error != CA_STATUS_OK)
223     {
224         OIC_LOG(DEBUG, TAG, "QueueDelete : FAIL, error in QueueReset");
225         return error;
226     }
227
228     OICFree(queue);
229     return (CA_STATUS_OK);
230 }
231
232 u_queue_message_t *u_queue_get_head(u_queue_t *queue)
233 {
234     if (NULL == queue)
235     {
236         OIC_LOG(DEBUG, TAG, "QueueGetHead FAIL, Invalid Queue");
237         return NULL;
238     }
239
240     if (NULL == queue->element)
241     {
242         OIC_LOG(DEBUG, TAG, "QueueGetHead : no messages in queue");
243         return NULL;
244     }
245     return queue->element->message;
246 }
247
248 CAResult_t u_queue_remove_req_elements(u_queue_t *queue,
249                                        QueueContextDataDestroy callback, void *ctx,
250                                        QueueDataDestroyFunction destroy)
251 {
252     if (NULL == queue)
253     {
254         OIC_LOG(DEBUG, TAG, "QueueRemoveReqElement FAIL, Invalid Queue");
255         return CA_STATUS_FAILED;
256     }
257
258     if (NULL == callback)
259     {
260         OIC_LOG(DEBUG, TAG, "QueueRemoveReqElement FAIL, NULL callback");
261         return CA_STATUS_FAILED;
262     }
263
264     u_queue_element *cur = queue->element;
265     u_queue_element *prev = NULL;
266     u_queue_element *remove = NULL;
267
268     while (NULL != cur)
269     {
270         if (cur->message && callback(cur->message->msg, cur->message->size, ctx))
271         {
272             remove = cur;
273             if (NULL != prev)
274             {
275                 prev->next = cur->next;
276             }
277             else
278             {
279                 queue->element = cur->next;
280             }
281             cur = cur->next;
282             if (NULL != destroy)
283             {
284                 destroy(remove->message->msg, remove->message->size);
285             }
286             else
287             {
288                 OICFree(remove->message->msg);
289             }
290             OICFree(remove->message);
291             OICFree(remove);
292             queue->count--;
293         }
294         else
295         {
296             prev = cur;
297             cur = cur->next;
298         }
299     }
300     return CA_STATUS_OK;
301 }
302