Update date in copyrights
[src/app-framework-main.git] / src / utils-json.c
1 /*
2  Copyright (C) 2015-2019 IoT.bzh
3
4  author: José Bollo <jose.bollo@iot.bzh>
5
6  Licensed under the Apache License, Version 2.0 (the "License");
7  you may not use this file except in compliance with the License.
8  You may obtain a copy of the License at
9
10      http://www.apache.org/licenses/LICENSE-2.0
11
12  Unless required by applicable law or agreed to in writing, software
13  distributed under the License is distributed on an "AS IS" BASIS,
14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  See the License for the specific language governing permissions and
16  limitations under the License.
17 */
18
19 #define _GNU_SOURCE
20
21 #include <errno.h>
22 #include <string.h>
23 #include <stdarg.h>
24
25 #include <json-c/json.h>
26
27 #include "utils-json.h"
28
29 int j_read_string(struct json_object *obj, const char **value)
30 {
31         return j_is_string(obj) && (*value = json_object_get_string(obj)) != NULL;
32 }
33
34 int j_read_boolean(struct json_object *obj, int *value)
35 {
36         return j_is_boolean(obj) && ((*value = (int)json_object_get_boolean(obj)), 1);
37 }
38
39 int j_read_integer(struct json_object *obj, int *value)
40 {
41         return j_is_integer(obj) && ((*value = (int)json_object_get_int(obj)), 1);
42 }
43
44 const char *j_string(struct json_object *obj, const char *defval)
45 {
46         return j_is_string(obj) ? json_object_get_string(obj) : defval;
47 }
48
49 int j_boolean(struct json_object *obj, int defval)
50 {
51         return j_is_boolean(obj) ? json_object_get_boolean(obj) : defval;
52 }
53
54 int j_integer(struct json_object *obj, int defval)
55 {
56         return j_is_integer(obj) ? json_object_get_int(obj) : defval;
57 }
58
59 int j_has(struct json_object *obj, const char *key)
60 {
61         return json_object_object_get_ex(obj, key, NULL);
62 }
63
64 int j_read_object_at(struct json_object *obj, const char *key, struct json_object **value)
65 {
66         return json_object_object_get_ex(obj, key, value);
67 }
68
69 int j_read_string_at(struct json_object *obj, const char *key, const char **value)
70 {
71         json_object *data;
72         return j_read_object_at(obj, key, &data) && j_read_string(data, value);
73 }
74
75 int j_read_boolean_at(struct json_object *obj, const char *key, int *value)
76 {
77         json_object *data;
78         return j_read_object_at(obj, key, &data) && j_read_boolean(data, value);
79 }
80
81 int j_read_integer_at(struct json_object *obj, const char *key, int *value)
82 {
83         json_object *data;
84         return j_read_object_at(obj, key, &data) && j_read_integer(data, value);
85 }
86
87 const char *j_string_at(struct json_object *obj, const char *key, const char *defval)
88 {
89         struct json_object *data;
90         return j_read_object_at(obj, key, &data) ? j_string(data, defval) : defval;
91 }
92
93 int j_boolean_at(struct json_object *obj, const char *key, int defval)
94 {
95         struct json_object *data;
96         return j_read_object_at(obj, key, &data) ? j_boolean(data, defval) : defval;
97 }
98
99 int j_integer_at(struct json_object *obj, const char *key, int defval)
100 {
101         struct json_object *data;
102         return j_read_object_at(obj, key, &data) ? j_integer(data, defval) : defval;
103 }
104
105 int j_add(struct json_object *obj, const char *key, struct json_object *val)
106 {
107         if (key)
108                 json_object_object_add(obj, key, val);
109         else
110                 json_object_array_add(obj, val);
111         return 1;
112 }
113
114 int j_add_string(struct json_object *obj, const char *key, const char *val)
115 {
116         struct json_object *str = json_object_new_string (val ? val : "");
117         return str ? j_add(obj, key, str) : (errno = ENOMEM, 0);
118 }
119
120 int j_add_boolean(struct json_object *obj, const char *key, int val)
121 {
122         struct json_object *str = json_object_new_boolean (val);
123         return str ? j_add(obj, key, str) : (errno = ENOMEM, 0);
124 }
125
126 int j_add_integer(struct json_object *obj, const char *key, int val)
127 {
128         struct json_object *str = json_object_new_int (val);
129         return str ? j_add(obj, key, str) : (errno = ENOMEM, 0);
130 }
131
132 struct json_object *j_add_new_array(struct json_object *obj, const char *key)
133 {
134         struct json_object *result = json_object_new_array();
135         if (result != NULL && !j_add(obj, key, result)) {
136                 json_object_put(result);
137                 result = NULL;
138         }
139         return result;
140 }
141
142 struct json_object *j_add_new_object(struct json_object *obj, const char *key)
143 {
144         struct json_object *result = json_object_new_object();
145         if (result != NULL && !j_add(obj, key, result)) {
146                 json_object_put(result);
147                 result = NULL;
148         }
149         return result;
150 }
151
152 int j_enter_m(struct json_object **obj, const char **mkey, int create)
153 {
154         char *n;
155         struct json_object *o, *x;
156         const char *f, *k;
157
158         k = *mkey;
159         f = strchr(k, '.');
160         if (f) {
161                 o = *obj;
162                 do {
163                         n = strndupa(k, (size_t)(f - k));
164                         if (!json_object_object_get_ex(o, n, &x)) {
165                                 if (!create)
166                                         return -ENOENT;
167                                 x = j_add_new_object(o, n);
168                                 if (!x)
169                                         return -ENOMEM;
170                         }
171                         o = x;
172                         k = f + 1;
173                         f = strchr(k, '.');
174                 } while(f);
175                 *obj = o;
176                 *mkey = k;
177         }
178         return 0;
179 }
180
181
182 int j_has_m(struct json_object *obj, const char *mkey)
183 {
184         return !j_enter_m(&obj, &mkey, 0) && j_has(obj, mkey);
185 }
186
187 int j_read_object_at_m(struct json_object *obj, const char *mkey, struct json_object **value)
188 {
189         return !j_enter_m(&obj, &mkey, 0) && j_read_object_at(obj, mkey, value);
190 }
191
192 int j_read_string_at_m(struct json_object *obj, const char *mkey, const char **value)
193 {
194         json_object *data;
195         return j_read_object_at_m(obj, mkey, &data) && j_read_string(data, value);
196 }
197
198 int j_read_boolean_at_m(struct json_object *obj, const char *mkey, int *value)
199 {
200         json_object *data;
201         return j_read_object_at_m(obj, mkey, &data) && j_read_boolean(data, value);
202 }
203
204 int j_read_integer_at_m(struct json_object *obj, const char *mkey, int *value)
205 {
206         json_object *data;
207         return j_read_object_at_m(obj, mkey, &data) && j_read_integer(data, value);
208 }
209
210 const char *j_string_at_m(struct json_object *obj, const char *mkey, const char *defval)
211 {
212         struct json_object *data;
213         return j_read_object_at_m(obj, mkey, &data) ? j_string(data, defval) : defval;
214 }
215
216 int j_boolean_at_m(struct json_object *obj, const char *mkey, int defval)
217 {
218         struct json_object *data;
219         return j_read_object_at_m(obj, mkey, &data) ? j_boolean(data, defval) : defval;
220 }
221
222 int j_integer_at_m(struct json_object *obj, const char *mkey, int defval)
223 {
224         struct json_object *data;
225         return j_read_object_at_m(obj, mkey, &data) ? j_integer(data, defval) : defval;
226 }
227
228 int j_add_m(struct json_object *obj, const char *mkey, struct json_object *val)
229 {
230         if (mkey)
231                 return !j_enter_m(&obj, &mkey, 1) && j_add(obj, mkey, val);
232         json_object_array_add(obj, val);
233         return 1;
234 }
235
236 int j_add_string_m(struct json_object *obj, const char *mkey, const char *val)
237 {
238         struct json_object *str = json_object_new_string (val ? val : "");
239         return str ? j_add_m(obj, mkey, str) : (errno = ENOMEM, 0);
240 }
241
242 int j_add_boolean_m(struct json_object *obj, const char *mkey, int val)
243 {
244         struct json_object *str = json_object_new_boolean (val);
245         return str ? j_add_m(obj, mkey, str) : (errno = ENOMEM, 0);
246 }
247
248 int j_add_integer_m(struct json_object *obj, const char *mkey, int val)
249 {
250         struct json_object *str = json_object_new_int (val);
251         return str ? j_add_m(obj, mkey, str) : (errno = ENOMEM, 0);
252 }
253
254 struct json_object *j_add_new_array_m(struct json_object *obj, const char *mkey)
255 {
256         struct json_object *result = json_object_new_array();
257         if (result != NULL && !j_add_m(obj, mkey, result)) {
258                 json_object_put(result);
259                 result = NULL;
260         }
261         return result;
262 }
263
264 struct json_object *j_add_new_object_m(struct json_object *obj, const char *mkey)
265 {
266         struct json_object *result = json_object_new_object();
267         if (result != NULL && !j_add_m(obj, mkey, result)) {
268                 json_object_put(result);
269                 result = NULL;
270         }
271         return result;
272 }
273
274 int j_add_many_strings_m(struct json_object *obj, ...)
275 {
276         const char *key, *val;
277         va_list ap;
278         int rc;
279
280         rc = 1;
281         va_start(ap, obj);
282         key = va_arg(ap, const char *);
283         while (key) {
284                 val = va_arg(ap, const char *);
285                 if (val) {
286                         if (!j_add_string_m(obj, key, val))
287                                 rc = 0;
288                 }
289                 key = va_arg(ap, const char *);
290         }
291         va_end(ap);
292         return rc;
293 }