Add implementation of string_list_key_get()
[profile/ivi/weekeyboard.git] / src / wkb-ibus-config-key.c
1 /*
2  * Copyright © 2013 Intel Corporation
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
17 #include <stdlib.h>
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <unistd.h>
21 #include <string.h>
22
23 #include <Eina.h>
24
25 #include "wkb-ibus-config-key.h"
26
27 typedef void (*key_free_cb) (void *);
28 typedef Eina_Bool (*key_set_cb) (struct wkb_config_key *, Eldbus_Message_Iter *);
29 typedef Eina_Bool (*key_get_cb) (struct wkb_config_key *, Eldbus_Message_Iter *);
30
31 struct wkb_config_key
32 {
33    const char *id;
34    void *field; /* pointer to the actual struct field */
35
36    key_free_cb free;
37    key_set_cb set;
38    key_get_cb get;
39 };
40
41 static struct wkb_config_key *
42 _key_new(const char *id, void *field, key_free_cb free_cb, key_set_cb set_cb, key_get_cb get_cb)
43 {
44    struct wkb_config_key *key = calloc(1, sizeof(*key));
45    key->id = eina_stringshare_add(id);
46    key->field = field;
47    key->free = free_cb;
48    key->set = set_cb;
49    key->get = get_cb;
50    return key;
51 }
52
53 #define _key_basic_set(_key, _type, _dtype) \
54    do { \
55         _type __value = 0; \
56         _type *__field = (_type *) _key->field; \
57         if (!eldbus_message_iter_arguments_get(iter, _dtype, &__value)) \
58           { \
59              printf("Error decoding " #_type " value using '" _dtype "'\n"); \
60              return EINA_FALSE; \
61           } \
62         *__field = __value; \
63         return EINA_TRUE; \
64    } while (0)
65
66 #define _key_basic_get(_key, _type, _dtype, _iter) \
67    do { \
68         _type *__field = (_type *) _key->field; \
69        eldbus_message_iter_basic_append(_iter, _dtype, *__field); \
70        return EINA_TRUE; \
71    } while (0)
72
73 static Eina_Bool
74 _key_int_set(struct wkb_config_key *key, Eldbus_Message_Iter *iter)
75 {
76    _key_basic_set(key, int, "i");
77 }
78
79 static Eina_Bool
80 _key_int_get(struct wkb_config_key *key, Eldbus_Message_Iter *reply)
81 {
82    _key_basic_get(key, int, 'i', reply);
83 }
84
85 static Eina_Bool
86 _key_bool_set(struct wkb_config_key *key, Eldbus_Message_Iter *iter)
87 {
88    _key_basic_set(key, Eina_Bool, "b");
89 }
90
91 static Eina_Bool
92 _key_bool_get(struct wkb_config_key *key, Eldbus_Message_Iter *reply)
93 {
94    _key_basic_get(key, Eina_Bool, 'b', reply);
95 }
96
97 static void
98 _key_string_free(const char **str)
99 {
100    if (*str)
101       eina_stringshare_del(*str);
102 }
103
104 static Eina_Bool
105 _key_string_set(struct wkb_config_key *key, Eldbus_Message_Iter *iter)
106 {
107    const char *str;
108    const char **field;
109
110    if (!eldbus_message_iter_arguments_get(iter, "s", &str))
111      {
112         printf("Error decoding string value using 's'\n");
113         return EINA_FALSE;
114      }
115
116    if ((field = (const char **) key->field) && *field)
117       eina_stringshare_del(*field);
118
119    if (str && strlen(str))
120       *field = eina_stringshare_add(str);
121    else
122       *field = NULL;
123
124    return EINA_TRUE;
125 }
126
127 static Eina_Bool
128 _key_string_get(struct wkb_config_key *key, Eldbus_Message_Iter *reply)
129 {
130    _key_basic_get(key, const char *, 's', reply);
131 }
132
133 static void
134 _key_string_list_free(Eina_List **list)
135 {
136    const char *str;
137
138    EINA_LIST_FREE(*list, str)
139       eina_stringshare_del(str);
140
141    eina_list_free(*list);
142 }
143
144 static Eina_Bool
145 _key_string_list_set(struct wkb_config_key *key, Eldbus_Message_Iter *iter)
146 {
147    const char *str;
148    Eina_List *list = NULL;
149    Eina_List **field;
150
151    while (eldbus_message_iter_get_and_next(iter, 's', &str))
152       list = eina_list_append(list,eina_stringshare_add(str));
153
154    if ((field = (Eina_List **) key->field) && *field)
155       _key_string_list_free(field);
156
157    *field = list;
158
159    return EINA_TRUE;
160 }
161
162 static Eina_Bool
163 _key_string_list_get(struct wkb_config_key *key, Eldbus_Message_Iter *reply)
164 {
165    Eina_List *node, **list = (Eina_List **) key->field;
166    const char *str;
167    Eldbus_Message_Iter *array;
168
169    array = eldbus_message_iter_container_new(reply, 'a', "s");
170
171    EINA_LIST_FOREACH(*list, node, str)
172       eldbus_message_iter_basic_append(array, 's', str);
173
174    eldbus_message_iter_container_close(reply, array);
175
176    return EINA_TRUE;
177 }
178
179 /*
180  * PUBLIC FUNCTIONS
181  */
182 struct wkb_config_key *
183 wkb_config_key_int(const char *id, void *field)
184 {
185    return _key_new(id, field, NULL, _key_int_set, _key_int_get);
186 }
187
188 struct wkb_config_key *
189 wkb_config_key_bool(const char *id, void *field)
190 {
191    return _key_new(id, field, NULL, _key_bool_set, _key_bool_get);
192 }
193
194 struct wkb_config_key *
195 wkb_config_key_string(const char *id, void *field)
196 {
197    return _key_new(id, field, (key_free_cb) _key_string_free, _key_string_set, _key_string_get);
198 }
199
200 struct wkb_config_key *
201 wkb_config_key_string_list(const char *id, void *field)
202 {
203    return _key_new(id, field, (key_free_cb) _key_string_list_free, _key_string_list_set, _key_string_list_get);
204 }
205
206 void
207 wkb_config_key_free(struct wkb_config_key *key)
208 {
209    if (key->free && key->field)
210       key->free(key->field);
211
212    eina_stringshare_del(key->id);
213    free(key);
214 }
215
216 const char *
217 wkb_config_key_id(struct wkb_config_key *key)
218 {
219    return key->id;
220 }
221
222 Eina_Bool
223 wkb_config_key_set(struct wkb_config_key * key, Eldbus_Message_Iter *iter)
224 {
225    if (!key->field || !key->set)
226       return EINA_FALSE;
227
228    return key->set(key, iter);
229 }
230
231 Eina_Bool
232 wkb_config_key_get(struct wkb_config_key *key, Eldbus_Message_Iter *reply)
233 {
234    if (!key->field || !key->get)
235       return EINA_FALSE;
236
237    return key->get(key, reply);
238 }
239