fce11e79a4f33a45b9da39b6680a089e81917619
[platform/core/iot/iotcon.git] / lib / icl-state.c
1 /* Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <stdlib.h>
17 #include <glib.h>
18
19 #include "iotcon-types.h"
20 #include "ic-utils.h"
21 #include "icl.h"
22 #include "icl-list.h"
23 #include "icl-value.h"
24 #include "icl-representation.h"
25 #include "icl-state.h"
26
27 void icl_state_inc_ref_count(iotcon_state_h val)
28 {
29         RET_IF(NULL == val);
30         RETM_IF(val->ref_count < 0, "Invalid Count(%d)", val->ref_count);
31
32         val->ref_count++;
33 }
34
35
36 static bool _icl_state_dec_ref_count(iotcon_state_h val)
37 {
38         RETV_IF(NULL == val, false);
39         RETVM_IF(val->ref_count <= 0, false, "Invalid Count(%d)", val->ref_count);
40
41         val->ref_count--;
42         if (0 == val->ref_count)
43                 return true;
44
45         return false;
46 }
47
48
49 API int iotcon_state_create(iotcon_state_h *ret_state)
50 {
51         errno = 0;
52         iotcon_state_h state;
53
54         RETV_IF(NULL == ret_state, IOTCON_ERROR_INVALID_PARAMETER);
55
56         state = calloc(1, sizeof(struct icl_state_s));
57         if (NULL == state) {
58                 ERR("calloc() Fail(%d)", errno);
59                 return IOTCON_ERROR_OUT_OF_MEMORY;
60         }
61
62         state->hash_table = g_hash_table_new_full(g_str_hash, g_str_equal, free,
63                         icl_value_destroy);
64         icl_state_inc_ref_count(state);
65
66         *ret_state = state;
67
68         return IOTCON_ERROR_NONE;
69 }
70
71
72 API void iotcon_state_destroy(iotcon_state_h state)
73 {
74         RET_IF(NULL == state);
75
76         if (false == _icl_state_dec_ref_count(state))
77                 return;
78
79         g_hash_table_destroy(state->hash_table);
80         free(state);
81 }
82
83 API int iotcon_state_clone(iotcon_state_h state, iotcon_state_h *state_clone)
84 {
85         int ret;
86         RETV_IF(NULL == state, IOTCON_ERROR_INVALID_PARAMETER);
87         RETV_IF(NULL == state_clone, IOTCON_ERROR_INVALID_PARAMETER);
88
89         ret = icl_state_clone(state, state_clone);
90         if (IOTCON_ERROR_NONE != ret) {
91                 ERR("icl_state_clone() Fail(%d)", ret);
92                 return ret;
93         }
94
95         return IOTCON_ERROR_NONE;
96 }
97
98
99 int icl_state_del_value(iotcon_state_h state, const char *key)
100 {
101         gboolean ret = FALSE;
102         iotcon_value_h value = NULL;
103
104         RETV_IF(NULL == state, IOTCON_ERROR_INVALID_PARAMETER);
105         RETV_IF(NULL == key, IOTCON_ERROR_INVALID_PARAMETER);
106
107         value = g_hash_table_lookup(state->hash_table, key);
108         if (NULL == value) {
109                 ERR("g_hash_table_lookup(%s) Fail", key);
110                 return IOTCON_ERROR_NO_DATA;
111         }
112
113         ret = g_hash_table_remove(state->hash_table, key);
114         if (FALSE == ret) {
115                 ERR("g_hash_table_remove(%s) Fail", key);
116                 return IOTCON_ERROR_NO_DATA;
117         }
118
119         return IOTCON_ERROR_NONE;
120 }
121
122 API int iotcon_state_get_int(iotcon_state_h state, const char *key, int *val)
123 {
124         iotcon_value_h value;
125
126         RETV_IF(NULL == state, IOTCON_ERROR_INVALID_PARAMETER);
127         RETV_IF(NULL == key, IOTCON_ERROR_INVALID_PARAMETER);
128         RETV_IF(NULL == val, IOTCON_ERROR_INVALID_PARAMETER);
129
130         value = g_hash_table_lookup(state->hash_table, key);
131         if (NULL == value) {
132                 ERR("g_hash_table_lookup() Fail");
133                 return IOTCON_ERROR_NO_DATA;
134         }
135
136         icl_basic_s *real = (icl_basic_s*)value;
137         if (IOTCON_TYPE_INT != real->type) {
138                 ERR("Invalid Type(%d)", real->type);
139                 return IOTCON_ERROR_INVALID_TYPE;
140         }
141
142         *val = real->val.i;
143
144         return IOTCON_ERROR_NONE;
145 }
146
147 API int iotcon_state_set_int(iotcon_state_h state, const char *key, int val)
148 {
149         iotcon_value_h value;
150
151         RETV_IF(NULL == state, IOTCON_ERROR_INVALID_PARAMETER);
152         RETV_IF(NULL == key, IOTCON_ERROR_INVALID_PARAMETER);
153
154         value = icl_value_create_int(val);
155         if (NULL == value) {
156                 ERR("icl_value_create_int(%d) Fail", val);
157                 return IOTCON_ERROR_OUT_OF_MEMORY;
158         }
159
160         g_hash_table_replace(state->hash_table, ic_utils_strdup(key), value);
161
162         return IOTCON_ERROR_NONE;
163 }
164
165 API int iotcon_state_unset(iotcon_state_h state, const char *key)
166 {
167         int ret;
168
169         RETV_IF(NULL == state, IOTCON_ERROR_INVALID_PARAMETER);
170         RETV_IF(NULL == key, IOTCON_ERROR_INVALID_PARAMETER);
171
172         ret = icl_state_del_value(state, key);
173         if (IOTCON_ERROR_NONE != ret)
174                 ERR("icl_state_del_value() Fail(%d)", ret);
175
176         return ret;
177 }
178
179 API int iotcon_state_get_bool(iotcon_state_h state, const char *key, bool *val)
180 {
181         icl_basic_s *real = NULL;
182         iotcon_value_h value = NULL;
183
184         RETV_IF(NULL == state, IOTCON_ERROR_INVALID_PARAMETER);
185         RETV_IF(NULL == key, IOTCON_ERROR_INVALID_PARAMETER);
186         RETV_IF(NULL == val, IOTCON_ERROR_INVALID_PARAMETER);
187
188         value = g_hash_table_lookup(state->hash_table, key);
189         if (NULL == value) {
190                 ERR("g_hash_table_lookup() Fail");
191                 return IOTCON_ERROR_NO_DATA;
192         }
193
194         real = (icl_basic_s*)value;
195         if (IOTCON_TYPE_BOOL != real->type) {
196                 ERR("Invalid Type(%d)", real->type);
197                 return IOTCON_ERROR_INVALID_TYPE;
198         }
199
200         *val = real->val.b;
201
202         return IOTCON_ERROR_NONE;
203 }
204
205 API int iotcon_state_set_bool(iotcon_state_h state, const char *key, bool val)
206 {
207         iotcon_value_h value = NULL;
208
209         RETV_IF(NULL == state, IOTCON_ERROR_INVALID_PARAMETER);
210         RETV_IF(NULL == key, IOTCON_ERROR_INVALID_PARAMETER);
211
212         value = icl_value_create_bool(val);
213         if (NULL == value) {
214                 ERR("icl_value_create_bool(%d) Fail", val);
215                 return IOTCON_ERROR_OUT_OF_MEMORY;
216         }
217
218         g_hash_table_replace(state->hash_table, ic_utils_strdup(key), value);
219
220         return IOTCON_ERROR_NONE;
221 }
222
223 API int iotcon_state_get_double(iotcon_state_h state, const char *key, double *val)
224 {
225         icl_basic_s *real = NULL;
226         iotcon_value_h value = NULL;
227
228         RETV_IF(NULL == state, IOTCON_ERROR_INVALID_PARAMETER);
229         RETV_IF(NULL == key, IOTCON_ERROR_INVALID_PARAMETER);
230         RETV_IF(NULL == val, IOTCON_ERROR_INVALID_PARAMETER);
231
232         value = g_hash_table_lookup(state->hash_table, key);
233         if (NULL == value) {
234                 ERR("g_hash_table_lookup() Fail");
235                 return IOTCON_ERROR_NO_DATA;
236         }
237
238         real = (icl_basic_s*)value;
239         if (IOTCON_TYPE_DOUBLE != real->type) {
240                 ERR("Invalid Type(%d)", real->type);
241                 return IOTCON_ERROR_INVALID_TYPE;
242         }
243
244         *val = real->val.d;
245
246         return IOTCON_ERROR_NONE;
247 }
248
249 API int iotcon_state_set_double(iotcon_state_h state, const char *key, double val)
250 {
251         iotcon_value_h value = NULL;
252
253         RETV_IF(NULL == state, IOTCON_ERROR_INVALID_PARAMETER);
254         RETV_IF(NULL == key, IOTCON_ERROR_INVALID_PARAMETER);
255
256         value = icl_value_create_double(val);
257         if (NULL == value) {
258                 ERR("icl_value_create_double(%f) Fail", val);
259                 return IOTCON_ERROR_OUT_OF_MEMORY;
260         }
261
262         g_hash_table_replace(state->hash_table, ic_utils_strdup(key), value);
263
264         return IOTCON_ERROR_NONE;
265 }
266
267 API int iotcon_state_get_str(iotcon_state_h state, const char *key, char **val)
268 {
269         icl_basic_s *real = NULL;
270         iotcon_value_h value = NULL;
271
272         RETV_IF(NULL == state, IOTCON_ERROR_INVALID_PARAMETER);
273         RETV_IF(NULL == key, IOTCON_ERROR_INVALID_PARAMETER);
274         RETV_IF(NULL == val, IOTCON_ERROR_INVALID_PARAMETER);
275
276         value = g_hash_table_lookup(state->hash_table, key);
277         if (NULL == value) {
278                 ERR("g_hash_table_lookup() Fail");
279                 return IOTCON_ERROR_NO_DATA;
280         }
281
282         real = (icl_basic_s*)value;
283         if (IOTCON_TYPE_STR != real->type) {
284                 ERR("Invalid Type(%d)", real->type);
285                 return IOTCON_ERROR_INVALID_TYPE;
286         }
287
288         *val = real->val.s;
289
290         return IOTCON_ERROR_NONE;
291 }
292
293 API int iotcon_state_set_str(iotcon_state_h state, const char *key, char *val)
294 {
295         iotcon_value_h value = NULL;
296
297         RETV_IF(NULL == state, IOTCON_ERROR_INVALID_PARAMETER);
298         RETV_IF(NULL == key, IOTCON_ERROR_INVALID_PARAMETER);
299         RETV_IF(NULL == val, IOTCON_ERROR_INVALID_PARAMETER);
300
301         value = icl_value_create_str(val);
302         if (NULL == value) {
303                 ERR("icl_value_create_str(%s) Fail", val);
304                 return IOTCON_ERROR_OUT_OF_MEMORY;
305         }
306
307         g_hash_table_replace(state->hash_table, ic_utils_strdup(key), value);
308
309         return IOTCON_ERROR_NONE;
310 }
311
312 API int iotcon_state_is_null(iotcon_state_h state, const char *key, bool *is_null)
313 {
314         icl_basic_s *real = NULL;
315         iotcon_value_h value = NULL;
316
317         RETV_IF(NULL == state, IOTCON_ERROR_INVALID_PARAMETER);
318         RETV_IF(NULL == key, IOTCON_ERROR_INVALID_PARAMETER);
319
320         value = (iotcon_value_h) g_hash_table_lookup(state->hash_table, key);
321         if (NULL == value) {
322                 ERR("g_hash_table_lookup() Fail");
323                 return IOTCON_ERROR_NO_DATA;
324         }
325
326         real = (icl_basic_s*)value;
327         *is_null = (IOTCON_TYPE_NULL == real->type) ? true : false;
328
329         return IOTCON_ERROR_NONE;
330 }
331
332 API int iotcon_state_set_null(iotcon_state_h state, const char *key)
333 {
334         iotcon_value_h value = NULL;
335
336         RETV_IF(NULL == state, IOTCON_ERROR_INVALID_PARAMETER);
337         RETV_IF(NULL == key, IOTCON_ERROR_INVALID_PARAMETER);
338
339         value = icl_value_create_null();
340         if (NULL == value) {
341                 ERR("icl_value_create_null() Fail");
342                 return IOTCON_ERROR_OUT_OF_MEMORY;
343         }
344
345         g_hash_table_replace(state->hash_table, ic_utils_strdup(key), value);
346
347         return IOTCON_ERROR_NONE;
348 }
349
350 API int iotcon_state_get_list(iotcon_state_h state, const char *key, iotcon_list_h *list)
351 {
352         iotcon_value_h value = NULL;
353         icl_val_list_s *real = NULL;
354
355         RETV_IF(NULL == state, IOTCON_ERROR_INVALID_PARAMETER);
356         RETV_IF(NULL == key, IOTCON_ERROR_INVALID_PARAMETER);
357         RETV_IF(NULL == list, IOTCON_ERROR_INVALID_PARAMETER);
358
359         value = g_hash_table_lookup(state->hash_table, key);
360         if (NULL == value) {
361                 ERR("g_hash_table_lookup() Fail");
362                 return IOTCON_ERROR_NO_DATA;
363         }
364
365         real = (icl_val_list_s*)value;
366         if (IOTCON_TYPE_LIST != real->type) {
367                 ERR("Invalid Type(%d)", real->type);
368                 return IOTCON_ERROR_INVALID_TYPE;
369         }
370
371         *list = real->list;
372
373         return IOTCON_ERROR_NONE;
374 }
375
376 API int iotcon_state_set_list(iotcon_state_h state, const char *key, iotcon_list_h list)
377 {
378         iotcon_value_h value = NULL;
379
380         RETV_IF(NULL == state, IOTCON_ERROR_INVALID_PARAMETER);
381         RETV_IF(NULL == key, IOTCON_ERROR_INVALID_PARAMETER);
382         RETV_IF(NULL == list, IOTCON_ERROR_INVALID_PARAMETER);
383
384         value = icl_value_create_list(list);
385         if (NULL == value) {
386                 ERR("icl_value_create_list() Fail");
387                 return IOTCON_ERROR_OUT_OF_MEMORY;
388         }
389         icl_list_inc_ref_count(list);
390
391         g_hash_table_replace(state->hash_table, ic_utils_strdup(key), value);
392
393         return IOTCON_ERROR_NONE;
394 }
395
396 API int iotcon_state_get_state(iotcon_state_h src, const char *key, iotcon_state_h *dest)
397 {
398         icl_val_state_s *real = NULL;
399         iotcon_value_h value = NULL;
400
401         RETV_IF(NULL == src, IOTCON_ERROR_INVALID_PARAMETER);
402         RETV_IF(NULL == key, IOTCON_ERROR_INVALID_PARAMETER);
403         RETV_IF(NULL == dest, IOTCON_ERROR_INVALID_PARAMETER);
404
405         value = g_hash_table_lookup(src->hash_table, key);
406         if (NULL == value) {
407                 ERR("g_hash_table_lookup() Fail");
408                 return IOTCON_ERROR_NO_DATA;
409         }
410
411         real = (icl_val_state_s*)value;
412         if (IOTCON_TYPE_STATE != real->type) {
413                 ERR("Invalid Type(%d)", real->type);
414                 return IOTCON_ERROR_INVALID_TYPE;
415         }
416
417         *dest = real->state;
418
419         return IOTCON_ERROR_NONE;
420 }
421
422 API int iotcon_state_set_state(iotcon_state_h state, const char *key, iotcon_state_h val)
423 {
424         iotcon_value_h value = NULL;
425
426         RETV_IF(NULL == state, IOTCON_ERROR_INVALID_PARAMETER);
427         RETV_IF(NULL == key, IOTCON_ERROR_INVALID_PARAMETER);
428         RETV_IF(NULL == val, IOTCON_ERROR_INVALID_PARAMETER);
429
430         value = icl_value_create_state(val);
431         if (NULL == value) {
432                 ERR("icl_value_create_state(%p) Fail", val);
433                 return IOTCON_ERROR_OUT_OF_MEMORY;
434         }
435         icl_state_inc_ref_count(val);
436
437         g_hash_table_replace(state->hash_table, ic_utils_strdup(key), value);
438
439         return IOTCON_ERROR_NONE;
440 }
441
442 API int iotcon_state_get_type(iotcon_state_h state, const char *key,
443                 iotcon_type_e *type)
444 {
445         iotcon_value_h value = NULL;
446
447         RETV_IF(NULL == state, IOTCON_ERROR_INVALID_PARAMETER);
448         RETV_IF(NULL == key, IOTCON_ERROR_INVALID_PARAMETER);
449         RETV_IF(NULL == type, IOTCON_ERROR_INVALID_PARAMETER);
450
451         value = g_hash_table_lookup(state->hash_table, key);
452         if (NULL == value) {
453                 ERR("g_hash_table_lookup() Fail");
454                 return IOTCON_ERROR_NO_DATA;
455         }
456         *type = value->type;
457
458         return IOTCON_ERROR_NONE;
459 }
460
461 int icl_state_set_value(iotcon_state_h state, const char *key, iotcon_value_h value)
462 {
463         RETV_IF(NULL == state, IOTCON_ERROR_INVALID_PARAMETER);
464         RETV_IF(NULL == key, IOTCON_ERROR_INVALID_PARAMETER);
465         RETV_IF(NULL == value, IOTCON_ERROR_INVALID_PARAMETER);
466
467         g_hash_table_replace(state->hash_table, ic_utils_strdup(key), value);
468
469         return IOTCON_ERROR_NONE;
470 }
471
472
473 int icl_state_clone(iotcon_state_h src, iotcon_state_h *dest)
474 {
475         int ret;
476
477         iotcon_state_h cloned_state = NULL;
478
479         RETV_IF(NULL == src, IOTCON_ERROR_INVALID_PARAMETER);
480         RETV_IF(NULL == dest, IOTCON_ERROR_INVALID_PARAMETER);
481
482         if (src->hash_table) {
483                 ret = iotcon_state_create(&cloned_state);
484                 if (IOTCON_ERROR_NONE != ret) {
485                         ERR("iotcon_state_create() Fail(%d)", ret);
486                         return ret;
487                 }
488
489                 g_hash_table_foreach(src->hash_table, (GHFunc)icl_state_clone_foreach,
490                                 cloned_state);
491         }
492
493         *dest = cloned_state;
494
495         return IOTCON_ERROR_NONE;
496 }