/* Copyright (C) 2016, 2017, 2018 "IoT.bzh" author: José Bollo Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include #include #include #include "wrap-json.h" void tclone(struct json_object *object) { struct json_object *o; o = wrap_json_clone(object); if (!wrap_json_equal(object, o)) printf("ERROR in clone or equal: %s VERSUS %s\n", json_object_to_json_string(object), json_object_to_json_string(o)); json_object_put(o); o = wrap_json_clone_deep(object); if (!wrap_json_equal(object, o)) printf("ERROR in clone_deep or equal: %s VERSUS %s\n", json_object_to_json_string(object), json_object_to_json_string(o)); json_object_put(o); } void p(const char *desc, ...) { int rc; va_list args; struct json_object *result; va_start(args, desc); rc = wrap_json_vpack(&result, desc, args); va_end(args); if (!rc) printf(" SUCCESS %s\n\n", json_object_to_json_string(result)); else 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)); tclone(result); json_object_put(result); } const char *xs[10]; int *xi[10]; int64_t *xI[10]; double *xf[10]; struct json_object *xo[10]; size_t xz[10]; uint8_t *xy[10]; void u(const char *value, const char *desc, ...) { unsigned m, k; int rc; va_list args; struct json_object *object, *o; memset(xs, 0, sizeof xs); memset(xi, 0, sizeof xi); memset(xI, 0, sizeof xI); memset(xf, 0, sizeof xf); memset(xo, 0, sizeof xo); memset(xy, 0, sizeof xy); memset(xz, 0, sizeof xz); object = json_tokener_parse(value); va_start(args, desc); rc = wrap_json_vunpack(object, desc, args); va_end(args); if (rc) 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)); else { value = NULL; printf(" SUCCESS"); va_start(args, desc); k = m = 0; while(*desc) { switch(*desc) { case '{': m = (m << 1) | 1; k = 1; break; case '}': m = m >> 1; k = m&1; break; case '[': m = m << 1; k = 0; break; case ']': m = m >> 1; k = m&1; break; case 's': printf(" s:%s", k ? va_arg(args, const char*) : *(va_arg(args, const char**)?:&value)); k ^= m&1; break; case '%': printf(" %%:%zu", *va_arg(args, size_t*)); k = m&1; break; case 'n': printf(" n"); k = m&1; break; case 'b': printf(" b:%d", *va_arg(args, int*)); k = m&1; break; case 'i': printf(" i:%d", *va_arg(args, int*)); k = m&1; break; case 'I': printf(" I:%lld", *va_arg(args, int64_t*)); k = m&1; break; case 'f': printf(" f:%f", *va_arg(args, double*)); k = m&1; break; case 'F': printf(" F:%f", *va_arg(args, double*)); k = m&1; break; case 'o': printf(" o:%s", json_object_to_json_string(*va_arg(args, struct json_object**))); k = m&1; break; case 'O': o = *va_arg(args, struct json_object**); printf(" O:%s", json_object_to_json_string(o)); json_object_put(o); k = m&1; break; case 'y': case 'Y': { uint8_t *p = *va_arg(args, uint8_t**); size_t s = *va_arg(args, size_t*); printf(" y/%d:%.*s", (int)s, (int)s, (char*)p); k ^= m&1; break; } default: break; } desc++; } va_end(args); printf("\n\n"); } tclone(object); json_object_put(object); } void c(const char *sx, const char *sy, int e, int c) { int re, rc; struct json_object *jx, *jy; jx = json_tokener_parse(sx); jy = json_tokener_parse(sy); re = wrap_json_cmp(jx, jy); rc = wrap_json_contains(jx, jy); printf("compare(%s)(%s)\n", sx, sy); printf(" -> %d / %d\n", re, rc); if (!re != !!e) printf(" ERROR should be %s\n", e ? "equal" : "different"); if (!rc != !c) printf(" ERROR should %scontain\n", c ? "" : "not "); printf("\n"); } #define P(...) do{ printf("pack(%s)\n",#__VA_ARGS__); p(__VA_ARGS__); } while(0) #define U(...) do{ printf("unpack(%s)\n",#__VA_ARGS__); u(__VA_ARGS__); } while(0) int main() { char buffer[4] = {'t', 'e', 's', 't'}; P("n"); P("b", 1); P("b", 0); P("i", 1); P("I", (uint64_t)0x123456789abcdef); P("f", 3.14); P("s", "test"); P("s?", "test"); P("s?", NULL); P("s#", "test asdf", 4); P("s%", "test asdf", (size_t)4); P("s#", buffer, 4); P("s%", buffer, (size_t)4); P("s++", "te", "st", "ing"); P("s#+#+", "test", 1, "test", 2, "test"); P("s%+%+", "test", (size_t)1, "test", (size_t)2, "test"); P("{}", 1.0); P("[]", 1.0); P("o", json_object_new_int(1)); P("o?", json_object_new_int(1)); P("o?", NULL); P("O", json_object_new_int(1)); P("O?", json_object_new_int(1)); P("O?", NULL); P("{s:[]}", "foo"); P("{s+#+: []}", "foo", "barbar", 3, "baz"); P("{s:s,s:o,s:O}", "a", NULL, "b", NULL, "c", NULL); P("{s:**}", "a", NULL); P("{s:s*,s:o*,s:O*}", "a", NULL, "b", NULL, "c", NULL); P("[i,i,i]", 0, 1, 2); P("[s,o,O]", NULL, NULL, NULL); P("[**]", NULL); P("[s*,o*,O*]", NULL, NULL, NULL); P(" s ", "test"); P("[ ]"); P("[ i , i, i ] ", 1, 2, 3); P("{\n\n1"); P("[}"); P("{]"); P("["); P("{"); P("[i]a", 42); P("ia", 42); P("s", NULL); P("+", NULL); P(NULL); P("{s:i}", NULL, 1); P("{ {}: s }", "foo"); P("{ s: {}, s:[ii{} }", "foo", "bar", 12, 13); P("[[[[[ [[[[[ [[[[ }]]]] ]]]] ]]]]]"); P("y", "???????hello>>>>>>>", (size_t)19); P("Y", "???????hello>>>>>>>", (size_t)19); P("{sy?}", "foo", "hi", (size_t)2); P("{sy?}", "foo", NULL, 0); P("{sy*}", "foo", "hi", (size_t)2); P("{sy*}", "foo", NULL, 0); U("true", "b", &xi[0]); U("false", "b", &xi[0]); U("null", "n"); U("42", "i", &xi[0]); U("123456789", "I", &xI[0]); U("3.14", "f", &xf[0]); U("12345", "F", &xf[0]); U("3.14", "F", &xf[0]); U("\"foo\"", "s", &xs[0]); U("\"foo\"", "s%", &xs[0], &xz[0]); U("{}", "{}"); U("[]", "[]"); U("{}", "o", &xo[0]); U("{}", "O", &xo[0]); U("{\"foo\":42}", "{si}", "foo", &xi[0]); U("[1,2,3]", "[i,i,i]", &xi[0], &xi[1], &xi[2]); U("{\"a\":1,\"b\":2,\"c\":3}", "{s:i, s:i, s:i}", "a", &xi[0], "b", &xi[1], "c", &xi[2]); U("42", "z"); U("null", "[i]"); U("[]", "[}"); U("{}", "{]"); U("[]", "["); U("{}", "{"); U("[42]", "[i]a", &xi[0]); U("42", "ia", &xi[0]); U("[]", NULL); U("\"foo\"", "s", NULL); U("42", "s", NULL); U("42", "n"); U("42", "b", NULL); U("42", "f", NULL); U("42", "[i]", NULL); U("42", "{si}", "foo", NULL); U("\"foo\"", "n"); U("\"foo\"", "b", NULL); U("\"foo\"", "i", NULL); U("\"foo\"", "I", NULL); U("\"foo\"", "f", NULL); U("\"foo\"", "F", NULL); U("true", "s", NULL); U("true", "n"); U("true", "i", NULL); U("true", "I", NULL); U("true", "f", NULL); U("true", "F", NULL); U("[42]", "[ii]", &xi[0], &xi[1]); U("{\"foo\":42}", "{si}", NULL, &xi[0]); U("{\"foo\":42}", "{si}", "baz", &xi[0]); U("[1,2,3]", "[iii!]", &xi[0], &xi[1], &xi[2]); U("[1,2,3]", "[ii!]", &xi[0], &xi[1]); U("[1,2,3]", "[ii]", &xi[0], &xi[1]); U("[1,2,3]", "[ii*]", &xi[0], &xi[1]); U("{\"foo\":42,\"baz\":45}", "{sisi}", "baz", &xi[0], "foo", &xi[1]); U("{\"foo\":42,\"baz\":45}", "{sisi*}", "baz", &xi[0], "foo", &xi[1]); U("{\"foo\":42,\"baz\":45}", "{sisi!}", "baz", &xi[0], "foo", &xi[1]); U("{\"foo\":42,\"baz\":45}", "{si}", "baz", &xi[0], "foo", &xi[1]); U("{\"foo\":42,\"baz\":45}", "{si*}", "baz", &xi[0], "foo", &xi[1]); U("{\"foo\":42,\"baz\":45}", "{si!}", "baz", &xi[0], "foo", &xi[1]); U("[1,{\"foo\":2,\"bar\":null},[3,4]]", "[i{sisn}[ii]]", &xi[0], "foo", &xi[1], "bar", &xi[2], &xi[3]); U("[1,2,3]", "[ii!i]", &xi[0], &xi[1], &xi[2]); U("[1,2,3]", "[ii*i]", &xi[0], &xi[1], &xi[2]); U("{\"foo\":1,\"bar\":2}", "{si!si}", "foo", &xi[1], "bar", &xi[2]); U("{\"foo\":1,\"bar\":2}", "{si*si}", "foo", &xi[1], "bar", &xi[2]); U("{\"foo\":{\"baz\":null,\"bar\":null}}", "{s{sn!}}", "foo", "bar"); U("[[1,2,3]]", "[[ii!]]", &xi[0], &xi[1]); U("{}", "{s?i}", "foo", &xi[0]); U("{\"foo\":1}", "{s?i}", "foo", &xi[0]); U("{}", "{s?[ii]s?{s{si!}}}", "foo", &xi[0], &xi[1], "bar", "baz", "quux", &xi[2]); U("{\"foo\":[1,2]}", "{s?[ii]s?{s{si!}}}", "foo", &xi[0], &xi[1], "bar", "baz", "quux", &xi[2]); U("{\"bar\":{\"baz\":{\"quux\":15}}}", "{s?[ii]s?{s{si!}}}", "foo", &xi[0], &xi[1], "bar", "baz", "quux", &xi[2]); U("{\"foo\":{\"bar\":4}}", "{s?{s?i}}", "foo", "bar", &xi[0]); U("{\"foo\":{}}", "{s?{s?i}}", "foo", "bar", &xi[0]); U("{}", "{s?{s?i}}", "foo", "bar", &xi[0]); U("{\"foo\":42,\"baz\":45}", "{s?isi!}", "baz", &xi[0], "foo", &xi[1]); U("{\"foo\":42}", "{s?isi!}", "baz", &xi[0], "foo", &xi[1]); U("\"Pz8_Pz8_P2hlbGxvPj4-Pj4-Pg\"", "y", &xy[0], &xz[0]); U("\"\"", "y", &xy[0], &xz[0]); U("null", "y", &xy[0], &xz[0]); U("{\"foo\":\"Pz8_Pz8_P2hlbGxvPj4-Pj4-Pg\"}", "{s?y}", "foo", &xy[0], &xz[0]); U("{\"foo\":\"\"}", "{s?y}", "foo", &xy[0], &xz[0]); U("{}", "{s?y}", "foo", &xy[0], &xz[0]); c("null", "null", 1, 1); c("true", "true", 1, 1); c("false", "false", 1, 1); c("1", "1", 1, 1); c("1.0", "1.0", 1, 1); c("\"\"", "\"\"", 1, 1); c("\"hi\"", "\"hi\"", 1, 1); c("{}", "{}", 1, 1); c("{\"a\":true,\"b\":false}", "{\"b\":false,\"a\":true}", 1, 1); c("[]", "[]", 1, 1); c("[1,true,null]", "[1,true,null]", 1, 1); c("null", "true", 0, 0); c("null", "false", 0, 0); c("0", "1", 0, 0); c("1", "0", 0, 0); c("0", "true", 0, 0); c("0", "false", 0, 0); c("0", "null", 0, 0); c("\"hi\"", "\"hello\"", 0, 0); c("\"hello\"", "\"hi\"", 0, 0); c("{}", "null", 0, 0); c("{}", "true", 0, 0); c("{}", "1", 0, 0); c("{}", "1.0", 0, 0); c("{}", "[]", 0, 0); c("{}", "\"x\"", 0, 0); c("[1,true,null]", "[1,true]", 0, 1); c("{\"a\":true,\"b\":false}", "{\"a\":true}", 0, 1); c("{\"a\":true,\"b\":false}", "{\"a\":true,\"c\":false}", 0, 0); c("{\"a\":true,\"c\":false}", "{\"a\":true,\"b\":false}", 0, 0); return 0; }