2 Copyright (C) 2016-2019 "IoT.bzh"
4 author: José Bollo <jose.bollo@iot.bzh>
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
10 http://www.apache.org/licenses/LICENSE-2.0
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.
23 #include "wrap-json.h"
24 #if !defined(JSON_C_TO_STRING_NOSLASHESCAPE)
25 #define JSON_C_TO_STRING_NOSLASHESCAPE 0
29 void tclone(struct json_object *object)
31 struct json_object *o;
33 o = wrap_json_clone(object);
34 if (!wrap_json_equal(object, o))
35 printf("ERROR in clone or equal: %s VERSUS %s\n", json_object_to_json_string_ext(object, JSON_C_TO_STRING_NOSLASHESCAPE), json_object_to_json_string_ext(o, JSON_C_TO_STRING_NOSLASHESCAPE));
38 o = wrap_json_clone_deep(object);
39 if (!wrap_json_equal(object, o))
40 printf("ERROR in clone_deep or equal: %s VERSUS %s\n", json_object_to_json_string_ext(object, JSON_C_TO_STRING_NOSLASHESCAPE), json_object_to_json_string_ext(o, JSON_C_TO_STRING_NOSLASHESCAPE));
45 void objcb(void *closure, struct json_object *obj, const char *key)
47 const char *prefix = closure;
48 printf(" %s {%s} %s\n", prefix ?: "", key ?: "[]", json_object_to_json_string_ext(obj, JSON_C_TO_STRING_NOSLASHESCAPE));
51 void arrcb(void *closure, struct json_object *obj)
53 objcb(closure, obj, NULL);
56 void tforall(struct json_object *object)
58 wrap_json_for_all(object, objcb, "wrap_json_for_all");
59 wrap_json_optobject_for_all(object, objcb, "wrap_json_optobject_for_all");
60 wrap_json_object_for_all(object, objcb, "wrap_json_object_for_all");
61 wrap_json_optarray_for_all(object, arrcb, "wrap_json_optarray_for_all");
62 wrap_json_array_for_all(object, arrcb, "wrap_json_array_for_all");
68 struct json_object *pair[2];
71 void mixcb(void *closure, struct json_object *obj, const char *key)
73 struct mix *mix = closure;
76 mix->pair[0] = json_object_new_object();
77 mix->pair[1] = json_object_new_object();
79 json_object_object_add(mix->pair[mix->n & 1], key, json_object_get(obj));
83 void tmix(struct json_object *object)
85 struct json_object *z;
86 struct mix mix = { .n = 0 };
88 wrap_json_object_for_all(object, mixcb, &mix);
90 z = wrap_json_object_add(wrap_json_clone(mix.pair[0]), mix.pair[1]);
91 if (!wrap_json_contains(z, mix.pair[0]))
92 printf(" ERROR mix/1\n");
93 if (!wrap_json_contains(z, mix.pair[1]))
94 printf(" ERROR mix/2\n");
95 if (!wrap_json_contains(z, object))
96 printf(" ERROR mix/3\n");
97 if (!wrap_json_contains(object, z))
98 printf(" ERROR mix/4\n");
99 if (!wrap_json_equal(object, z))
100 printf(" ERROR mix/5\n");
102 json_object_put(mix.pair[0]);
103 json_object_put(mix.pair[1]);
107 void p(const char *desc, ...)
111 struct json_object *result;
113 va_start(args, desc);
114 rc = wrap_json_vpack(&result, desc, args);
117 printf(" SUCCESS %s\n\n", json_object_to_json_string_ext(result, JSON_C_TO_STRING_NOSLASHESCAPE));
119 printf(" ERROR[char %d err %d] %s\n\n", wrap_json_get_error_position(rc), wrap_json_get_error_code(rc), wrap_json_get_error_string(rc));
121 json_object_put(result);
128 struct json_object *xo[10];
132 int extrchk(const char *desc, const char **array, int length, va_list args)
145 case '[': k = !(*desc - '{'); m = (m << 1) | k; break;
147 case ']': m = m >> 1; k = m&1; break;
150 (void)va_arg(args, char**);
154 array[n++] = va_arg(args, const char*);
157 case '%': (void)va_arg(args, size_t*); k = m&1; break;
158 case 'n': k = m&1; break;
160 case 'i': (void)va_arg(args, int*); k = m&1; break;
161 case 'I': (void)va_arg(args, int64_t*); k = m&1; break;
163 case 'F': (void)va_arg(args, double*); k = m&1; break;
164 case 'o': (void)va_arg(args, struct json_object**), k = m&1; break;
165 case 'O': (void)va_arg(args, struct json_object**); k = m&1; break;
168 (void)va_arg(args, uint8_t**);
169 (void)va_arg(args, size_t*);
180 const char *mkeys[5];
182 void tchk(struct json_object *object, const char *desc, const char **keys, int length, int qrc)
186 rm = wrap_json_match(object, desc, keys[0], keys[1], keys[2], keys[3], keys[4]);
187 rc = wrap_json_check(object, desc, keys[0], keys[1], keys[2], keys[3], keys[4]);
189 printf(" ERROR DIFFERS[char %d err %d] %s\n", wrap_json_get_error_position(rc), wrap_json_get_error_code(rc), wrap_json_get_error_string(rc));
191 printf(" ERROR OF MATCH\n");
194 void u(const char *value, const char *desc, ...)
200 struct json_object *object, *o;
202 memset(xs, 0, sizeof xs);
203 memset(xi, 0, sizeof xi);
204 memset(xI, 0, sizeof xI);
205 memset(xf, 0, sizeof xf);
206 memset(xo, 0, sizeof xo);
207 memset(xy, 0, sizeof xy);
208 memset(xz, 0, sizeof xz);
209 object = json_tokener_parse(value);
210 va_start(args, desc);
211 rc = wrap_json_vunpack(object, desc, args);
214 printf(" ERROR[char %d err %d] %s", wrap_json_get_error_position(rc), wrap_json_get_error_code(rc), wrap_json_get_error_string(rc));
219 va_start(args, desc);
223 case '{': m = (m << 1) | 1; k = 1; break;
224 case '}': m = m >> 1; k = m&1; break;
225 case '[': m = m << 1; k = 0; break;
226 case ']': m = m >> 1; k = m&1; break;
227 case 's': printf(" s:%s", k ? va_arg(args, const char*) : *(va_arg(args, const char**)?:&value)); k ^= m&1; break;
228 case '%': printf(" %%:%zu", *va_arg(args, size_t*)); k = m&1; break;
229 case 'n': printf(" n"); k = m&1; break;
230 case 'b': printf(" b:%d", *va_arg(args, int*)); k = m&1; break;
231 case 'i': printf(" i:%d", *va_arg(args, int*)); k = m&1; break;
232 case 'I': printf(" I:%lld", (long long int)*va_arg(args, int64_t*)); k = m&1; break;
233 case 'f': printf(" f:%f", *va_arg(args, double*)); k = m&1; break;
234 case 'F': printf(" F:%f", *va_arg(args, double*)); k = m&1; break;
235 case 'o': printf(" o:%s", json_object_to_json_string_ext(*va_arg(args, struct json_object**), JSON_C_TO_STRING_NOSLASHESCAPE)); k = m&1; break;
236 case 'O': o = *va_arg(args, struct json_object**); printf(" O:%s", json_object_to_json_string_ext(o, JSON_C_TO_STRING_NOSLASHESCAPE)); json_object_put(o); k = m&1; break;
239 uint8_t *p = *va_arg(args, uint8_t**);
240 size_t s = *va_arg(args, size_t*);
241 printf(" y/%d:%.*s", (int)s, (int)s, (char*)p);
252 va_start(args, desc);
253 n = extrchk(desc, mkeys, (int)(sizeof mkeys / sizeof *mkeys), args);
256 printf(" ERROR: too much keys in %s\n", desc);
258 tchk(object, desc, mkeys, n, rc);
263 json_object_put(object);
266 void c(const char *sx, const char *sy, int e, int c)
269 struct json_object *jx, *jy;
271 jx = json_tokener_parse(sx);
272 jy = json_tokener_parse(sy);
274 re = wrap_json_cmp(jx, jy);
275 rc = wrap_json_contains(jx, jy);
277 printf("compare(%s)(%s)\n", sx, sy);
278 printf(" -> %d / %d\n", re, rc);
281 printf(" ERROR should be %s\n", e ? "equal" : "different");
283 printf(" ERROR should %scontain\n", c ? "" : "not ");
288 #define P(...) do{ printf("pack(%s)\n",#__VA_ARGS__); p(__VA_ARGS__); } while(0)
289 #define U(...) do{ printf("unpack(%s)\n",#__VA_ARGS__); u(__VA_ARGS__); } while(0)
293 char buffer[4] = {'t', 'e', 's', 't'};
299 P("I", (uint64_t)0x123456789abcdef);
304 P("s#", "test asdf", 4);
305 P("s%", "test asdf", (size_t)4);
307 P("s%", buffer, (size_t)4);
308 P("s++", "te", "st", "ing");
309 P("s#+#+", "test", 1, "test", 2, "test");
310 P("s%+%+", "test", (size_t)1, "test", (size_t)2, "test");
313 P("o", json_object_new_int(1));
314 P("o?", json_object_new_int(1));
316 P("O", json_object_new_int(1));
317 P("O?", json_object_new_int(1));
320 P("{s+#+: []}", "foo", "barbar", 3, "baz");
321 P("{s:s,s:o,s:O}", "a", NULL, "b", NULL, "c", NULL);
322 P("{s:**}", "a", NULL);
323 P("{s:s*,s:o*,s:O*}", "a", NULL, "b", NULL, "c", NULL);
324 P("[i,i,i]", 0, 1, 2);
325 P("[s,o,O]", NULL, NULL, NULL);
327 P("[s*,o*,O*]", NULL, NULL, NULL);
330 P("[ i , i, i ] ", 1, 2, 3);
342 P("{ {}: s }", "foo");
343 P("{ s: {}, s:[ii{} }", "foo", "bar", 12, 13);
344 P("[[[[[ [[[[[ [[[[ }]]]] ]]]] ]]]]]");
345 P("y", "???????hello>>>>>>>", (size_t)19);
346 P("Y", "???????hello>>>>>>>", (size_t)19);
347 P("{sy?}", "foo", "hi", (size_t)2);
348 P("{sy?}", "foo", NULL, 0);
349 P("{sy*}", "foo", "hi", (size_t)2);
350 P("{sy*}", "foo", NULL, 0);
352 U("true", "b", &xi[0]);
353 U("false", "b", &xi[0]);
355 U("42", "i", &xi[0]);
356 U("123456789", "I", &xI[0]);
357 U("3.14", "f", &xf[0]);
358 U("12345", "F", &xf[0]);
359 U("3.14", "F", &xf[0]);
360 U("\"foo\"", "s", &xs[0]);
361 U("\"foo\"", "s%", &xs[0], &xz[0]);
364 U("{}", "o", &xo[0]);
365 U("{}", "O", &xo[0]);
366 U("{\"foo\":42}", "{si}", "foo", &xi[0]);
367 U("[1,2,3]", "[i,i,i]", &xi[0], &xi[1], &xi[2]);
368 U("{\"a\":1,\"b\":2,\"c\":3}", "{s:i, s:i, s:i}", "a", &xi[0], "b", &xi[1], "c", &xi[2]);
375 U("[42]", "[i]a", &xi[0]);
376 U("42", "ia", &xi[0]);
378 U("\"foo\"", "s", NULL);
383 U("42", "[i]", NULL);
384 U("42", "{si}", "foo", NULL);
386 U("\"foo\"", "b", NULL);
387 U("\"foo\"", "i", NULL);
388 U("\"foo\"", "I", NULL);
389 U("\"foo\"", "f", NULL);
390 U("\"foo\"", "F", NULL);
391 U("true", "s", NULL);
393 U("true", "i", NULL);
394 U("true", "I", NULL);
395 U("true", "f", NULL);
396 U("true", "F", NULL);
397 U("[42]", "[ii]", &xi[0], &xi[1]);
398 U("{\"foo\":42}", "{si}", NULL, &xi[0]);
399 U("{\"foo\":42}", "{si}", "baz", &xi[0]);
400 U("[1,2,3]", "[iii!]", &xi[0], &xi[1], &xi[2]);
401 U("[1,2,3]", "[ii!]", &xi[0], &xi[1]);
402 U("[1,2,3]", "[ii]", &xi[0], &xi[1]);
403 U("[1,2,3]", "[ii*]", &xi[0], &xi[1]);
404 U("{\"foo\":42,\"baz\":45}", "{sisi}", "baz", &xi[0], "foo", &xi[1]);
405 U("{\"foo\":42,\"baz\":45}", "{sisi*}", "baz", &xi[0], "foo", &xi[1]);
406 U("{\"foo\":42,\"baz\":45}", "{sisi!}", "baz", &xi[0], "foo", &xi[1]);
407 U("{\"foo\":42,\"baz\":45}", "{si}", "baz", &xi[0], "foo", &xi[1]);
408 U("{\"foo\":42,\"baz\":45}", "{si*}", "baz", &xi[0], "foo", &xi[1]);
409 U("{\"foo\":42,\"baz\":45}", "{si!}", "baz", &xi[0], "foo", &xi[1]);
410 U("[1,{\"foo\":2,\"bar\":null},[3,4]]", "[i{sisn}[ii]]", &xi[0], "foo", &xi[1], "bar", &xi[2], &xi[3]);
411 U("[1,2,3]", "[ii!i]", &xi[0], &xi[1], &xi[2]);
412 U("[1,2,3]", "[ii*i]", &xi[0], &xi[1], &xi[2]);
413 U("{\"foo\":1,\"bar\":2}", "{si!si}", "foo", &xi[1], "bar", &xi[2]);
414 U("{\"foo\":1,\"bar\":2}", "{si*si}", "foo", &xi[1], "bar", &xi[2]);
415 U("{\"foo\":{\"baz\":null,\"bar\":null}}", "{s{sn!}}", "foo", "bar");
416 U("[[1,2,3]]", "[[ii!]]", &xi[0], &xi[1]);
417 U("{}", "{s?i}", "foo", &xi[0]);
418 U("{\"foo\":1}", "{s?i}", "foo", &xi[0]);
419 U("{}", "{s?[ii]s?{s{si!}}}", "foo", &xi[0], &xi[1], "bar", "baz", "quux", &xi[2]);
420 U("{\"foo\":[1,2]}", "{s?[ii]s?{s{si!}}}", "foo", &xi[0], &xi[1], "bar", "baz", "quux", &xi[2]);
421 U("{\"bar\":{\"baz\":{\"quux\":15}}}", "{s?[ii]s?{s{si!}}}", "foo", &xi[0], &xi[1], "bar", "baz", "quux", &xi[2]);
422 U("{\"foo\":{\"bar\":4}}", "{s?{s?i}}", "foo", "bar", &xi[0]);
423 U("{\"foo\":{}}", "{s?{s?i}}", "foo", "bar", &xi[0]);
424 U("{}", "{s?{s?i}}", "foo", "bar", &xi[0]);
425 U("{\"foo\":42,\"baz\":45}", "{s?isi!}", "baz", &xi[0], "foo", &xi[1]);
426 U("{\"foo\":42}", "{s?isi!}", "baz", &xi[0], "foo", &xi[1]);
428 U("\"Pz8_Pz8_P2hlbGxvPj4-Pj4-Pg\"", "y", &xy[0], &xz[0]);
429 U("\"\"", "y", &xy[0], &xz[0]);
430 U("null", "y", &xy[0], &xz[0]);
431 U("{\"foo\":\"Pz8_Pz8_P2hlbGxvPj4-Pj4-Pg\"}", "{s?y}", "foo", &xy[0], &xz[0]);
432 U("{\"foo\":\"\"}", "{s?y}", "foo", &xy[0], &xz[0]);
433 U("{}", "{s?y}", "foo", &xy[0], &xz[0]);
435 c("null", "null", 1, 1);
436 c("true", "true", 1, 1);
437 c("false", "false", 1, 1);
439 c("1.0", "1.0", 1, 1);
440 c("\"\"", "\"\"", 1, 1);
441 c("\"hi\"", "\"hi\"", 1, 1);
443 c("{\"a\":true,\"b\":false}", "{\"b\":false,\"a\":true}", 1, 1);
445 c("[1,true,null]", "[1,true,null]", 1, 1);
447 c("null", "true", 0, 0);
448 c("null", "false", 0, 0);
451 c("0", "true", 0, 0);
452 c("0", "false", 0, 0);
453 c("0", "null", 0, 0);
455 c("\"hi\"", "\"hello\"", 0, 0);
456 c("\"hello\"", "\"hi\"", 0, 0);
458 c("{}", "null", 0, 0);
459 c("{}", "true", 0, 0);
461 c("{}", "1.0", 0, 0);
463 c("{}", "\"x\"", 0, 0);
465 c("[1,true,null]", "[1,true]", 0, 1);
466 c("{\"a\":true,\"b\":false}", "{\"a\":true}", 0, 1);
467 c("{\"a\":true,\"b\":false}", "{\"a\":true,\"c\":false}", 0, 0);
468 c("{\"a\":true,\"c\":false}", "{\"a\":true,\"b\":false}", 0, 0);