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