Fix invalid memory access
[platform/core/iot/iotcon.git] / lib / icl-resource-interfaces.c
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include <stdlib.h>
17 #include <string.h>
18 #include <errno.h>
19 #include <glib.h>
20
21 #include "iotcon-types.h"
22 #include "ic-utils.h"
23 #include "icl.h"
24 #include "icl-resource-interfaces.h"
25
26 iotcon_resource_interfaces_h icl_resource_interfaces_ref(
27                 iotcon_resource_interfaces_h ifaces)
28 {
29         RETV_IF(NULL == ifaces, NULL);
30         RETV_IF(ifaces->ref_count <= 0, NULL);
31
32         ifaces->ref_count++;
33
34         return ifaces;
35 }
36
37
38 API int iotcon_resource_interfaces_create(iotcon_resource_interfaces_h *ret_ifaces)
39 {
40         iotcon_resource_interfaces_h ifaces;
41
42         RETV_IF(false == ic_utils_check_oic_feature_supported(), IOTCON_ERROR_NOT_SUPPORTED);
43         RETV_IF(NULL == ret_ifaces, IOTCON_ERROR_INVALID_PARAMETER);
44
45         ifaces = calloc(1, sizeof(struct icl_resource_ifaces));
46         if (NULL == ifaces) {
47                 ERR("calloc() Fail(%d)", errno);
48                 return IOTCON_ERROR_OUT_OF_MEMORY;
49         }
50
51         ifaces->ref_count = 1;
52
53         *ret_ifaces = ifaces;
54
55         return IOTCON_ERROR_NONE;
56 }
57
58
59 API void iotcon_resource_interfaces_destroy(iotcon_resource_interfaces_h ifaces)
60 {
61         RET_IF(NULL == ifaces);
62
63         ifaces->ref_count--;
64
65         if (0 == ifaces->ref_count) {
66                 g_list_free_full(ifaces->iface_list, free);
67                 free(ifaces);
68         }
69 }
70
71
72 static int _icl_resource_interfaces_strcmp(const void *a, const void *b)
73 {
74         return strcmp(a, b);
75 }
76
77
78 static bool _icl_resource_interfaces_duplicate_check(iotcon_resource_interfaces_h ifaces,
79                 const char *iface)
80 {
81         GList *node = NULL;
82
83         RETV_IF(NULL == ifaces, false);
84         RETV_IF(NULL == iface, false);
85
86         node = g_list_find_custom(ifaces->iface_list, iface, _icl_resource_interfaces_strcmp);
87         if (NULL == node)
88                 return false;
89
90         return true;
91 }
92
93
94 /* Duplicate strings are not allowed. */
95 API int iotcon_resource_interfaces_add(iotcon_resource_interfaces_h ifaces,
96                 const char *iface)
97 {
98         char *resource_iface;
99
100         RETV_IF(false == ic_utils_check_oic_feature_supported(), IOTCON_ERROR_NOT_SUPPORTED);
101         RETV_IF(NULL == ifaces, IOTCON_ERROR_INVALID_PARAMETER);
102         RETV_IF(NULL == iface, IOTCON_ERROR_INVALID_PARAMETER);
103         RETVM_IF(1 < ifaces->ref_count, IOTCON_ERROR_INVALID_PARAMETER,
104                         "Don't modify it. It is already set.");
105
106         if (true == _icl_resource_interfaces_duplicate_check(ifaces, iface)) {
107                 ERR("%s is already contained.", iface);
108                 return IOTCON_ERROR_INVALID_PARAMETER;
109         }
110
111         resource_iface = strdup(iface);
112         if (NULL == resource_iface) {
113                 ERR("strdup() Fail");
114                 return IOTCON_ERROR_INVALID_PARAMETER;
115         }
116
117         ifaces->iface_list = g_list_append(ifaces->iface_list, resource_iface);
118
119         return IOTCON_ERROR_NONE;
120 }
121
122
123 API int iotcon_resource_interfaces_remove(iotcon_resource_interfaces_h ifaces,
124                 const char *iface)
125 {
126         GList *node;
127         char *node_data;
128
129         RETV_IF(false == ic_utils_check_oic_feature_supported(), IOTCON_ERROR_NOT_SUPPORTED);
130         RETV_IF(NULL == ifaces, IOTCON_ERROR_INVALID_PARAMETER);
131         RETV_IF(NULL == iface, IOTCON_ERROR_INVALID_PARAMETER);
132         RETVM_IF(1 < ifaces->ref_count, IOTCON_ERROR_INVALID_PARAMETER,
133                         "Don't modify it. It is already set.");
134
135         node = g_list_find_custom(ifaces->iface_list, iface, _icl_resource_interfaces_strcmp);
136         if (NULL == node) {
137                 ERR("g_list_find_custom() Fail");
138                 return IOTCON_ERROR_NO_DATA;
139         }
140
141         node_data = node->data;
142         ifaces->iface_list = g_list_delete_link(ifaces->iface_list, node);
143         free(node_data);
144
145         return IOTCON_ERROR_NONE;
146 }
147
148
149 API int iotcon_resource_interfaces_foreach(iotcon_resource_interfaces_h ifaces,
150                 iotcon_resource_interfaces_foreach_cb cb, void *user_data)
151 {
152         GList *node;
153
154         RETV_IF(false == ic_utils_check_oic_feature_supported(), IOTCON_ERROR_NOT_SUPPORTED);
155         RETV_IF(NULL == ifaces, IOTCON_ERROR_INVALID_PARAMETER);
156         RETV_IF(NULL == cb, IOTCON_ERROR_INVALID_PARAMETER);
157
158         for (node = ifaces->iface_list; node; node = node->next) {
159                 if (IOTCON_FUNC_STOP == cb((const char*)node->data, user_data))
160                         break;
161         }
162
163         return IOTCON_ERROR_NONE;
164 }
165
166
167 API int iotcon_resource_interfaces_clone(iotcon_resource_interfaces_h src,
168                 iotcon_resource_interfaces_h *dest)
169 {
170         GList *node;
171         char *resource_iface;
172         iotcon_resource_interfaces_h resource_ifaces;
173
174         RETV_IF(false == ic_utils_check_oic_feature_supported(), IOTCON_ERROR_NOT_SUPPORTED);
175         RETV_IF(NULL == src, IOTCON_ERROR_INVALID_PARAMETER);
176         RETV_IF(NULL == dest, IOTCON_ERROR_INVALID_PARAMETER);
177
178         resource_ifaces = calloc(1, sizeof(struct icl_resource_ifaces));
179         if (NULL == resource_ifaces) {
180                 ERR("calloc() Fail(%d)", errno);
181                 return IOTCON_ERROR_OUT_OF_MEMORY;
182         }
183
184         for (node = src->iface_list; node; node = node->next) {
185                 resource_iface = ic_utils_strdup(node->data);
186                 if (NULL == resource_iface) {
187                         iotcon_resource_interfaces_destroy(resource_ifaces);
188                         ERR("ic_utils_strdup() Fail");
189                         return IOTCON_ERROR_OUT_OF_MEMORY;
190                 }
191                 resource_ifaces->iface_list = g_list_append(resource_ifaces->iface_list,
192                                 resource_iface);
193         }
194
195         resource_ifaces->ref_count = 1;
196
197         *dest = resource_ifaces;
198
199         return IOTCON_ERROR_NONE;
200 }
201
202
203 /* counting from 0 */
204 const char* icl_resource_interfaces_get_nth_data(iotcon_resource_interfaces_h ifaces,
205                 int index)
206 {
207         return g_list_nth_data(ifaces->iface_list, index);
208 }
209
210
211 unsigned int icl_resource_interfaces_get_length(iotcon_resource_interfaces_h ifaces)
212 {
213         return g_list_length(ifaces->iface_list);
214 }