Project homepage Mailing List  Warmcat.com  API Docs  Github Mirror 
{"schema":"libjg2-1", "vpath":"/git/", "avatar":"/git/avatar/", "alang":"en-US,en;q\u003d0.5", "gen_ut":1618121308, "reponame":"libwebsockets", "desc":"libwebsockets lightweight C networking library", "owner": { "name": "Andy Green", "email": "andy@warmcat.com", "md5": "c50933ca2aa61e0fe2c43d46bb6b59cb" },"url":"https://libwebsockets.org/repo/libwebsockets", "f":3, "items": [ {"schema":"libjg2-1", "cid":"a9287c136e9412879361b40e893854e2", "oid":{ "oid": "24abd699f6a01315c4f5e0e216249ce21d54aabe", "alias": [ "refs/heads/main","refs/heads/master"]},"blobname": "lib/misc/lejp.c", "blob": "/*\n * libwebsockets - small server side websockets and web server implementation\n *\n * Copyright (C) 2010 - 2020 Andy Green \u003candy@warmcat.com\u003e\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \u0022Software\u0022), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \u0022AS IS\u0022, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n#include \u0022private-lib-core.h\u0022\n#include \u003cstring.h\u003e\n#include \u003cstdio.h\u003e\n\nstatic const char * const parser_errs[] \u003d {\n\t\u0022\u0022,\n\t\u0022\u0022,\n\t\u0022No opening '{'\u0022,\n\t\u0022Expected closing '}'\u0022,\n\t\u0022Expected '\u005c\u0022'\u0022,\n\t\u0022String underrun\u0022,\n\t\u0022Illegal unescaped control char\u0022,\n\t\u0022Illegal escape format\u0022,\n\t\u0022Illegal hex number\u0022,\n\t\u0022Expected ':'\u0022,\n\t\u0022Illegal value start\u0022,\n\t\u0022Digit required after decimal point\u0022,\n\t\u0022Bad number format\u0022,\n\t\u0022Bad exponent format\u0022,\n\t\u0022Unknown token\u0022,\n\t\u0022Too many ']'\u0022,\n\t\u0022Mismatched ']'\u0022,\n\t\u0022Expected ']'\u0022,\n\t\u0022JSON nesting limit exceeded\u0022,\n\t\u0022Nesting tracking used up\u0022,\n\t\u0022Number too long\u0022,\n\t\u0022Comma or block end expected\u0022,\n\t\u0022Unknown\u0022,\n\t\u0022Parser callback errored (see earlier error)\u0022,\n};\n\n/**\n * lejp_construct - prepare a struct lejp_ctx for use\n *\n * \u005cparam ctx:\tpointer to your struct lejp_ctx\n * \u005cparam callback:\tyour user callback which will received parsed tokens\n * \u005cparam user:\toptional user data pointer untouched by lejp\n * \u005cparam paths:\tyour array of name elements you are interested in\n * \u005cparam count_paths:\tLWS_ARRAY_SIZE() of @paths\n *\n * Prepares your context struct for use with lejp\n */\n\nvoid\nlejp_construct(struct lejp_ctx *ctx,\n\tsigned char (*callback)(struct lejp_ctx *ctx, char reason), void *user,\n\t\t\tconst char * const *paths, unsigned char count_paths)\n{\n\tctx-\u003est[0].s \u003d 0;\n\tctx-\u003est[0].p \u003d 0;\n\tctx-\u003est[0].i \u003d 0;\n\tctx-\u003est[0].b \u003d 0;\n\tctx-\u003esp \u003d 0;\n\tctx-\u003eipos \u003d 0;\n\tctx-\u003eouter_array \u003d 0;\n\tctx-\u003epath_match \u003d 0;\n\tctx-\u003epath_stride \u003d 0;\n\tctx-\u003epath[0] \u003d '\u005c0';\n\tctx-\u003euser \u003d user;\n\tctx-\u003eline \u003d 1;\n\n\tctx-\u003epst_sp \u003d 0;\n\tctx-\u003epst[0].callback \u003d callback;\n\tctx-\u003epst[0].paths \u003d paths;\n\tctx-\u003epst[0].count_paths \u003d count_paths;\n\tctx-\u003epst[0].user \u003d NULL;\n\tctx-\u003epst[0].ppos \u003d 0;\n\n\tctx-\u003epst[0].callback(ctx, LEJPCB_CONSTRUCTED);\n}\n\n/**\n * lejp_destruct - retire a previously constructed struct lejp_ctx\n *\n * \u005cparam ctx:\tpointer to your struct lejp_ctx\n *\n * lejp does not perform any allocations, but since your user code might, this\n * provides a one-time LEJPCB_DESTRUCTED callback at destruction time where\n * you can clean up in your callback.\n */\n\nvoid\nlejp_destruct(struct lejp_ctx *ctx)\n{\n\t/* no allocations... just let callback know what it happening */\n\tif (ctx-\u003epst[0].callback)\n\t\tctx-\u003epst[0].callback(ctx, LEJPCB_DESTRUCTED);\n}\n\n/**\n * lejp_change_callback - switch to a different callback from now on\n *\n * \u005cparam ctx:\tpointer to your struct lejp_ctx\n * \u005cparam callback:\tyour user callback which will received parsed tokens\n *\n * This tells the old callback it was destroyed, in case you want to take any\n * action because that callback \u0022lost focus\u0022, then changes to the new\n * callback and tells it first that it was constructed, and then started.\n *\n * Changing callback is a cheap and powerful trick to split out handlers\n * according to information earlier in the parse. For example you may have\n * a JSON pair \u0022schema\u0022 whose value defines what can be expected for the rest\n * of the JSON. Rather than having one huge callback for all cases, you can\n * have an initial one looking for \u0022schema\u0022 which then calls\n * lejp_change_callback() to a handler specific for the schema.\n *\n * Notice that afterwards, you need to construct the context again anyway to\n * parse another JSON object, and the callback is reset then to the main,\n * schema-interpreting one. The construction action is very lightweight.\n */\n\nvoid\nlejp_change_callback(struct lejp_ctx *ctx,\n\t\t signed char (*callback)(struct lejp_ctx *ctx, char reason))\n{\n\tctx-\u003epst[0].callback(ctx, LEJPCB_DESTRUCTED);\n\tctx-\u003epst[0].callback \u003d callback;\n\tctx-\u003epst[0].callback(ctx, LEJPCB_CONSTRUCTED);\n\tctx-\u003epst[0].callback(ctx, LEJPCB_START);\n}\n\nvoid\nlejp_check_path_match(struct lejp_ctx *ctx)\n{\n\tconst char *p, *q;\n\tint n;\n\tsize_t s \u003d sizeof(char *);\n\n\tif (ctx-\u003epath_stride)\n\t\ts \u003d ctx-\u003epath_stride;\n\n\t/* we only need to check if a match is not active */\n\tfor (n \u003d 0; !ctx-\u003epath_match \u0026\u0026\n\t n \u003c ctx-\u003epst[ctx-\u003epst_sp].count_paths; n++) {\n\t\tctx-\u003ewildcount \u003d 0;\n\t\tp \u003d ctx-\u003epath;\n\n\t\tq \u003d *((char **)(((char *)ctx-\u003epst[ctx-\u003epst_sp].paths) + ((unsigned int)n * s)));\n\n\t\twhile (*p \u0026\u0026 *q) {\n\t\t\tif (*q !\u003d '*') {\n\t\t\t\tif (*p !\u003d *q)\n\t\t\t\t\tbreak;\n\t\t\t\tp++;\n\t\t\t\tq++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tctx-\u003ewild[ctx-\u003ewildcount++] \u003d (uint16_t)lws_ptr_diff_size_t(p, ctx-\u003epath);\n\t\t\tq++;\n\t\t\t/*\n\t\t\t * if * has something after it, match to .\n\t\t\t * if ends with *, eat everything.\n\t\t\t * This implies match sequences must be ordered like\n\t\t\t * x.*.*\n\t\t\t * x.*\n\t\t\t * if both options are possible\n\t\t\t */\n\t\t\twhile (*p \u0026\u0026 (*p !\u003d '.' || !*q))\n\t\t\t\tp++;\n\t\t}\n\t\tif (*p || *q)\n\t\t\tcontinue;\n\n\t\tctx-\u003epath_match \u003d (uint8_t)(n + 1);\n\t\tctx-\u003epath_match_len \u003d ctx-\u003epst[ctx-\u003epst_sp].ppos;\n\t\treturn;\n\t}\n\n\tif (!ctx-\u003epath_match)\n\t\tctx-\u003ewildcount \u003d 0;\n}\n\nint\nlejp_get_wildcard(struct lejp_ctx *ctx, int wildcard, char *dest, int len)\n{\n\tint n;\n\n\tif (wildcard \u003e\u003d ctx-\u003ewildcount || !len)\n\t\treturn 0;\n\n\tn \u003d ctx-\u003ewild[wildcard];\n\n\twhile (--len \u0026\u0026 n \u003c ctx-\u003epst[ctx-\u003epst_sp].ppos \u0026\u0026\n\t (n \u003d\u003d ctx-\u003ewild[wildcard] || ctx-\u003epath[n] !\u003d '.'))\n\t\t*dest++ \u003d ctx-\u003epath[n++];\n\n\t*dest \u003d '\u005c0';\n\tn++;\n\n\treturn n - ctx-\u003ewild[wildcard];\n}\n\n/**\n * lejp_parse - interpret some more incoming data incrementally\n *\n * \u005cparam ctx:\tpreviously constructed parsing context\n * \u005cparam json:\tchar buffer with the new data to interpret\n * \u005cparam len:\tamount of data in the buffer\n *\n * Because lejp is a stream parser, it incrementally parses as new data\n * becomes available, maintaining all state in the context struct. So an\n * incomplete JSON is a normal situation, getting you a LEJP_CONTINUE\n * return, signalling there's no error but to call again with more data when\n * it comes to complete the parsing. Successful parsing completes with a\n * 0 or positive integer indicating how much of the last input buffer was\n * unused.\n */\n\nstatic const char esc_char[] \u003d \u0022\u005c\u0022\u005c\u005c/bfnrt\u0022;\nstatic const char esc_tran[] \u003d \u0022\u005c\u0022\u005c\u005c/\u005cb\u005cf\u005cn\u005cr\u005ct\u0022;\nstatic const char tokens[] \u003d \u0022rue alse ull \u0022;\n\nint\nlejp_parse(struct lejp_ctx *ctx, const unsigned char *json, int len)\n{\n\tunsigned char c, n, s;\n\tint ret \u003d LEJP_REJECT_UNKNOWN;\n\n\tif (!ctx-\u003esp \u0026\u0026 !ctx-\u003epst[ctx-\u003epst_sp].ppos)\n\t\tctx-\u003epst[ctx-\u003epst_sp].callback(ctx, LEJPCB_START);\n\n\twhile (len--) {\n\t\tc \u003d *json++;\n\t\ts \u003d (unsigned char)ctx-\u003est[ctx-\u003esp].s;\n\n\t\t/* skip whitespace unless we should care */\n\t\tif (c \u003d\u003d ' ' || c \u003d\u003d '\u005ct' || c \u003d\u003d '\u005cn' || c \u003d\u003d '\u005cr' || c \u003d\u003d '#') {\n\t\t\tif (c \u003d\u003d '\u005cn') {\n\t\t\t\tctx-\u003eline++;\n\t\t\t\tctx-\u003est[ctx-\u003esp].s \u0026\u003d (char)~LEJP_FLAG_WS_COMMENTLINE;\n\t\t\t}\n\t\t\tif (!(s \u0026 LEJP_FLAG_WS_KEEP)) {\n\t\t\t\tif (c \u003d\u003d '#')\n\t\t\t\t\tctx-\u003est[ctx-\u003esp].s |\u003d\n\t\t\t\t\t\tLEJP_FLAG_WS_COMMENTLINE;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tif (ctx-\u003est[ctx-\u003esp].s \u0026 LEJP_FLAG_WS_COMMENTLINE)\n\t\t\tcontinue;\n\n\t\tswitch (s) {\n\t\tcase LEJP_IDLE:\n\t\t\tif (!ctx-\u003esp \u0026\u0026 c \u003d\u003d '[') {\n\t\t\t\t/* push */\n\t\t\t\tctx-\u003eouter_array \u003d 1;\n\t\t\t\tctx-\u003est[ctx-\u003esp].s \u003d LEJP_MP_ARRAY_END;\n\t\t\t\tc \u003d LEJP_MP_VALUE;\n\t\t\t\tctx-\u003epath[ctx-\u003epst[ctx-\u003epst_sp].ppos++] \u003d '[';\n\t\t\t\tctx-\u003epath[ctx-\u003epst[ctx-\u003epst_sp].ppos++] \u003d ']';\n\t\t\t\tctx-\u003epath[ctx-\u003epst[ctx-\u003epst_sp].ppos] \u003d '\u005c0';\n\t\t\t\tif (ctx-\u003epst[ctx-\u003epst_sp].callback(ctx, LEJPCB_ARRAY_START))\n\t\t\t\t\tgoto reject_callback;\n\t\t\t\tctx-\u003ei[ctx-\u003eipos++] \u003d 0;\n\t\t\t\tif (ctx-\u003eipos \u003e LWS_ARRAY_SIZE(ctx-\u003ei)) {\n\t\t\t\t\tret \u003d LEJP_REJECT_MP_DELIM_ISTACK;\n\t\t\t\t\tgoto reject;\n\t\t\t\t}\n\t\t\t\tgoto add_stack_level;\n\t\t\t}\n\t\t\tif (c !\u003d '{') {\n\t\t\t\tret \u003d LEJP_REJECT_IDLE_NO_BRACE;\n\t\t\t\tgoto reject;\n\t\t\t}\n\t\t\tif (ctx-\u003epst[ctx-\u003epst_sp].callback(ctx,\n\t\t\t\t\t\t\t LEJPCB_OBJECT_START))\n\t\t\t\tgoto reject_callback;\n\t\t\tctx-\u003est[ctx-\u003esp].s \u003d LEJP_MEMBERS;\n\t\t\tbreak;\n\t\tcase LEJP_MEMBERS:\n\t\t\tif (c \u003d\u003d '}') {\n\t\t\t\tif (ctx-\u003esp \u003e\u003d 1)\n\t\t\t\t\tgoto pop_level;\n\n\t\t\t\tctx-\u003est[ctx-\u003esp].s \u003d LEJP_IDLE;\n\t\t\t\tret \u003d LEJP_REJECT_MEMBERS_NO_CLOSE;\n\t\t\t\tgoto reject;\n\t\t\t}\n\t\t\tctx-\u003est[ctx-\u003esp].s \u003d LEJP_M_P;\n\t\t\tgoto redo_character;\n\t\tcase LEJP_M_P:\n\t\t\tif (c !\u003d '\u005c\u0022') {\n\t\t\t\tret \u003d LEJP_REJECT_MP_NO_OPEN_QUOTE;\n\t\t\t\tgoto reject;\n\t\t\t}\n\t\t\t/* push */\n\t\t\tctx-\u003est[ctx-\u003esp].s \u003d LEJP_MP_DELIM;\n\t\t\tc \u003d LEJP_MP_STRING;\n\t\t\tgoto add_stack_level;\n\n\t\tcase LEJP_MP_STRING:\n\t\t\tif (c \u003d\u003d '\u005c\u0022') {\n\t\t\t\tif (!ctx-\u003esp) { /* JSON can't end on quote */\n\t\t\t\t\tret \u003d LEJP_REJECT_MP_STRING_UNDERRUN;\n\t\t\t\t\tgoto reject;\n\t\t\t\t}\n\t\t\t\tif (ctx-\u003est[ctx-\u003esp - 1].s !\u003d LEJP_MP_DELIM) {\n\t\t\t\t\tctx-\u003ebuf[ctx-\u003enpos] \u003d '\u005c0';\n\t\t\t\t\tif (ctx-\u003epst[ctx-\u003epst_sp].callback(ctx,\n\t\t\t\t\t\t LEJPCB_VAL_STR_END) \u003c 0)\n\t\t\t\t\t\tgoto reject_callback;\n\t\t\t\t}\n\t\t\t\t/* pop */\n\t\t\t\tctx-\u003esp--;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (c \u003d\u003d '\u005c\u005c') {\n\t\t\t\tctx-\u003est[ctx-\u003esp].s \u003d LEJP_MP_STRING_ESC;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (c \u003c ' ') {/* \u0022control characters\u0022 not allowed */\n\t\t\t\tret \u003d LEJP_REJECT_MP_ILLEGAL_CTRL;\n\t\t\t\tgoto reject;\n\t\t\t}\n\t\t\tgoto emit_string_char;\n\n\t\tcase LEJP_MP_STRING_ESC:\n\t\t\tif (c \u003d\u003d 'u') {\n\t\t\t\tctx-\u003est[ctx-\u003esp].s \u003d LEJP_MP_STRING_ESC_U1;\n\t\t\t\tctx-\u003euni \u003d 0;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tfor (n \u003d 0; n \u003c sizeof(esc_char); n++) {\n\t\t\t\tif (c !\u003d esc_char[n])\n\t\t\t\t\tcontinue;\n\t\t\t\t/* found it */\n\t\t\t\tc \u003d (unsigned char)esc_tran[n];\n\t\t\t\tctx-\u003est[ctx-\u003esp].s \u003d LEJP_MP_STRING;\n\t\t\t\tgoto emit_string_char;\n\t\t\t}\n\t\t\tret \u003d LEJP_REJECT_MP_STRING_ESC_ILLEGAL_ESC;\n\t\t\t/* illegal escape char */\n\t\t\tgoto reject;\n\n\t\tcase LEJP_MP_STRING_ESC_U1:\n\t\tcase LEJP_MP_STRING_ESC_U2:\n\t\tcase LEJP_MP_STRING_ESC_U3:\n\t\tcase LEJP_MP_STRING_ESC_U4:\n\t\t\tctx-\u003euni \u003d (uint16_t)(ctx-\u003euni \u003c\u003c 4);\n\t\t\tif (c \u003e\u003d '0' \u0026\u0026 c \u003c\u003d '9')\n\t\t\t\tctx-\u003euni |\u003d (uint16_t)(c - '0');\n\t\t\telse\n\t\t\t\tif (c \u003e\u003d 'a' \u0026\u0026 c \u003c\u003d 'f')\n\t\t\t\t\tctx-\u003euni |\u003d (uint16_t)(c - 'a' + 10);\n\t\t\t\telse\n\t\t\t\t\tif (c \u003e\u003d 'A' \u0026\u0026 c \u003c\u003d 'F')\n\t\t\t\t\t\tctx-\u003euni |\u003d (uint16_t)(c - 'A' + 10);\n\t\t\t\t\telse {\n\t\t\t\t\t\tret \u003d LEJP_REJECT_ILLEGAL_HEX;\n\t\t\t\t\t\tgoto reject;\n\t\t\t\t\t}\n\t\t\tctx-\u003est[ctx-\u003esp].s++;\n\t\t\tswitch (s) {\n\t\t\tcase LEJP_MP_STRING_ESC_U2:\n\t\t\t\tif (ctx-\u003euni \u003c 0x08)\n\t\t\t\t\tbreak;\n\t\t\t\t/*\n\t\t\t\t * 0x08-0xff (0x0800 - 0xffff)\n\t\t\t\t * emit 3-byte UTF-8\n\t\t\t\t */\n\t\t\t\tc \u003d (unsigned char)(0xe0 | ((ctx-\u003euni \u003e\u003e 4) \u0026 0xf));\n\t\t\t\tgoto emit_string_char;\n\n\t\t\tcase LEJP_MP_STRING_ESC_U3:\n\t\t\t\tif (ctx-\u003euni \u003e\u003d 0x080) {\n\t\t\t\t\t/*\n\t\t\t\t\t * 0x080 - 0xfff (0x0800 - 0xffff)\n\t\t\t\t\t * middle 3-byte seq\n\t\t\t\t\t * send ....XXXXXX..\n\t\t\t\t\t */\n\t\t\t\t\tc \u003d (unsigned char)(0x80 | ((ctx-\u003euni \u003e\u003e 2) \u0026 0x3f));\n\t\t\t\t\tgoto emit_string_char;\n\t\t\t\t}\n\t\t\t\tif (ctx-\u003euni \u003c 0x008)\n\t\t\t\t\tbreak;\n\t\t\t\t/*\n\t\t\t\t * 0x008 - 0x7f (0x0080 - 0x07ff)\n\t\t\t\t * start 2-byte seq\n\t\t\t\t */\n\t\t\t\tc \u003d (unsigned char)(0xc0 | (ctx-\u003euni \u003e\u003e 2));\n\t\t\t\tgoto emit_string_char;\n\n\t\t\tcase LEJP_MP_STRING_ESC_U4:\n\t\t\t\tif (ctx-\u003euni \u003e\u003d 0x0080)\n\t\t\t\t\t/* end of 2 or 3-byte seq */\n\t\t\t\t\tc \u003d (unsigned char)(0x80 | (ctx-\u003euni \u0026 0x3f));\n\t\t\t\telse\n\t\t\t\t\t/* literal */\n\t\t\t\t\tc \u003d (unsigned char)ctx-\u003euni;\n\n\t\t\t\tctx-\u003est[ctx-\u003esp].s \u003d LEJP_MP_STRING;\n\t\t\t\tgoto emit_string_char;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase LEJP_MP_DELIM:\n\t\t\tif (c !\u003d ':') {\n\t\t\t\tret \u003d LEJP_REJECT_MP_DELIM_MISSING_COLON;\n\t\t\t\tgoto reject;\n\t\t\t}\n\t\t\tctx-\u003est[ctx-\u003esp].s \u003d LEJP_MP_VALUE;\n\t\t\tctx-\u003epath[ctx-\u003epst[ctx-\u003epst_sp].ppos] \u003d '\u005c0';\n\n\t\t\tlejp_check_path_match(ctx);\n\t\t\tif (ctx-\u003epst[ctx-\u003epst_sp].callback(ctx, LEJPCB_PAIR_NAME))\n\t\t\t\tgoto reject_callback;\n\t\t\tbreak;\n\n\t\tcase LEJP_MP_VALUE:\n\t\t\tif (c \u003d\u003d '-' || (c \u003e\u003d '0' \u0026\u0026 c \u003c\u003d '9')) {\n\t\t\t\tctx-\u003enpos \u003d 0;\n\t\t\t\tctx-\u003edcount \u003d 0;\n\t\t\t\tctx-\u003ef \u003d 0;\n\t\t\t\tctx-\u003est[ctx-\u003esp].s \u003d LEJP_MP_VALUE_NUM_INT;\n\t\t\t\tgoto redo_character;\n\t\t\t}\n\t\t\tswitch (c) {\n\t\t\tcase'\u005c\u0022':\n\t\t\t\t/* push */\n\t\t\t\tctx-\u003est[ctx-\u003esp].s \u003d LEJP_MP_COMMA_OR_END;\n\t\t\t\tc \u003d LEJP_MP_STRING;\n\t\t\t\tctx-\u003enpos \u003d 0;\n\t\t\t\tctx-\u003ebuf[0] \u003d '\u005c0';\n\t\t\t\tif (ctx-\u003epst[ctx-\u003epst_sp].callback(ctx,\n\t\t\t\t\t\t\tLEJPCB_VAL_STR_START))\n\t\t\t\t\tgoto reject_callback;\n\t\t\t\tgoto add_stack_level;\n\n\t\t\tcase '{':\n\t\t\t\t/* push */\n\t\t\t\tctx-\u003est[ctx-\u003esp].s \u003d LEJP_MP_COMMA_OR_END;\n\t\t\t\tc \u003d LEJP_MEMBERS;\n\t\t\t\tlejp_check_path_match(ctx);\n\t\t\t\tif (ctx-\u003epst[ctx-\u003epst_sp].callback(ctx,\n\t\t\t\t\t\t\tLEJPCB_OBJECT_START))\n\t\t\t\t\tgoto reject_callback;\n\t\t\t\tctx-\u003epath_match \u003d 0;\n\t\t\t\tgoto add_stack_level;\n\n\t\t\tcase '[':\n\t\t\t\t/* push */\n\t\t\t\tctx-\u003est[ctx-\u003esp].s \u003d LEJP_MP_ARRAY_END;\n\t\t\t\tc \u003d LEJP_MP_VALUE;\n\t\t\t\tctx-\u003epath[ctx-\u003epst[ctx-\u003epst_sp].ppos++] \u003d '[';\n\t\t\t\tctx-\u003epath[ctx-\u003epst[ctx-\u003epst_sp].ppos++] \u003d ']';\n\t\t\t\tctx-\u003epath[ctx-\u003epst[ctx-\u003epst_sp].ppos] \u003d '\u005c0';\n\t\t\t\tif (ctx-\u003epst[ctx-\u003epst_sp].callback(ctx, LEJPCB_ARRAY_START))\n\t\t\t\t\tgoto reject_callback;\n\t\t\t\tctx-\u003ei[ctx-\u003eipos++] \u003d 0;\n\t\t\t\tif (ctx-\u003eipos \u003e LWS_ARRAY_SIZE(ctx-\u003ei)) {\n\t\t\t\t\tret \u003d LEJP_REJECT_MP_DELIM_ISTACK;\n\t\t\t\t\tgoto reject;\n\t\t\t\t}\n\t\t\t\tgoto add_stack_level;\n\n\t\t\tcase ']':\n\t\t\t\t/* pop */\n\t\t\t\tif (!ctx-\u003esp) { /* JSON can't end on ] */\n\t\t\t\t\tret \u003d LEJP_REJECT_MP_C_OR_E_UNDERF;\n\t\t\t\t\tgoto reject;\n\t\t\t\t}\n\t\t\t\tctx-\u003esp--;\n\t\t\t\tif (ctx-\u003est[ctx-\u003esp].s !\u003d LEJP_MP_ARRAY_END) {\n\t\t\t\t\tret \u003d LEJP_REJECT_MP_C_OR_E_NOTARRAY;\n\t\t\t\t\tgoto reject;\n\t\t\t\t}\n\t\t\t\t/* drop the path [n] bit */\n\t\t\t\tif (ctx-\u003esp) {\n\t\t\t\t\tctx-\u003epst[ctx-\u003epst_sp].ppos \u003d (unsigned char)\n\t\t\t\t\t\t\tctx-\u003est[ctx-\u003esp - 1].p;\n\t\t\t\t\tctx-\u003eipos \u003d (unsigned char)ctx-\u003est[ctx-\u003esp - 1].i;\n\t\t\t\t}\n\t\t\t\tctx-\u003epath[ctx-\u003epst[ctx-\u003epst_sp].ppos] \u003d '\u005c0';\n\t\t\t\tif (ctx-\u003epath_match \u0026\u0026\n\t\t\t\t ctx-\u003epst[ctx-\u003epst_sp].ppos \u003c\u003d ctx-\u003epath_match_len)\n\t\t\t\t\t/*\n\t\t\t\t\t * we shrank the path to be\n\t\t\t\t\t * smaller than the matching point\n\t\t\t\t\t */\n\t\t\t\t\tctx-\u003epath_match \u003d 0;\n\t\t\t\tif (ctx-\u003eouter_array \u0026\u0026 !ctx-\u003esp) { /* ended on ] */\n\t\t\t\t\tn \u003d LEJPCB_ARRAY_END;\n\t\t\t\t\tgoto completed;\n\t\t\t\t}\n\t\t\t\tgoto array_end;\n\n\t\t\tcase 't': /* true */\n\t\t\t\tctx-\u003euni \u003d 0;\n\t\t\t\tctx-\u003est[ctx-\u003esp].s \u003d LEJP_MP_VALUE_TOK;\n\t\t\t\tbreak;\n\n\t\t\tcase 'f':\n\t\t\t\tctx-\u003euni \u003d 4;\n\t\t\t\tctx-\u003est[ctx-\u003esp].s \u003d LEJP_MP_VALUE_TOK;\n\t\t\t\tbreak;\n\n\t\t\tcase 'n':\n\t\t\t\tctx-\u003euni \u003d 4 + 5;\n\t\t\t\tctx-\u003est[ctx-\u003esp].s \u003d LEJP_MP_VALUE_TOK;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tret \u003d LEJP_REJECT_MP_DELIM_BAD_VALUE_START;\n\t\t\t\tgoto reject;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase LEJP_MP_VALUE_NUM_INT:\n\t\t\tif (!ctx-\u003enpos \u0026\u0026 c \u003d\u003d '-') {\n\t\t\t\tctx-\u003ef |\u003d LEJP_SEEN_MINUS;\n\t\t\t\tgoto append_npos;\n\t\t\t}\n\n\t\t\tif (ctx-\u003edcount \u003c 20 \u0026\u0026 c \u003e\u003d '0' \u0026\u0026 c \u003c\u003d '9') {\n\t\t\t\tif (ctx-\u003ef \u0026 LEJP_SEEN_POINT)\n\t\t\t\t\tctx-\u003ef |\u003d LEJP_SEEN_POST_POINT;\n\t\t\t\tctx-\u003edcount++;\n\t\t\t\tgoto append_npos;\n\t\t\t}\n\t\t\tif (c \u003d\u003d '.') {\n\t\t\t\tif (!ctx-\u003edcount || (ctx-\u003ef \u0026 LEJP_SEEN_POINT)) {\n\t\t\t\t\tret \u003d LEJP_REJECT_MP_VAL_NUM_FORMAT;\n\t\t\t\t\tgoto reject;\n\t\t\t\t}\n\t\t\t\tctx-\u003ef |\u003d LEJP_SEEN_POINT;\n\t\t\t\tgoto append_npos;\n\t\t\t}\n\t\t\t/*\n\t\t\t * before exponent, if we had . we must have had at\n\t\t\t * least one more digit\n\t\t\t */\n\t\t\tif ((ctx-\u003ef \u0026\n\t\t\t\t(LEJP_SEEN_POINT | LEJP_SEEN_POST_POINT)) \u003d\u003d\n\t\t\t\t\t\t\t LEJP_SEEN_POINT) {\n\t\t\t\tret \u003d LEJP_REJECT_MP_VAL_NUM_INT_NO_FRAC;\n\t\t\t\tgoto reject;\n\t\t\t}\n\t\t\tif (c \u003d\u003d 'e' || c \u003d\u003d 'E') {\n\t\t\t\tif (ctx-\u003ef \u0026 LEJP_SEEN_EXP) {\n\t\t\t\t\tret \u003d LEJP_REJECT_MP_VAL_NUM_FORMAT;\n\t\t\t\t\tgoto reject;\n\t\t\t\t}\n\t\t\t\tctx-\u003ef |\u003d LEJP_SEEN_EXP;\n\t\t\t\tctx-\u003est[ctx-\u003esp].s \u003d LEJP_MP_VALUE_NUM_EXP;\n\t\t\t\tgoto append_npos;\n\t\t\t}\n\t\t\t/* if none of the above, did we even have a number? */\n\t\t\tif (!ctx-\u003edcount) {\n\t\t\t\tret \u003d LEJP_REJECT_MP_VAL_NUM_FORMAT;\n\t\t\t\tgoto reject;\n\t\t\t}\n\n\t\t\tctx-\u003ebuf[ctx-\u003enpos] \u003d '\u005c0';\n\t\t\tif (ctx-\u003ef \u0026 LEJP_SEEN_POINT) {\n\t\t\t\tif (ctx-\u003epst[ctx-\u003epst_sp].callback(ctx,\n\t\t\t\t\t\t\tLEJPCB_VAL_NUM_FLOAT))\n\t\t\t\t\tgoto reject_callback;\n\t\t\t} else {\n\t\t\t\tif (ctx-\u003epst[ctx-\u003epst_sp].callback(ctx,\n\t\t\t\t\t\t\tLEJPCB_VAL_NUM_INT))\n\t\t\t\t\tgoto reject_callback;\n\t\t\t}\n\n\t\t\t/* then this is the post-number character, loop */\n\t\t\tctx-\u003est[ctx-\u003esp].s \u003d LEJP_MP_COMMA_OR_END;\n\t\t\tgoto redo_character;\n\n\t\tcase LEJP_MP_VALUE_NUM_EXP:\n\t\t\tctx-\u003est[ctx-\u003esp].s \u003d LEJP_MP_VALUE_NUM_INT;\n\t\t\tif (c \u003e\u003d '0' \u0026\u0026 c \u003c\u003d '9')\n\t\t\t\tgoto redo_character;\n\t\t\tif (c \u003d\u003d '+' || c \u003d\u003d '-')\n\t\t\t\tgoto append_npos;\n\t\t\tret \u003d LEJP_REJECT_MP_VAL_NUM_EXP_BAD_EXP;\n\t\t\tgoto reject;\n\n\t\tcase LEJP_MP_VALUE_TOK: /* true, false, null */\n\t\t\tif (c !\u003d tokens[ctx-\u003euni]) {\n\t\t\t\tret \u003d LEJP_REJECT_MP_VAL_TOK_UNKNOWN;\n\t\t\t\tgoto reject;\n\t\t\t}\n\t\t\tctx-\u003euni++;\n\t\t\tif (tokens[ctx-\u003euni] !\u003d ' ')\n\t\t\t\tbreak;\n\t\t\tswitch (ctx-\u003euni) {\n\t\t\tcase 3:\n\t\t\t\tctx-\u003ebuf[0] \u003d '1';\n\t\t\t\tctx-\u003ebuf[1] \u003d '\u005c0';\n\t\t\t\tif (ctx-\u003epst[ctx-\u003epst_sp].callback(ctx,\n\t\t\t\t\t\t\t\tLEJPCB_VAL_TRUE))\n\t\t\t\t\tgoto reject_callback;\n\t\t\t\tbreak;\n\t\t\tcase 8:\n\t\t\t\tctx-\u003ebuf[0] \u003d '0';\n\t\t\t\tctx-\u003ebuf[1] \u003d '\u005c0';\n\t\t\t\tif (ctx-\u003epst[ctx-\u003epst_sp].callback(ctx,\n\t\t\t\t\t\t\t\tLEJPCB_VAL_FALSE))\n\t\t\t\t\tgoto reject_callback;\n\t\t\t\tbreak;\n\t\t\tcase 12:\n\t\t\t\tctx-\u003ebuf[0] \u003d '\u005c0';\n\t\t\t\tif (ctx-\u003epst[ctx-\u003epst_sp].callback(ctx,\n\t\t\t\t\t\t\t\tLEJPCB_VAL_NULL))\n\t\t\t\t\tgoto reject_callback;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tctx-\u003est[ctx-\u003esp].s \u003d LEJP_MP_COMMA_OR_END;\n\t\t\tbreak;\n\n\t\tcase LEJP_MP_COMMA_OR_END:\n\t\t\tctx-\u003epath[ctx-\u003epst[ctx-\u003epst_sp].ppos] \u003d '\u005c0';\n\t\t\tif (c \u003d\u003d ',') {\n\t\t\t\t/* increment this stack level's index */\n\t\t\t\tctx-\u003est[ctx-\u003esp].s \u003d LEJP_M_P;\n\t\t\t\tif (!ctx-\u003esp) {\n\t\t\t\t\tctx-\u003epst[ctx-\u003epst_sp].ppos \u003d 0;\n\t\t\t\t\t/*\n\t\t\t\t\t * since we came back to root level,\n\t\t\t\t\t * no path can still match\n\t\t\t\t\t */\n\t\t\t\t\tctx-\u003epath_match \u003d 0;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tctx-\u003epst[ctx-\u003epst_sp].ppos \u003d (unsigned char)ctx-\u003est[ctx-\u003esp - 1].p;\n\t\t\t\tctx-\u003epath[ctx-\u003epst[ctx-\u003epst_sp].ppos] \u003d '\u005c0';\n\t\t\t\tif (ctx-\u003epath_match \u0026\u0026\n\t\t\t\t ctx-\u003epst[ctx-\u003epst_sp].ppos \u003c\u003d ctx-\u003epath_match_len)\n\t\t\t\t\t/*\n\t\t\t\t\t * we shrank the path to be\n\t\t\t\t\t * smaller than the matching point\n\t\t\t\t\t */\n\t\t\t\t\tctx-\u003epath_match \u003d 0;\n\n\t\t\t\tif (ctx-\u003est[ctx-\u003esp - 1].s !\u003d LEJP_MP_ARRAY_END)\n\t\t\t\t\tbreak;\n\t\t\t\t/* top level is definitely an array... */\n\t\t\t\tif (ctx-\u003eipos)\n\t\t\t\t\tctx-\u003ei[ctx-\u003eipos - 1]++;\n\t\t\t\tctx-\u003est[ctx-\u003esp].s \u003d LEJP_MP_VALUE;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (c \u003d\u003d ']') {\n\t\t\t\tif (!ctx-\u003esp) {\n\t\t\t\t\tret \u003d LEJP_REJECT_MP_C_OR_E_UNDERF;\n\t\t\t\t\tgoto reject;\n\t\t\t\t}\n\t\t\t\t/* pop */\n\t\t\t\tctx-\u003esp--;\n\t\t\t\tif (ctx-\u003est[ctx-\u003esp].s !\u003d LEJP_MP_ARRAY_END) {\n\t\t\t\t\tret \u003d LEJP_REJECT_MP_C_OR_E_NOTARRAY;\n\t\t\t\t\tgoto reject;\n\t\t\t\t}\n\n\t\t\t\t/* drop the path [n] bit */\n\t\t\t\tif (ctx-\u003esp) {\n\t\t\t\t\tctx-\u003epst[ctx-\u003epst_sp].ppos \u003d (unsigned char)\n\t\t\t\t\t\t\tctx-\u003est[ctx-\u003esp - 1].p;\n\t\t\t\t\tctx-\u003eipos \u003d (unsigned char)ctx-\u003est[ctx-\u003esp - 1].i;\n\t\t\t\t}\n\t\t\t\tctx-\u003epath[ctx-\u003epst[ctx-\u003epst_sp].ppos] \u003d '\u005c0';\n\t\t\t\tif (ctx-\u003epath_match \u0026\u0026\n\t\t\t\t ctx-\u003epst[ctx-\u003epst_sp].ppos \u003c\u003d ctx-\u003epath_match_len)\n\t\t\t\t\t/*\n\t\t\t\t\t * we shrank the path to be\n\t\t\t\t\t * smaller than the matching point\n\t\t\t\t\t */\n\t\t\t\t\tctx-\u003epath_match \u003d 0;\n\n\t\t\t\tif (ctx-\u003eouter_array \u0026\u0026 !ctx-\u003esp) { /* ended on ] */\n\t\t\t\t\tn \u003d LEJPCB_ARRAY_END;\n\t\t\t\t\tgoto completed;\n\t\t\t\t}\n\n\t\t\t\t/* do LEJP_MP_ARRAY_END processing */\n\t\t\t\tgoto redo_character;\n\t\t\t}\n\t\t\tif (c !\u003d '}') {\n\t\t\t\tret \u003d LEJP_REJECT_MP_C_OR_E_NEITHER;\n\t\t\t\tgoto reject;\n\t\t\t}\n\t\t\tif (!ctx-\u003esp) {\n\t\t\t\tn \u003d LEJPCB_OBJECT_END;\ncompleted:\n\t\t\t\tlejp_check_path_match(ctx);\n\t\t\t\tif (ctx-\u003epst[ctx-\u003epst_sp].callback(ctx, (char)n) ||\n\t\t\t\t ctx-\u003epst[ctx-\u003epst_sp].callback(ctx,\n\t\t\t\t\t\t\t LEJPCB_COMPLETE))\n\t\t\t\t\tgoto reject_callback;\n\n\t\t\t\t/* done, return unused amount */\n\t\t\t\treturn len;\n\t\t\t}\n\n\t\t\t/* pop */\npop_level:\n\t\t\tctx-\u003esp--;\n\t\t\tif (ctx-\u003esp) {\n\t\t\t\tctx-\u003epst[ctx-\u003epst_sp].ppos \u003d (unsigned char)ctx-\u003est[ctx-\u003esp].p;\n\t\t\t\tctx-\u003eipos \u003d (unsigned char)ctx-\u003est[ctx-\u003esp].i;\n\t\t\t}\n\t\t\tctx-\u003epath[ctx-\u003epst[ctx-\u003epst_sp].ppos] \u003d '\u005c0';\n\t\t\tif (ctx-\u003epath_match \u0026\u0026\n\t\t\t ctx-\u003epst[ctx-\u003epst_sp].ppos \u003c\u003d ctx-\u003epath_match_len)\n\t\t\t\t/*\n\t\t\t\t * we shrank the path to be\n\t\t\t\t * smaller than the matching point\n\t\t\t\t */\n\t\t\t\tctx-\u003epath_match \u003d 0;\n\n\t\t\tlejp_check_path_match(ctx);\n\t\t\tif (ctx-\u003epst[ctx-\u003epst_sp].callback(ctx,\n\t\t\t\t\t\t\t LEJPCB_OBJECT_END))\n\t\t\t\tgoto reject_callback;\n\t\t\tbreak;\n\n\t\tcase LEJP_MP_ARRAY_END:\narray_end:\n\t\t\tctx-\u003epath[ctx-\u003epst[ctx-\u003epst_sp].ppos] \u003d '\u005c0';\n\t\t\tif (c \u003d\u003d ',') {\n\t\t\t\t/* increment this stack level's index */\n\t\t\t\tif (ctx-\u003eipos)\n\t\t\t\t\tctx-\u003ei[ctx-\u003eipos - 1]++;\n\t\t\t\tctx-\u003est[ctx-\u003esp].s \u003d LEJP_MP_VALUE;\n\t\t\t\tif (ctx-\u003esp)\n\t\t\t\t\tctx-\u003epst[ctx-\u003epst_sp].ppos \u003d (unsigned char)\n\t\t\t\t\t\t\tctx-\u003est[ctx-\u003esp - 1].p;\n\t\t\t\tctx-\u003epath[ctx-\u003epst[ctx-\u003epst_sp].ppos] \u003d '\u005c0';\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (c !\u003d ']') {\n\t\t\t\tret \u003d LEJP_REJECT_MP_ARRAY_END_MISSING;\n\t\t\t\tgoto reject;\n\t\t\t}\n\n\t\t\tctx-\u003est[ctx-\u003esp].s \u003d LEJP_MP_COMMA_OR_END;\n\t\t\tctx-\u003epst[ctx-\u003epst_sp].callback(ctx, LEJPCB_ARRAY_END);\n\t\t\tbreak;\n\t\t}\n\n\t\tcontinue;\n\nemit_string_char:\n\t\tif (!ctx-\u003esp || ctx-\u003est[ctx-\u003esp - 1].s !\u003d LEJP_MP_DELIM) {\n\t\t\t/* assemble the string value into chunks */\n\t\t\tctx-\u003ebuf[ctx-\u003enpos++] \u003d (char)c;\n\t\t\tif (ctx-\u003enpos \u003d\u003d sizeof(ctx-\u003ebuf) - 1) {\n\t\t\t\tif (ctx-\u003epst[ctx-\u003epst_sp].callback(ctx,\n\t\t\t\t\t\t\t LEJPCB_VAL_STR_CHUNK))\n\t\t\t\t\tgoto reject_callback;\n\t\t\t\tctx-\u003enpos \u003d 0;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\t/* name part of name:value pair */\n\t\tctx-\u003epath[ctx-\u003epst[ctx-\u003epst_sp].ppos++] \u003d (char)c;\n\t\tcontinue;\n\nadd_stack_level:\n\t\t/* push on to the object stack */\n\t\tif (ctx-\u003epst[ctx-\u003epst_sp].ppos \u0026\u0026\n\t\t ctx-\u003est[ctx-\u003esp].s !\u003d LEJP_MP_COMMA_OR_END \u0026\u0026\n\t\t ctx-\u003est[ctx-\u003esp].s !\u003d LEJP_MP_ARRAY_END)\n\t\t\tctx-\u003epath[ctx-\u003epst[ctx-\u003epst_sp].ppos++] \u003d '.';\n\n\t\tctx-\u003est[ctx-\u003esp].p \u003d (char)ctx-\u003epst[ctx-\u003epst_sp].ppos;\n\t\tctx-\u003est[ctx-\u003esp].i \u003d (char)ctx-\u003eipos;\n\t\tif (++ctx-\u003esp \u003d\u003d LWS_ARRAY_SIZE(ctx-\u003est)) {\n\t\t\tret \u003d LEJP_REJECT_STACK_OVERFLOW;\n\t\t\tgoto reject;\n\t\t}\n\t\tctx-\u003epath[ctx-\u003epst[ctx-\u003epst_sp].ppos] \u003d '\u005c0';\n\t\tctx-\u003est[ctx-\u003esp].s \u003d (char)c;\n\t\tctx-\u003est[ctx-\u003esp].b \u003d 0;\n\t\tcontinue;\n\nappend_npos:\n\t\tif (ctx-\u003enpos \u003e\u003d sizeof(ctx-\u003ebuf)) {\n\t\t\tret \u003d LEJP_REJECT_NUM_TOO_LONG;\n\t\t\tgoto reject;\n\t\t}\n\t\tctx-\u003ebuf[ctx-\u003enpos++] \u003d (char)c;\n\t\tcontinue;\n\nredo_character:\n\t\tjson--;\n\t\tlen++;\n\t}\n\n\treturn LEJP_CONTINUE;\n\n\nreject_callback:\n\tret \u003d LEJP_REJECT_CALLBACK;\n\nreject:\n\tctx-\u003epst[ctx-\u003epst_sp].callback(ctx, LEJPCB_FAILED);\n\treturn ret;\n}\n\nint\nlejp_parser_push(struct lejp_ctx *ctx, void *user, const char * const *paths,\n\t\t unsigned char paths_count, lejp_callback lejp_cb)\n{\n\tstruct _lejp_parsing_stack *p;\n\n\tif (ctx-\u003epst_sp + 1 \u003d\u003d LEJP_MAX_PARSING_STACK_DEPTH)\n\t\treturn -1;\n\n\tlejp_check_path_match(ctx);\n\n\tctx-\u003epst[ctx-\u003epst_sp].path_match \u003d ctx-\u003epath_match;\n\tctx-\u003epst_sp++;\n\n\tp \u003d \u0026ctx-\u003epst[ctx-\u003epst_sp];\n\tp-\u003euser \u003d user;\n\tp-\u003ecallback \u003d lejp_cb;\n\tp-\u003epaths \u003d paths;\n\tp-\u003ecount_paths \u003d paths_count;\n\tp-\u003eppos \u003d 0;\n\n\tctx-\u003epath_match \u003d 0;\n\tlejp_check_path_match(ctx);\n\n\tlwsl_debug(\u0022%s: pushed parser stack to %d (path %s)\u005cn\u0022, __func__,\n\t\t ctx-\u003epst_sp, ctx-\u003epath);\n\n\treturn 0;\n}\n\nint\nlejp_parser_pop(struct lejp_ctx *ctx)\n{\n\tif (!ctx-\u003epst_sp)\n\t\treturn -1;\n\n\tctx-\u003epst_sp--;\n\tlwsl_debug(\u0022%s: popped parser stack to %d\u005cn\u0022, __func__, ctx-\u003epst_sp);\n\n\tctx-\u003epath_match \u003d 0; /* force it to check */\n\tlejp_check_path_match(ctx);\n\n\treturn 0;\n}\n\nconst char *\nlejp_error_to_string(int e)\n{\n\tif (e \u003e 0)\n\t\te \u003d 0;\n\telse\n\t\te \u003d -e;\n\n\tif (e \u003e\u003d (int)LWS_ARRAY_SIZE(parser_errs))\n\t\treturn \u0022Unknown error\u0022;\n\n\treturn parser_errs[e];\n}\n","s":{"c":1618121308,"u": 953}} ],"g": 7402,"chitpc": 0,"ehitpc": 0,"indexed":0 , "ab": 1, "si": 0, "db":0, "di":0, "sat":0, "lfc": "0000"}