uloop: fix uloop_run_timeout
[project/libubox.git] / tests / test-blobmsg-types.c
1 #include <stdio.h>
2 #include <float.h>
3 #include <limits.h>
4 #include <stdint.h>
5 #include <inttypes.h>
6
7 #include "blobmsg.h"
8 #include "blobmsg_json.h"
9
10 enum {
11 FOO_STRING,
12 FOO_INT64_MAX,
13 FOO_INT64_MIN,
14 FOO_INT32_MAX,
15 FOO_INT32_MIN,
16 FOO_INT16_MAX,
17 FOO_INT16_MIN,
18 FOO_INT8_MAX,
19 FOO_INT8_MIN,
20 FOO_DOUBLE_MAX,
21 FOO_DOUBLE_MIN,
22 __FOO_MAX
23 };
24
25 static const struct blobmsg_policy pol[] = {
26 [FOO_STRING] = {
27 .name = "string",
28 .type = BLOBMSG_TYPE_STRING,
29 },
30 [FOO_INT64_MAX] = {
31 .name = "int64_max",
32 .type = BLOBMSG_TYPE_INT64,
33 },
34 [FOO_INT64_MIN] = {
35 .name = "int64_min",
36 .type = BLOBMSG_TYPE_INT64,
37 },
38 [FOO_INT32_MAX] = {
39 .name = "int32_max",
40 .type = BLOBMSG_TYPE_INT32,
41 },
42 [FOO_INT32_MIN] = {
43 .name = "int32_min",
44 .type = BLOBMSG_TYPE_INT32,
45 },
46 [FOO_INT16_MAX] = {
47 .name = "int16_max",
48 .type = BLOBMSG_TYPE_INT16,
49 },
50 [FOO_INT16_MIN] = {
51 .name = "int16_min",
52 .type = BLOBMSG_TYPE_INT16,
53 },
54 [FOO_INT8_MAX] = {
55 .name = "int8_max",
56 .type = BLOBMSG_TYPE_INT8,
57 },
58 [FOO_INT8_MIN] = {
59 .name = "int8_min",
60 .type = BLOBMSG_TYPE_INT8,
61 },
62 [FOO_DOUBLE_MAX] = {
63 .name = "double_max",
64 .type = BLOBMSG_TYPE_DOUBLE,
65 },
66 [FOO_DOUBLE_MIN] = {
67 .name = "double_min",
68 .type = BLOBMSG_TYPE_DOUBLE,
69 },
70 };
71
72 static const struct blobmsg_policy pol_json[] = {
73 [FOO_STRING] = {
74 .name = "string",
75 .type = BLOBMSG_TYPE_STRING,
76 },
77 [FOO_INT64_MAX] = {
78 .name = "int64_max",
79 .type = BLOBMSG_TYPE_INT64,
80 },
81 [FOO_INT64_MIN] = {
82 .name = "int64_min",
83 .type = BLOBMSG_TYPE_INT64,
84 },
85 [FOO_INT32_MAX] = {
86 .name = "int32_max",
87 .type = BLOBMSG_TYPE_INT32,
88 },
89 [FOO_INT32_MIN] = {
90 .name = "int32_min",
91 .type = BLOBMSG_TYPE_INT32,
92 },
93 [FOO_INT16_MAX] = {
94 .name = "int16_max",
95 .type = BLOBMSG_TYPE_INT32,
96 },
97 [FOO_INT16_MIN] = {
98 .name = "int16_min",
99 .type = BLOBMSG_TYPE_INT32,
100 },
101 [FOO_INT8_MAX] = {
102 .name = "int8_max",
103 .type = BLOBMSG_TYPE_INT8,
104 },
105 [FOO_INT8_MIN] = {
106 .name = "int8_min",
107 .type = BLOBMSG_TYPE_INT8,
108 },
109 [FOO_DOUBLE_MAX] = {
110 .name = "double_max",
111 .type = BLOBMSG_TYPE_DOUBLE,
112 },
113 [FOO_DOUBLE_MIN] = {
114 .name = "double_min",
115 .type = BLOBMSG_TYPE_DOUBLE,
116 },
117 };
118
119 #ifndef ARRAY_SIZE
120 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
121 #endif
122
123 static void dump_message(struct blob_buf *buf)
124 {
125 struct blob_attr *tb[ARRAY_SIZE(pol)];
126
127 if (blobmsg_parse(pol, ARRAY_SIZE(pol), tb, blob_data(buf->head), blob_len(buf->head)) != 0) {
128 fprintf(stderr, "Parse failed\n");
129 return;
130 }
131 if (tb[FOO_STRING])
132 fprintf(stderr, "string: %s\n", blobmsg_get_string(tb[FOO_STRING]));
133 if (tb[FOO_INT64_MAX])
134 fprintf(stderr, "int64_max: %" PRId64 "\n", (int64_t)blobmsg_get_u64(tb[FOO_INT64_MAX]));
135 if (tb[FOO_INT64_MIN])
136 fprintf(stderr, "int64_min: %" PRId64 "\n", (int64_t)blobmsg_get_u64(tb[FOO_INT64_MIN]));
137 if (tb[FOO_INT32_MAX])
138 fprintf(stderr, "int32_max: %" PRId32 "\n", (int32_t)blobmsg_get_u32(tb[FOO_INT32_MAX]));
139 if (tb[FOO_INT32_MIN])
140 fprintf(stderr, "int32_min: %" PRId32 "\n", (int32_t)blobmsg_get_u32(tb[FOO_INT32_MIN]));
141 if (tb[FOO_INT16_MAX])
142 fprintf(stderr, "int16_max: %" PRId16 "\n", (int16_t)blobmsg_get_u16(tb[FOO_INT16_MAX]));
143 if (tb[FOO_INT16_MIN])
144 fprintf(stderr, "int16_min: %" PRId16 "\n", (int16_t)blobmsg_get_u16(tb[FOO_INT16_MIN]));
145 if (tb[FOO_INT8_MAX])
146 fprintf(stderr, "int8_max: %" PRId8 "\n", (int8_t)blobmsg_get_u8(tb[FOO_INT8_MAX]));
147 if (tb[FOO_INT8_MIN])
148 fprintf(stderr, "int8_min: %" PRId8 "\n", (int8_t)blobmsg_get_u8(tb[FOO_INT8_MIN]));
149 if (tb[FOO_DOUBLE_MAX])
150 fprintf(stderr, "double_max: %e\n", blobmsg_get_double(tb[FOO_DOUBLE_MAX]));
151 if (tb[FOO_DOUBLE_MIN])
152 fprintf(stderr, "double_min: %e\n", blobmsg_get_double(tb[FOO_DOUBLE_MIN]));
153 }
154
155 static void dump_message_cast_u64(struct blob_buf *buf)
156 {
157 struct blob_attr *tb[ARRAY_SIZE(pol)];
158
159 if (blobmsg_parse(pol, ARRAY_SIZE(pol), tb, blob_data(buf->head), blob_len(buf->head)) != 0) {
160 fprintf(stderr, "Parse failed\n");
161 return;
162 }
163 if (tb[FOO_STRING])
164 fprintf(stderr, "string: %s\n", blobmsg_get_string(tb[FOO_STRING]));
165 if (tb[FOO_INT64_MAX])
166 fprintf(stderr, "int64_max: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT64_MAX]));
167 if (tb[FOO_INT64_MIN])
168 fprintf(stderr, "int64_min: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT64_MIN]));
169 if (tb[FOO_INT32_MAX])
170 fprintf(stderr, "int32_max: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT32_MAX]));
171 if (tb[FOO_INT32_MIN])
172 fprintf(stderr, "int32_min: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT32_MIN]));
173 if (tb[FOO_INT16_MAX])
174 fprintf(stderr, "int16_max: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT16_MAX]));
175 if (tb[FOO_INT16_MIN])
176 fprintf(stderr, "int16_min: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT16_MIN]));
177 if (tb[FOO_INT8_MAX])
178 fprintf(stderr, "int8_max: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT8_MAX]));
179 if (tb[FOO_INT8_MIN])
180 fprintf(stderr, "int8_min: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT8_MIN]));
181 if (tb[FOO_DOUBLE_MAX])
182 fprintf(stderr, "double_max: %e\n", blobmsg_get_double(tb[FOO_DOUBLE_MAX]));
183 if (tb[FOO_DOUBLE_MIN])
184 fprintf(stderr, "double_min: %e\n", blobmsg_get_double(tb[FOO_DOUBLE_MIN]));
185 }
186
187 static void dump_message_cast_s64(struct blob_buf *buf)
188 {
189 struct blob_attr *tb[ARRAY_SIZE(pol)];
190
191 if (blobmsg_parse(pol, ARRAY_SIZE(pol), tb, blob_data(buf->head), blob_len(buf->head)) != 0) {
192 fprintf(stderr, "Parse failed\n");
193 return;
194 }
195 if (tb[FOO_STRING])
196 fprintf(stderr, "string: %s\n", blobmsg_get_string(tb[FOO_STRING]));
197 if (tb[FOO_INT64_MAX])
198 fprintf(stderr, "int64_max: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT64_MAX]));
199 if (tb[FOO_INT64_MIN])
200 fprintf(stderr, "int64_min: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT64_MIN]));
201 if (tb[FOO_INT32_MAX])
202 fprintf(stderr, "int32_max: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT32_MAX]));
203 if (tb[FOO_INT32_MIN])
204 fprintf(stderr, "int32_min: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT32_MIN]));
205 if (tb[FOO_INT16_MAX])
206 fprintf(stderr, "int16_max: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT16_MAX]));
207 if (tb[FOO_INT16_MIN])
208 fprintf(stderr, "int16_min: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT16_MIN]));
209 if (tb[FOO_INT8_MAX])
210 fprintf(stderr, "int8_max: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT8_MAX]));
211 if (tb[FOO_INT8_MIN])
212 fprintf(stderr, "int8_min: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT8_MIN]));
213 if (tb[FOO_DOUBLE_MAX])
214 fprintf(stderr, "double_max: %e\n", blobmsg_get_double(tb[FOO_DOUBLE_MAX]));
215 if (tb[FOO_DOUBLE_MIN])
216 fprintf(stderr, "double_min: %e\n", blobmsg_get_double(tb[FOO_DOUBLE_MIN]));
217 }
218
219 static void dump_message_json(struct blob_buf *buf)
220 {
221 struct blob_attr *tb[ARRAY_SIZE(pol)];
222
223 if (blobmsg_parse(pol_json, ARRAY_SIZE(pol_json), tb, blob_data(buf->head), blob_len(buf->head)) != 0) {
224 fprintf(stderr, "Parse failed\n");
225 return;
226 }
227 if (tb[FOO_STRING])
228 fprintf(stderr, "string: %s\n", blobmsg_get_string(tb[FOO_STRING]));
229 if (tb[FOO_INT64_MAX])
230 fprintf(stderr, "int64_max: %" PRId64 "\n", blobmsg_get_u64(tb[FOO_INT64_MAX]));
231 if (tb[FOO_INT64_MIN])
232 fprintf(stderr, "int64_min: %" PRId64 "\n", blobmsg_get_u64(tb[FOO_INT64_MIN]));
233 if (tb[FOO_INT32_MAX])
234 fprintf(stderr, "int32_max: %" PRId32 "\n", blobmsg_get_u32(tb[FOO_INT32_MAX]));
235 if (tb[FOO_INT32_MIN])
236 fprintf(stderr, "int32_min: %" PRId32 "\n", blobmsg_get_u32(tb[FOO_INT32_MIN]));
237 /* u16 is unknown to json, retrieve as u32 */
238 if (tb[FOO_INT16_MAX])
239 fprintf(stderr, "int16_max: %" PRId32 "\n", blobmsg_get_u32(tb[FOO_INT16_MAX]));
240 /* u16 is unknown to json, retrieve as u32 */
241 if (tb[FOO_INT16_MIN])
242 fprintf(stderr, "int16_min: %" PRId32 "\n", blobmsg_get_u32(tb[FOO_INT16_MIN]));
243 /* u8 is converted to boolean (true: all values != 0/false: value 0) in json */
244 if (tb[FOO_INT8_MAX])
245 fprintf(stderr, "int8_max: %" PRId8 "\n", blobmsg_get_u8(tb[FOO_INT8_MAX]));
246 /* u8 is converted to boolean (true: all values != 0/false: value 0) in json */
247 if (tb[FOO_INT8_MIN])
248 fprintf(stderr, "int8_min: %" PRId8 "\n", blobmsg_get_u8(tb[FOO_INT8_MIN]));
249 if (tb[FOO_DOUBLE_MAX])
250 fprintf(stderr, "double_max: %e\n", blobmsg_get_double(tb[FOO_DOUBLE_MAX]));
251 if (tb[FOO_DOUBLE_MIN])
252 fprintf(stderr, "double_min: %e\n", blobmsg_get_double(tb[FOO_DOUBLE_MIN]));
253 }
254
255 static void dump_message_cast_u64_json(struct blob_buf *buf)
256 {
257 struct blob_attr *tb[ARRAY_SIZE(pol)];
258
259 if (blobmsg_parse(pol_json, ARRAY_SIZE(pol_json), tb, blob_data(buf->head), blob_len(buf->head)) != 0) {
260 fprintf(stderr, "Parse failed\n");
261 return;
262 }
263 if (tb[FOO_STRING])
264 fprintf(stderr, "string: %s\n", blobmsg_get_string(tb[FOO_STRING]));
265 if (tb[FOO_INT64_MAX])
266 fprintf(stderr, "int64_max: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT64_MAX]));
267 if (tb[FOO_INT64_MIN])
268 fprintf(stderr, "int64_min: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT64_MIN]));
269 if (tb[FOO_INT32_MAX])
270 fprintf(stderr, "int32_max: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT32_MAX]));
271 if (tb[FOO_INT32_MIN])
272 fprintf(stderr, "int32_min: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT32_MIN]));
273 if (tb[FOO_INT16_MAX])
274 fprintf(stderr, "int16_max: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT16_MAX]));
275 if (tb[FOO_INT16_MIN])
276 fprintf(stderr, "int16_min: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT16_MIN]));
277 if (tb[FOO_INT8_MAX])
278 fprintf(stderr, "int8_max: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT8_MAX]));
279 if (tb[FOO_INT8_MIN])
280 fprintf(stderr, "int8_min: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT8_MIN]));
281 if (tb[FOO_DOUBLE_MAX])
282 fprintf(stderr, "double_max: %e\n", blobmsg_get_double(tb[FOO_DOUBLE_MAX]));
283 if (tb[FOO_DOUBLE_MIN])
284 fprintf(stderr, "double_min: %e\n", blobmsg_get_double(tb[FOO_DOUBLE_MIN]));
285 }
286
287 static void dump_message_cast_s64_json(struct blob_buf *buf)
288 {
289 struct blob_attr *tb[ARRAY_SIZE(pol)];
290
291 if (blobmsg_parse(pol_json, ARRAY_SIZE(pol_json), tb, blob_data(buf->head), blob_len(buf->head)) != 0) {
292 fprintf(stderr, "Parse failed\n");
293 return;
294 }
295 if (tb[FOO_STRING])
296 fprintf(stderr, "string: %s\n", blobmsg_get_string(tb[FOO_STRING]));
297 if (tb[FOO_INT64_MAX])
298 fprintf(stderr, "int64_max: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT64_MAX]));
299 if (tb[FOO_INT64_MIN])
300 fprintf(stderr, "int64_min: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT64_MIN]));
301 if (tb[FOO_INT32_MAX])
302 fprintf(stderr, "int32_max: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT32_MAX]));
303 if (tb[FOO_INT32_MIN])
304 fprintf(stderr, "int32_min: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT32_MIN]));
305 if (tb[FOO_INT16_MAX])
306 fprintf(stderr, "int16_max: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT16_MAX]));
307 if (tb[FOO_INT16_MIN])
308 fprintf(stderr, "int16_min: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT16_MIN]));
309 if (tb[FOO_INT8_MAX])
310 fprintf(stderr, "int8_max: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT8_MAX]));
311 if (tb[FOO_INT8_MIN])
312 fprintf(stderr, "int8_min: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT8_MIN]));
313 if (tb[FOO_DOUBLE_MAX])
314 fprintf(stderr, "double_max: %e\n", blobmsg_get_double(tb[FOO_DOUBLE_MAX]));
315 if (tb[FOO_DOUBLE_MIN])
316 fprintf(stderr, "double_min: %e\n", blobmsg_get_double(tb[FOO_DOUBLE_MIN]));
317 }
318
319 static void
320 fill_message(struct blob_buf *buf)
321 {
322 blobmsg_add_string(buf, "string", "Hello, world!");
323 blobmsg_add_u64(buf, "int64_max", INT64_MAX);
324 blobmsg_add_u64(buf, "int64_min", INT64_MIN);
325 blobmsg_add_u32(buf, "int32_max", INT32_MAX);
326 blobmsg_add_u32(buf, "int32_min", INT32_MIN);
327 blobmsg_add_u16(buf, "int16_max", INT16_MAX);
328 blobmsg_add_u16(buf, "int16_min", INT16_MIN);
329 blobmsg_add_u8(buf, "int8_max", INT8_MAX);
330 blobmsg_add_u8(buf, "int8_min", INT8_MIN);
331 blobmsg_add_double(buf, "double_max", DBL_MAX);
332 blobmsg_add_double(buf, "double_min", DBL_MIN);
333 }
334
335 int main(int argc, char **argv)
336 {
337 char *json = NULL;
338 static struct blob_buf buf;
339
340 blobmsg_buf_init(&buf);
341 fill_message(&buf);
342 fprintf(stderr, "[*] blobmsg dump:\n");
343 dump_message(&buf);
344 fprintf(stderr, "[*] blobmsg dump cast_u64:\n");
345 dump_message_cast_u64(&buf);
346 fprintf(stderr, "[*] blobmsg dump cast_s64:\n");
347 dump_message_cast_s64(&buf);
348
349 json = blobmsg_format_json(buf.head, true);
350 if (!json)
351 exit(EXIT_FAILURE);
352
353 fprintf(stderr, "\n[*] blobmsg to json: %s\n", json);
354
355 blobmsg_buf_init(&buf);
356 if (!blobmsg_add_json_from_string(&buf, json))
357 exit(EXIT_FAILURE);
358
359 fprintf(stderr, "\n[*] blobmsg from json:\n");
360 dump_message_json(&buf);
361 fprintf(stderr, "\n[*] blobmsg from json/cast_u64:\n");
362 dump_message_cast_u64_json(&buf);
363 fprintf(stderr, "\n[*] blobmsg from json/cast_s64:\n");
364 dump_message_cast_s64_json(&buf);
365
366 if (buf.buf)
367 free(buf.buf);
368 free(json);
369
370 return 0;
371 }