From 4dfc9a3ef96cef95058e849378fdc2c4f58b0e65 Mon Sep 17 00:00:00 2001 From: Dmitry Volyntsev Date: Wed, 27 Mar 2019 21:00:20 +0300 Subject: [PATCH] Added njs_vm_json_parse() and njs_vm_json_stringify(). --- njs/njs.h | 5 ++ njs/njs_json.c | 25 ++++++++ njs/test/njs_unit_test.c | 129 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 159 insertions(+) diff --git a/njs/njs.h b/njs/njs.h index 334fcc87..f3d317fd 100644 --- a/njs/njs.h +++ b/njs/njs.h @@ -282,6 +282,11 @@ NXT_EXPORT njs_ret_t njs_vm_object_alloc(njs_vm_t *vm, njs_value_t *retval, NXT_EXPORT njs_value_t *njs_vm_object_prop(njs_vm_t *vm, const njs_value_t *value, const nxt_str_t *key); +NXT_EXPORT njs_ret_t njs_vm_json_parse(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs); +NXT_EXPORT njs_ret_t njs_vm_json_stringify(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs); + extern const nxt_mem_proto_t njs_vm_mp_proto; #endif /* _NJS_H_INCLUDED_ */ diff --git a/njs/njs_json.c b/njs/njs_json.c index 75aab3c6..cfbb2099 100644 --- a/njs/njs_json.c +++ b/njs/njs_json.c @@ -159,6 +159,9 @@ static nxt_int_t njs_json_buf_pullup(njs_json_stringify_t *stringify, nxt_str_t *str); +static const njs_object_prop_t njs_json_object_properties[]; + + static njs_ret_t njs_json_parse(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) @@ -248,6 +251,17 @@ memory_error: } +njs_ret_t +njs_vm_json_parse(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs) +{ + njs_function_t *parse; + + parse = njs_json_object_properties[0].value.data.u.function; + + return njs_vm_call(vm, parse, args, nargs); +} + + static njs_ret_t njs_json_stringify(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) @@ -335,6 +349,17 @@ memory_error: } +njs_ret_t +njs_vm_json_stringify(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs) +{ + njs_function_t *stringify; + + stringify = njs_json_object_properties[1].value.data.u.function; + + return njs_vm_call(vm, stringify, args, nargs); +} + + static const u_char * njs_json_parse_value(njs_json_parse_ctx_t *ctx, njs_value_t *value, const u_char *p) diff --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c index 0f48b756..016d2c17 100644 --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -12396,6 +12396,131 @@ done: } +static nxt_int_t +njs_vm_json_test(nxt_bool_t disassemble, nxt_bool_t verbose) +{ + njs_vm_t *vm; + nxt_int_t ret, rc; + nxt_str_t s, *script; + nxt_uint_t i; + nxt_bool_t success; + njs_value_t args[3]; + njs_vm_opt_t options; + + static const nxt_str_t fname = nxt_string("replacer"); + static const nxt_str_t iname = nxt_string("indent"); + + static njs_unit_test_t tests[] = { + { nxt_string("'[1, true, \"x\", {\"a\": {}}]'"), + nxt_string("[1,true,\"x\",{\"a\":{}}]") }, + { nxt_string("'{\"a\":{\"b\":1}}'"), + nxt_string("{\"a\":{\"b\":1}}") }, + { nxt_string("'[[[],{}]]'"), + nxt_string("[[[],{}]]") }, + { nxt_string("var indent = 1; '[]'"), + nxt_string("[\n \n]") }, + { nxt_string("function replacer(k, v) {return v}; '{\"a\":{\"b\":1}}'"), + nxt_string("{\"a\":{\"b\":1}}") }, + { nxt_string("function replacer(k, v) {" + " return (typeof v === 'string') ? undefined : v};" + "'{\"a\":1, \"b\":\"x\"}'"), + nxt_string("{\"a\":1}") }, + }; + + vm = NULL; + + rc = NXT_ERROR; + + for (i = 0; i < nxt_nitems(tests); i++) { + + memset(&options, 0, sizeof(njs_vm_opt_t)); + options.init = 1; + + vm = njs_vm_create(&options); + if (vm == NULL) { + nxt_printf("njs_vm_create() failed\n"); + goto done; + } + + script = &tests[i].script; + + ret = njs_vm_compile(vm, &script->start, + script->start + script->length); + + if (ret != NXT_OK) { + nxt_printf("njs_vm_compile() failed\n"); + goto done; + } + + ret = njs_vm_start(vm); + if (ret != NXT_OK) { + nxt_printf("njs_vm_run() failed\n"); + goto done; + } + + args[0] = *njs_vm_retval(vm); + + ret = njs_vm_json_parse(vm, args, 1); + if (ret != NXT_OK) { + nxt_printf("njs_vm_json_parse() failed\n"); + goto done; + } + + args[0] = vm->retval; + args[1] = *njs_vm_value(vm, &fname); + args[2] = *njs_vm_value(vm, &iname); + + ret = njs_vm_json_stringify(vm, args, 3); + if (ret != NXT_OK) { + nxt_printf("njs_vm_json_stringify() failed\n"); + goto done; + } + + if (njs_vm_retval_to_ext_string(vm, &s) != NXT_OK) { + nxt_printf("njs_vm_retval_to_ext_string() failed\n"); + goto done; + } + + success = nxt_strstr_eq(&tests[i].ret, &s); + + if (!success) { + nxt_printf("njs_vm_json_test(\"%V\")\n" + "expected: \"%V\"\n got: \"%V\"\n", script, + &tests[i].ret, &s); + + goto done; + } + + njs_vm_destroy(vm); + vm = NULL; + } + + rc = NXT_OK; + +done: + + if (rc == NXT_OK) { + nxt_printf("njs_vm_json_test passed\n"); + + } else { + if (njs_vm_retval_to_ext_string(vm, &s) != NXT_OK) { + nxt_printf("njs_vm_retval_to_ext_string() failed\n"); + + } else { + nxt_printf("%V\n", &s); + } + } + + if (vm != NULL) { + njs_vm_destroy(vm); + } + + return rc; +} + + + + static nxt_int_t njs_vm_object_alloc_test(njs_vm_t * vm, nxt_bool_t disassemble, nxt_bool_t verbose) @@ -12647,6 +12772,10 @@ main(int argc, char **argv) printf("njs timezone tests skipped, timezone is unavailable\n"); } + ret = njs_vm_json_test(disassemble, verbose); + if (ret != NXT_OK) { + return ret; + } return njs_api_test(disassemble, verbose); } -- 2.47.3