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":1660499782, "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":"fc9261268a63b1a42e4ff2ae3c4c8bf6", "oid":{ "oid": "e3ed2ba6901c385b44acace6a4e91fac2b165f40", "alias": [ "refs/heads/main"]},"blobname": "lib/misc/lws-struct-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 \u003clibwebsockets.h\u003e\n#include \u003cprivate-lib-core.h\u003e\n\n#include \u003cassert.h\u003e\n\nsigned char\nlws_struct_schema_only_lejp_cb(struct lejp_ctx *ctx, char reason)\n{\n\tlws_struct_args_t *a \u003d (lws_struct_args_t *)ctx-\u003euser;\n\tconst lws_struct_map_t *map \u003d a-\u003emap_st[ctx-\u003epst_sp];\n\tsize_t n \u003d a-\u003emap_entries_st[ctx-\u003epst_sp], imp \u003d 0;\n\tlejp_callback cb \u003d map-\u003elejp_cb;\n\n\tif (reason \u003d\u003d LEJPCB_PAIR_NAME \u0026\u0026 strcmp(ctx-\u003epath, \u0022schema\u0022)) {\n\t\t/*\n\t\t * If not \u0022schema\u0022, the schema is implicit rather than\n\t\t * explicitly given, ie, he just goes ahead and starts using\n\t\t * member names that imply a particular type. For example, he\n\t\t * may have an implicit type normally, and a different one for\n\t\t * exceptions that just starts using \u0022error-message\u0022 or whatever\n\t\t * and we can understand that's the exception type now.\n\t\t *\n\t\t * Let's look into each of the maps in the top level array\n\t\t * and match the first one that mentions the name he gave here,\n\t\t * and bind to the associated type / create a toplevel object\n\t\t * of that type.\n\t\t */\n\n\t\twhile (n--) {\n\t\t\tint m, child_members \u003d (int)map-\u003echild_map_size;\n\n\t\t\tfor (m \u003d 0; m \u003c child_members; m++) {\n\t\t\t\tconst lws_struct_map_t *child \u003d \u0026map-\u003echild_map[m];\n\t\t\t\tif (!strcmp(ctx-\u003epath, child-\u003ecolname)) {\n\t\t\t\t\t/*\n\t\t\t\t\t * We matched on him... map is pointing\n\t\t\t\t\t * to the right toplevel type, let's\n\t\t\t\t\t * just pick up from there as if we\n\t\t\t\t\t * matched the explicit schema name...\n\t\t\t\t\t */\n\t\t\t\t\tctx-\u003epath_match \u003d 1;\n\t\t\t\t\timp \u003d 1;\n\t\t\t\t\tgoto matched;\n\t\t\t\t}\n\t\t\t}\n\t\t\tmap++;\n\t\t}\n\t\tlwsl_notice(\u0022%s: can't match implicit schema %s\u005cn\u0022,\n\t\t\t __func__, ctx-\u003epath);\n\n\t\treturn -1;\n\t}\n\n\tif (reason !\u003d LEJPCB_VAL_STR_END || ctx-\u003epath_match !\u003d 1)\n\t\treturn 0;\n\n\t/* If \u0022schema\u0022, then look for a matching name in the map array */\n\n\twhile (n--) {\n\t\tif (strcmp(ctx-\u003ebuf, map-\u003ecolname)) {\n\t\t\tmap++;\n\t\t\tcontinue;\n\t\t}\n\nmatched:\n\n\t\ta-\u003edest \u003d lwsac_use_zero(\u0026a-\u003eac, map-\u003eaux, a-\u003eac_block_size);\n\t\tif (!a-\u003edest) {\n\t\t\tlwsl_err(\u0022%s: OOT\u005cn\u0022, __func__);\n\n\t\t\treturn 1;\n\t\t}\n\t\ta-\u003edest_len \u003d map-\u003eaux;\n\t\tif (!ctx-\u003epst_sp)\n\t\t\ta-\u003etop_schema_index \u003d (int)(map - a-\u003emap_st[ctx-\u003epst_sp]);\n\n\t\tif (!cb)\n\t\t\tcb \u003d lws_struct_default_lejp_cb;\n\n\t\tlejp_parser_push(ctx, a-\u003edest, \u0026map-\u003echild_map[0].colname,\n\t\t\t\t (uint8_t)map-\u003echild_map_size, cb);\n\t\ta-\u003emap_st[ctx-\u003epst_sp] \u003d map-\u003echild_map;\n\t\ta-\u003emap_entries_st[ctx-\u003epst_sp] \u003d map-\u003echild_map_size;\n\n\t\t// lwsl_notice(\u0022%s: child map ofs_clist %d\u005cn\u0022, __func__,\n\t\t// \t\t(int)a-\u003emap_st[ctx-\u003epst_sp]-\u003eofs_clist);\n\n\t\tif (imp)\n\t\t\treturn cb(ctx, reason);\n\n\t\treturn 0;\n\t}\n\n\tlwsl_notice(\u0022%s: unknown schema %s\u005cn\u0022, __func__, ctx-\u003ebuf);\n\n\treturn 1;\n}\n\nstatic int\nlws_struct_lejp_push(struct lejp_ctx *ctx, lws_struct_args_t *args,\n\t\t const lws_struct_map_t *map, uint8_t *ch)\n{\n\tlejp_callback cb \u003d map-\u003elejp_cb;\n\n\tif (!cb)\n\t\tcb \u003d lws_struct_default_lejp_cb;\n\n\tlejp_parser_push(ctx, ch, (const char * const*)map-\u003echild_map,\n\t\t\t (uint8_t)map-\u003echild_map_size, cb);\n\n\targs-\u003emap_st[ctx-\u003epst_sp] \u003d map-\u003echild_map;\n\targs-\u003emap_entries_st[ctx-\u003epst_sp] \u003d map-\u003echild_map_size;\n\n\treturn 0;\n}\n\nsigned char\nlws_struct_default_lejp_cb(struct lejp_ctx *ctx, char reason)\n{\n\tlws_struct_args_t *args \u003d (lws_struct_args_t *)ctx-\u003euser;\n\tconst lws_struct_map_t *map, *pmap \u003d NULL;\n\tuint8_t *ch;\n\tsize_t n;\n\tchar *u;\n\n\tif (reason \u003d\u003d LEJPCB_ARRAY_END) {\n\t\tlejp_parser_pop(ctx);\n\n\t\treturn 0;\n\t}\n\n\tif (reason \u003d\u003d LEJPCB_ARRAY_START) {\n\t\tif (!ctx-\u003epath_match)\n\t\t\tlwsl_err(\u0022%s: ARRAY_START with ctx-\u003epath_match 0\u005cn\u0022, __func__);\n\t\tmap \u003d \u0026args-\u003emap_st[ctx-\u003epst_sp][ctx-\u003epath_match - 1];\n\n\t\tif (map-\u003etype \u003d\u003d LSMT_LIST)\n\t\t\tlws_struct_lejp_push(ctx, args, map, NULL);\n\n\t\treturn 0;\n\t}\n\n\tif (ctx-\u003epst_sp)\n\t\tpmap \u003d \u0026args-\u003emap_st[ctx-\u003epst_sp - 1]\n\t [ctx-\u003epst[ctx-\u003epst_sp - 1].path_match - 1];\n\n\tif (reason \u003d\u003d LEJPCB_OBJECT_START) {\n\n\t\tif (!ctx-\u003epath_match) {\n\t\t\tctx-\u003epst[ctx-\u003epst_sp].user \u003d NULL;\n\n\t\t\treturn 0;\n\t\t}\n\n\t\tmap \u003d \u0026args-\u003emap_st[ctx-\u003epst_sp][ctx-\u003epath_match - 1];\n\t\tn \u003d args-\u003emap_entries_st[ctx-\u003epst_sp];\n\n\t\tif (map-\u003etype !\u003d LSMT_CHILD_PTR \u0026\u0026 map-\u003etype !\u003d LSMT_LIST) {\n\t\t\tctx-\u003epst[ctx-\u003epst_sp].user \u003d NULL;\n\n\t\t\treturn 0;\n\t\t}\n\t\tpmap \u003d map;\n\n\t\tlws_struct_lejp_push(ctx, args, map, NULL);\n\t}\n\n\tif (reason \u003d\u003d LEJPCB_OBJECT_END \u0026\u0026 pmap) {\n\t\tif (pmap-\u003etype \u003d\u003d LSMT_CHILD_PTR)\n\t\t\tlejp_parser_pop(ctx);\n\n\t\tif (ctx-\u003epst_sp)\n\t\t\tpmap \u003d \u0026args-\u003emap_st[ctx-\u003epst_sp - 1]\n\t\t [ctx-\u003epst[ctx-\u003epst_sp - 1].path_match - 1];\n\t}\n\n\tif (!ctx-\u003epath_match)\n\t\treturn 0;\n\n\tmap \u003d \u0026args-\u003emap_st[ctx-\u003epst_sp][ctx-\u003epath_match - 1];\n\tn \u003d args-\u003emap_entries_st[ctx-\u003epst_sp];\n\n\tif (map-\u003etype \u003d\u003d LSMT_SCHEMA) {\n\n\t\twhile (n--) {\n\t\t\tif (strncmp(map-\u003ecolname, ctx-\u003ebuf, ctx-\u003enpos)) {\n\t\t\t\tmap++;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* instantiate the correct toplevel object */\n\n\t\t\tch \u003d lwsac_use_zero(\u0026args-\u003eac, map-\u003eaux,\n\t\t\t\t\t args-\u003eac_block_size);\n\t\t\tif (!ch) {\n\t\t\t\tlwsl_err(\u0022OOM\u005cn\u0022);\n\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\tlws_struct_lejp_push(ctx, args, map, ch);\n\n\t\t\treturn 0;\n\t\t}\n\t\tlwsl_notice(\u0022%s: unknown schema %.*s, tried %d\u005cn\u0022, __func__,\n\t\t\t\tctx-\u003enpos, ctx-\u003ebuf,\n\t\t\t\t(int)args-\u003emap_entries_st[ctx-\u003epst_sp]);\n\n\t\tgoto cleanup;\n\t}\n\n\tif (!ctx-\u003epst[ctx-\u003epst_sp].user) {\n\t\tstruct lws_dll2_owner *owner;\n\t\tstruct lws_dll2 *list;\n\n\t\t/* create list item object if none already */\n\n\t\tif (!ctx-\u003epath_match || !pmap)\n\t\t\treturn 0;\n\n\t\tmap \u003d \u0026args-\u003emap_st[ctx-\u003epst_sp - 1][ctx-\u003epath_match - 1];\n\t\tn \u003d args-\u003emap_entries_st[ctx-\u003epst_sp - 1];\n\n\t\tif (!ctx-\u003epst_sp)\n\t\t\treturn 0;\n\n\t\tif (pmap-\u003etype !\u003d LSMT_LIST \u0026\u0026 pmap-\u003etype !\u003d LSMT_CHILD_PTR)\n\t\t\treturn 1;\n\n\t\t/* we need to create a child or array item object */\n\n\t\towner \u003d (struct lws_dll2_owner *)\n\t\t\t(((char *)ctx-\u003epst[ctx-\u003epst_sp - 1].user) + pmap-\u003eofs);\n\n\t\tassert(pmap-\u003eaux);\n\n\t\t/* instantiate one of the child objects */\n\n\t\tctx-\u003epst[ctx-\u003epst_sp].user \u003d lwsac_use_zero(\u0026args-\u003eac,\n\t\t\t\t\t\tpmap-\u003eaux, args-\u003eac_block_size);\n\t\tif (!ctx-\u003epst[ctx-\u003epst_sp].user) {\n\t\t\tlwsl_err(\u0022OOM\u005cn\u0022);\n\n\t\t\treturn 1;\n\t\t}\n\t\tlwsl_info(\u0022%s: created '%s' object size %d\u005cn\u0022, __func__,\n\t\t\t\tpmap-\u003ecolname, (int)pmap-\u003eaux);\n\n\t\tswitch (pmap-\u003etype) {\n\t\tcase LSMT_LIST:\n\t\t\tlist \u003d (struct lws_dll2 *)\n\t\t\t\t ((char *)ctx-\u003epst[ctx-\u003epst_sp].user +\n\t\t\t\t pmap-\u003eofs_clist);\n\n\t\t\tlws_dll2_add_tail(list, owner);\n\t\t\tbreak;\n\t\tcase LSMT_CHILD_PTR:\n\t\t\t*((void **)owner) \u003d ctx-\u003epst[ctx-\u003epst_sp].user;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tassert(0);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!ctx-\u003epath_match)\n\t\treturn 0;\n\n\tif (reason \u003d\u003d LEJPCB_VAL_STR_CHUNK) {\n\t\tlejp_collation_t *coll;\n\n\t\t/* don't cache stuff we are going to ignore */\n\n\t\tif (map-\u003etype \u003d\u003d LSMT_STRING_CHAR_ARRAY \u0026\u0026\n\t\t args-\u003echunks_length \u003e\u003d map-\u003eaux)\n\t\t\treturn 0;\n\n\t\tcoll \u003d lwsac_use_zero(\u0026args-\u003eac_chunks, sizeof(*coll),\n\t\t\t\t sizeof(*coll));\n\t\tif (!coll) {\n\t\t\tlwsl_err(\u0022%s: OOT\u005cn\u0022, __func__);\n\n\t\t\treturn 1;\n\t\t}\n\t\tcoll-\u003echunks.prev \u003d NULL;\n\t\tcoll-\u003echunks.next \u003d NULL;\n\t\tcoll-\u003echunks.owner \u003d NULL;\n\n\t\tcoll-\u003elen \u003d ctx-\u003enpos;\n\t\tlws_dll2_add_tail(\u0026coll-\u003echunks, \u0026args-\u003echunks_owner);\n\n\t\tmemcpy(coll-\u003ebuf, ctx-\u003ebuf, ctx-\u003enpos);\n\n\t\targs-\u003echunks_length +\u003d ctx-\u003enpos;\n\n\t\treturn 0;\n\t}\n\n\tif (reason !\u003d LEJPCB_VAL_STR_END \u0026\u0026 reason !\u003d LEJPCB_VAL_NUM_INT \u0026\u0026\n\t reason !\u003d LEJPCB_VAL_TRUE \u0026\u0026 reason !\u003d LEJPCB_VAL_FALSE)\n\t\treturn 0;\n\n\t/* this is the end of the string */\n\n\tif (ctx-\u003epst[ctx-\u003epst_sp].user \u0026\u0026 pmap \u0026\u0026 pmap-\u003etype \u003d\u003d LSMT_CHILD_PTR) {\n\t\tvoid **pp \u003d (void **)\n\t\t\t(((char *)ctx-\u003epst[ctx-\u003epst_sp - 1].user) + pmap-\u003eofs);\n\n\t\t*pp \u003d ctx-\u003epst[ctx-\u003epst_sp].user;\n\t}\n\n\tu \u003d (char *)ctx-\u003epst[ctx-\u003epst_sp].user;\n\tif (!u)\n\t\tu \u003d (char *)ctx-\u003epst[ctx-\u003epst_sp - 1].user;\n\n\t{\n\t\tchar **pp, *s;\n\t\tsize_t lim, b;\n\t\tlong long li;\n\n\t\tswitch (map-\u003etype) {\n\t\tcase LSMT_SIGNED:\n\t\t\tif (map-\u003eaux \u003d\u003d sizeof(signed char)) {\n\t\t\t\tsigned char *pc;\n\t\t\t\tpc \u003d (signed char *)(u + map-\u003eofs);\n\t\t\t\t*pc \u003d (signed char)atoi(ctx-\u003ebuf);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (map-\u003eaux \u003d\u003d sizeof(int)) {\n\t\t\t\tint *pi;\n\t\t\t\tpi \u003d (int *)(u + map-\u003eofs);\n\t\t\t\t*pi \u003d atoi(ctx-\u003ebuf);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (map-\u003eaux \u003d\u003d sizeof(long)) {\n\t\t\t\tlong *pl;\n\t\t\t\tpl \u003d (long *)(u + map-\u003eofs);\n\t\t\t\t*pl \u003d atol(ctx-\u003ebuf);\n\t\t\t} else {\n\t\t\t\tlong long *pll;\n\t\t\t\tpll \u003d (long long *)(u + map-\u003eofs);\n\t\t\t\t*pll \u003d atoll(ctx-\u003ebuf);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase LSMT_UNSIGNED:\n\t\t\tif (map-\u003eaux \u003d\u003d sizeof(unsigned char)) {\n\t\t\t\tunsigned char *pc;\n\t\t\t\tpc \u003d (unsigned char *)(u + map-\u003eofs);\n\t\t\t\t*pc \u003d (unsigned char)(unsigned int)atoi(ctx-\u003ebuf);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (map-\u003eaux \u003d\u003d sizeof(unsigned int)) {\n\t\t\t\tunsigned int *pi;\n\t\t\t\tpi \u003d (unsigned int *)(u + map-\u003eofs);\n\t\t\t\t*pi \u003d (unsigned int)atoi(ctx-\u003ebuf);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (map-\u003eaux \u003d\u003d sizeof(unsigned long)) {\n\t\t\t\tunsigned long *pl;\n\t\t\t\tpl \u003d (unsigned long *)(u + map-\u003eofs);\n\t\t\t\t*pl \u003d (unsigned long)atol(ctx-\u003ebuf);\n\t\t\t} else {\n\t\t\t\tunsigned long long *pll;\n\t\t\t\tpll \u003d (unsigned long long *)(u + map-\u003eofs);\n\t\t\t\t*pll \u003d (unsigned long long)atoll(ctx-\u003ebuf);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase LSMT_BOOLEAN:\n\t\t\tli \u003d reason \u003d\u003d LEJPCB_VAL_TRUE;\n\t\t\tif (map-\u003eaux \u003d\u003d sizeof(char)) {\n\t\t\t\tchar *pc;\n\t\t\t\tpc \u003d (char *)(u + map-\u003eofs);\n\t\t\t\t*pc \u003d (char)li;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (map-\u003eaux \u003d\u003d sizeof(int)) {\n\t\t\t\tint *pi;\n\t\t\t\tpi \u003d (int *)(u + map-\u003eofs);\n\t\t\t\t*pi \u003d (int)li;\n\t\t\t} else {\n\t\t\t\tuint64_t *p64;\n\t\t\t\tp64 \u003d (uint64_t *)(u + map-\u003eofs);\n\t\t\t\t*p64 \u003d (uint64_t)li;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase LSMT_STRING_CHAR_ARRAY:\n\t\t\ts \u003d (char *)(u + map-\u003eofs);\n\t\t\tlim \u003d map-\u003eaux - 1;\n\t\t\tgoto chunk_copy;\n\n\t\tcase LSMT_STRING_PTR:\n\t\t\tpp \u003d (char **)(u + map-\u003eofs);\n\t\t\tlim \u003d args-\u003echunks_length + ctx-\u003enpos;\n\t\t\ts \u003d lwsac_use(\u0026args-\u003eac, lim + 1, args-\u003eac_block_size);\n\t\t\tif (!s)\n\t\t\t\tgoto cleanup;\n\t\t\t*pp \u003d s;\n\nchunk_copy:\n\t\t\ts[lim] \u003d '\u005c0';\n\t\t\t/* copy up to lim from the string chunk ac first */\n\t\t\tlws_start_foreach_dll_safe(struct lws_dll2 *, p, p1,\n\t\t\t\t\t\targs-\u003echunks_owner.head) {\n\t\t\t\tlejp_collation_t *coll \u003d (lejp_collation_t *)p;\n\n\t\t\t\tif (lim) {\n\t\t\t\t\tb \u003d (unsigned int)coll-\u003elen;\n\t\t\t\t\tif (b \u003e lim)\n\t\t\t\t\t\tb \u003d lim;\n\t\t\t\t\tmemcpy(s, coll-\u003ebuf, b);\n\t\t\t\t\ts +\u003d b;\n\t\t\t\t\tlim -\u003d b;\n\t\t\t\t}\n\t\t\t} lws_end_foreach_dll_safe(p, p1);\n\n\t\t\tlwsac_free(\u0026args-\u003eac_chunks);\n\t\t\targs-\u003echunks_owner.count \u003d 0;\n\t\t\targs-\u003echunks_owner.head \u003d NULL;\n\t\t\targs-\u003echunks_owner.tail \u003d NULL;\n\n\t\t\tif (lim) {\n\t\t\t\tb \u003d ctx-\u003enpos;\n\t\t\t\tif (b \u003e lim)\n\t\t\t\t\tb \u003d lim;\n\t\t\t\tmemcpy(s, ctx-\u003ebuf, b);\n\t\t\t\ts[b] \u003d '\u005c0';\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (args-\u003ecb)\n\t\targs-\u003ecb(args-\u003edest, args-\u003ecb_arg);\n\n\treturn 0;\n\ncleanup:\n\tlwsl_notice(\u0022%s: cleanup\u005cn\u0022, __func__);\n\tlwsac_free(\u0026args-\u003eac_chunks);\n\targs-\u003echunks_owner.count \u003d 0;\n\targs-\u003echunks_owner.head \u003d NULL;\n\targs-\u003echunks_owner.tail \u003d NULL;\n\n\treturn 1;\n}\n\nstatic const char * schema[] \u003d { \u0022schema\u0022 };\n\nint\nlws_struct_json_init_parse(struct lejp_ctx *ctx, lejp_callback cb, void *user)\n{\n\t/*\n\t * By default we are looking to match on a toplevel member called\n\t * \u0022schema\u0022, against an LSM_SCHEMA\n\t */\n\tif (!cb)\n\t\tcb \u003d lws_struct_schema_only_lejp_cb;\n\tlejp_construct(ctx, cb, user, schema, 1);\n\n\tctx-\u003epath_stride \u003d sizeof(lws_struct_map_t);\n\n\treturn 0;\n}\n\nlws_struct_serialize_t *\nlws_struct_json_serialize_create(const lws_struct_map_t *map,\n\t\t\t\t size_t map_entries, int flags,\n\t\t\t\t const void *ptoplevel)\n{\n\tlws_struct_serialize_t *js \u003d lws_zalloc(sizeof(*js), __func__);\n\tlws_struct_serialize_st_t *j;\n\n\tif (!js)\n\t\treturn NULL;\n\n\tjs-\u003eflags \u003d flags;\n\n\tj \u003d \u0026js-\u003est[0];\n\tj-\u003emap \u003d map;\n\tj-\u003emap_entries \u003d map_entries;\n\tj-\u003eobj \u003d ptoplevel;\n\tj-\u003eidt \u003d 0;\n\n\treturn js;\n}\n\nvoid\nlws_struct_json_serialize_destroy(lws_struct_serialize_t **pjs)\n{\n\tif (!*pjs)\n\t\treturn;\n\n\tlws_free(*pjs);\n\n\t*pjs \u003d NULL;\n}\n\nstatic void\nlws_struct_pretty(lws_struct_serialize_t *js, uint8_t **pbuf, size_t *plen)\n{\n\tif (js-\u003eflags \u0026 LSSERJ_FLAG_PRETTY) {\n\t\tint n;\n\n\t\t*(*pbuf)++ \u003d '\u005cn';\n\t\t(*plen)--;\n\t\tfor (n \u003d 0; n \u003c js-\u003est[js-\u003esp].idt; n++) {\n\t\t\t*(*pbuf)++ \u003d ' ';\n\t\t\t(*plen)--;\n\t\t}\n\t}\n}\n\nlws_struct_json_serialize_result_t\nlws_struct_json_serialize(lws_struct_serialize_t *js, uint8_t *buf,\n\t\t\t size_t len, size_t *written)\n{\n\tlws_struct_serialize_st_t *j;\n\tconst lws_struct_map_t *map;\n\tsize_t budget \u003d 0, olen \u003d len, m;\n\tstruct lws_dll2_owner *o;\n\tunsigned long long uli;\n\tconst char *q;\n\tconst void *p;\n\tchar dbuf[72];\n\tlong long li;\n\tint n, used;\n\n\t*written \u003d 0;\n\t*buf \u003d '\u005c0';\n\n\twhile (len \u003e sizeof(dbuf) + 20) {\n\t\tj \u003d \u0026js-\u003est[js-\u003esp];\n\t\tmap \u003d \u0026j-\u003emap[j-\u003emap_entry];\n\t\tq \u003d j-\u003eobj + map-\u003eofs;\n\n\t\t/* early check if the entry should be elided */\n\n\t\tswitch (map-\u003etype) {\n\t\tcase LSMT_STRING_CHAR_ARRAY:\n\t\t\tif (!q)\n\t\t\t\tgoto up;\n\t\t\tbreak;\n\t\tcase LSMT_STRING_PTR:\n\t\tcase LSMT_CHILD_PTR:\n\t\t\tq \u003d (char *)*(char **)q;\n\t\t\tif (!q)\n\t\t\t\tgoto up;\n\t\t\tbreak;\n\n\t\tcase LSMT_LIST:\n\t\t\to \u003d (struct lws_dll2_owner *)q;\n\t\t\tp \u003d j-\u003edllpos \u003d lws_dll2_get_head(o);\n\t\t\tif (!p)\n\t\t\t\tgoto up;\n\t\t\tbreak;\n\n\t\tcase LSMT_BLOB_PTR:\n\t\t\tgoto up;\n\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\n\t\tif (j-\u003esubsequent) {\n\t\t\t*buf++ \u003d ',';\n\t\t\tlen--;\n\t\t\tlws_struct_pretty(js, \u0026buf, \u0026len);\n\t\t}\n\t\tj-\u003esubsequent \u003d 1;\n\n\t\tif (map-\u003etype !\u003d LSMT_SCHEMA \u0026\u0026 !js-\u003eoffset) {\n\t\t\tn \u003d lws_snprintf((char *)buf, len, \u0022\u005c\u0022%s\u005c\u0022:\u0022,\n\t\t\t\t\t map-\u003ecolname);\n\t\t\tbuf +\u003d n;\n\t\t\tlen \u003d len - (unsigned int)n;\n\t\t\tif (js-\u003eflags \u0026 LSSERJ_FLAG_PRETTY) {\n\t\t\t\t*buf++ \u003d ' ';\n\t\t\t\tlen--;\n\t\t\t}\n\t\t}\n\n\t\tswitch (map-\u003etype) {\n\t\tcase LSMT_BOOLEAN:\n\t\tcase LSMT_UNSIGNED:\n\t\t\tif (map-\u003eaux \u003d\u003d sizeof(char)) {\n\t\t\t\tuli \u003d *(unsigned char *)q;\n\t\t\t} else {\n\t\t\t\tif (map-\u003eaux \u003d\u003d sizeof(int)) {\n\t\t\t\t\tuli \u003d *(unsigned int *)q;\n\t\t\t\t} else {\n\t\t\t\t\tif (map-\u003eaux \u003d\u003d sizeof(long))\n\t\t\t\t\t\tuli \u003d *(unsigned long *)q;\n\t\t\t\t\telse\n\t\t\t\t\t\tuli \u003d *(unsigned long long *)q;\n\t\t\t\t}\n\t\t\t}\n\t\t\tq \u003d dbuf;\n\n\t\t\tif (map-\u003etype \u003d\u003d LSMT_BOOLEAN) {\n\t\t\t\tbudget \u003d (unsigned int)lws_snprintf(dbuf, sizeof(dbuf),\n\t\t\t\t\t\t\u0022%s\u0022, uli ? \u0022true\u0022 : \u0022false\u0022);\n\t\t\t} else\n\t\t\t\tbudget \u003d (unsigned int)lws_snprintf(dbuf, sizeof(dbuf),\n\t\t\t\t\t\t \u0022%llu\u0022, uli);\n\t\t\tbreak;\n\n\t\tcase LSMT_SIGNED:\n\t\t\tif (map-\u003eaux \u003d\u003d sizeof(signed char)) {\n\t\t\t\tli \u003d (long long)*(signed char *)q;\n\t\t\t} else {\n\t\t\t\tif (map-\u003eaux \u003d\u003d sizeof(int)) {\n\t\t\t\t\tli \u003d (long long)*(int *)q;\n\t\t\t\t} else {\n\t\t\t\t\tif (map-\u003eaux \u003d\u003d sizeof(long))\n\t\t\t\t\t\tli \u003d (long long)*(long *)q;\n\t\t\t\t\telse\n\t\t\t\t\t\tli \u003d *(long long *)q;\n\t\t\t\t}\n\t\t\t}\n\t\t\tq \u003d dbuf;\n\t\t\tbudget \u003d (unsigned int)lws_snprintf(dbuf, sizeof(dbuf), \u0022%lld\u0022, li);\n\t\t\tbreak;\n\n\t\tcase LSMT_STRING_CHAR_ARRAY:\n\t\tcase LSMT_STRING_PTR:\n\t\t\tif (!js-\u003eoffset) {\n\t\t\t\t*buf++ \u003d '\u005c\u0022';\n\t\t\t\tlen--;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase LSMT_LIST:\n\t\t\t*buf++ \u003d '[';\n\t\t\tlen--;\n\t\t\tif (js-\u003esp + 1 \u003d\u003d LEJP_MAX_PARSING_STACK_DEPTH)\n\t\t\t\treturn LSJS_RESULT_ERROR;\n\n\t\t\t/* add a stack level to handle parsing array members */\n\n\t\t\to \u003d (struct lws_dll2_owner *)q;\n\t\t\tp \u003d j-\u003edllpos \u003d lws_dll2_get_head(o);\n\n\t\t\tif (!j-\u003edllpos) {\n\t\t\t\t*buf++ \u003d ']';\n\t\t\t\tlen--;\n\t\t\t\tgoto up;\n\t\t\t}\n\n\t\t\tn \u003d j-\u003eidt;\n\t\t\tj \u003d \u0026js-\u003est[++js-\u003esp];\n\t\t\tj-\u003eidt \u003d (char)(n + 2);\n\t\t\tj-\u003emap \u003d map-\u003echild_map;\n\t\t\tj-\u003emap_entries \u003d map-\u003echild_map_size;\n\t\t\tj-\u003esize \u003d map-\u003eaux;\n\t\t\tj-\u003esubsequent \u003d 0;\n\t\t\tj-\u003emap_entry \u003d 0;\n\t\t\tlws_struct_pretty(js, \u0026buf, \u0026len);\n\t\t\t*buf++ \u003d '{';\n\t\t\tlen--;\n\t\t\tlws_struct_pretty(js, \u0026buf, \u0026len);\n\t\t\tif (p)\n\t\t\t\tj-\u003eobj \u003d ((char *)p) - j-\u003emap-\u003eofs_clist;\n\t\t\telse\n\t\t\t\tj-\u003eobj \u003d NULL;\n\t\t\tcontinue;\n\n\t\tcase LSMT_CHILD_PTR:\n\n\t\t\tif (js-\u003esp + 1 \u003d\u003d LEJP_MAX_PARSING_STACK_DEPTH)\n\t\t\t\treturn LSJS_RESULT_ERROR;\n\n\t\t\t/* add a stack level to handle parsing child members */\n\n\t\t\tn \u003d j-\u003eidt;\n\t\t\tj \u003d \u0026js-\u003est[++js-\u003esp];\n\t\t\tj-\u003eidt \u003d (char)(n + 2);\n\t\t\tj-\u003emap \u003d map-\u003echild_map;\n\t\t\tj-\u003emap_entries \u003d map-\u003echild_map_size;\n\t\t\tj-\u003esize \u003d map-\u003eaux;\n\t\t\tj-\u003esubsequent \u003d 0;\n\t\t\tj-\u003emap_entry \u003d 0;\n\t\t\t*buf++ \u003d '{';\n\t\t\tlen--;\n\t\t\tlws_struct_pretty(js, \u0026buf, \u0026len);\n\t\t\tj-\u003eobj \u003d q;\n\n\t\t\tcontinue;\n\n\t\tcase LSMT_SCHEMA:\n\t\t\tq \u003d dbuf;\n\t\t\t*buf++ \u003d '{';\n\t\t\tlen--;\n\t\t\tj \u003d \u0026js-\u003est[++js-\u003esp];\n\t\t\tlws_struct_pretty(js, \u0026buf, \u0026len);\n\t\t\tif (!(js-\u003eflags \u0026 LSSERJ_FLAG_OMIT_SCHEMA)) {\n\t\t\t\tbudget \u003d (unsigned int)lws_snprintf(dbuf, 15, \u0022\u005c\u0022schema\u005c\u0022:\u0022);\n\t\t\t\tif (js-\u003eflags \u0026 LSSERJ_FLAG_PRETTY)\n\t\t\t\t\tdbuf[budget++] \u003d ' ';\n\n\t\t\t\tbudget +\u003d (unsigned int)lws_snprintf(dbuf + budget,\n\t\t\t\t\t\t sizeof(dbuf) - budget,\n\t\t\t\t\t\t \u0022\u005c\u0022%s\u005c\u0022\u0022, map-\u003ecolname);\n\t\t\t}\n\n\n\t\t\tif (js-\u003esp !\u003d 1)\n\t\t\t\treturn LSJS_RESULT_ERROR;\n\t\t\tj-\u003emap \u003d map-\u003echild_map;\n\t\t\tj-\u003emap_entries \u003d map-\u003echild_map_size;\n\t\t\tj-\u003esize \u003d map-\u003eaux;\n\t\t\tj-\u003esubsequent \u003d 0;\n\t\t\tj-\u003emap_entry \u003d 0;\n\t\t\tj-\u003eobj \u003d js-\u003est[js-\u003esp - 1].obj;\n\t\t\tj-\u003edllpos \u003d NULL;\n\t\t\tif (!(js-\u003eflags \u0026 LSSERJ_FLAG_OMIT_SCHEMA))\n\t\t\t\t/* we're actually at the same level */\n\t\t\t\tj-\u003esubsequent \u003d 1;\n\t\t\tj-\u003eidt \u003d 1;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\n\t\tswitch (map-\u003etype) {\n\t\tcase LSMT_STRING_CHAR_ARRAY:\n\t\tcase LSMT_STRING_PTR:\n\t\t\t/*\n\t\t\t * This is a bit tricky... we have to escape the string\n\t\t\t * which may 6x its length depending on what the\n\t\t\t * contents are.\n\t\t\t *\n\t\t\t * We offset the unescaped string starting point first\n\t\t\t */\n\n\t\t\tq +\u003d js-\u003eoffset;\n\t\t\tbudget \u003d strlen(q); /* how much unescaped is left */\n\n\t\t\t/*\n\t\t\t * This is going to escape as much as it can fit, and\n\t\t\t * let us know the amount of input that was consumed\n\t\t\t * in \u0022used\u0022.\n\t\t\t */\n\n\t\t\tlws_json_purify((char *)buf, q, (int)len, \u0026used);\n\t\t\tm \u003d strlen((const char *)buf);\n\t\t\tbuf +\u003d m;\n\t\t\tlen -\u003d m;\n\t\t\tjs-\u003eremaining \u003d budget - (unsigned int)used;\n\t\t\tjs-\u003eoffset \u003d (unsigned int)used;\n\t\t\tif (!js-\u003eremaining)\n\t\t\t\tjs-\u003eoffset \u003d 0;\n\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tq +\u003d js-\u003eoffset;\n\t\t\tbudget -\u003d js-\u003eremaining;\n\n\t\t\tif (budget \u003e len) {\n\t\t\t\tjs-\u003eremaining \u003d budget - len;\n\t\t\t\tjs-\u003eoffset \u003d len;\n\t\t\t\tbudget \u003d len;\n\t\t\t} else {\n\t\t\t\tjs-\u003eremaining \u003d 0;\n\t\t\t\tjs-\u003eoffset \u003d 0;\n\t\t\t}\n\n\t\t\tmemcpy(buf, q, budget);\n\t\t\tbuf +\u003d budget;\n\t\t\t*buf \u003d '\u005c0';\n\t\t\tlen -\u003d budget;\n\t\t\tbreak;\n\t\t}\n\n\n\n\t\tswitch (map-\u003etype) {\n\t\tcase LSMT_STRING_CHAR_ARRAY:\n\t\tcase LSMT_STRING_PTR:\n\t\t\t*buf++ \u003d '\u005c\u0022';\n\t\t\tlen--;\n\t\t\tbreak;\n\t\tcase LSMT_SCHEMA:\n\t\t\tcontinue;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\n\t\tif (js-\u003eremaining)\n\t\t\tcontinue;\nup:\n\t\tif (++j-\u003emap_entry \u003c j-\u003emap_entries)\n\t\t\tcontinue;\n\n\t\tif (!js-\u003esp)\n\t\t\tcontinue;\n\t\tjs-\u003esp--;\n\t\tif (!js-\u003esp) {\n\t\t\tlws_struct_pretty(js, \u0026buf, \u0026len);\n\t\t\t*buf++ \u003d '}';\n\t\t\tlen--;\n\t\t\tlws_struct_pretty(js, \u0026buf, \u0026len);\n\t\t\tbreak;\n\t\t}\n\t\tjs-\u003eoffset \u003d 0;\n\t\tj \u003d \u0026js-\u003est[js-\u003esp];\n\t\tmap \u003d \u0026j-\u003emap[j-\u003emap_entry];\n\n\t\tif (map-\u003etype \u003d\u003d LSMT_CHILD_PTR) {\n\t\t\tlws_struct_pretty(js, \u0026buf, \u0026len);\n\t\t\t*buf++ \u003d '}';\n\t\t\tlen--;\n\n\t\t\t/* we have done the singular child pointer */\n\n\t\t\tjs-\u003eoffset \u003d 0;\n\t\t\tgoto up;\n\t\t}\n\n\t\tif (map-\u003etype !\u003d LSMT_LIST)\n\t\t\tcontinue;\n\t\t/*\n\t\t * we are coming back up to an array map, it means we should\n\t\t * advance to the next array member if there is one\n\t\t */\n\n\t\tlws_struct_pretty(js, \u0026buf, \u0026len);\n\t\t*buf++ \u003d '}';\n\t\tlen--;\n\n\t\tp \u003d j-\u003edllpos \u003d j-\u003edllpos-\u003enext;\n\t\tif (j-\u003edllpos) {\n\t\t\t/*\n\t\t\t * there was another item in the array to do... let's\n\t\t\t * move on to that and do it\n\t\t\t */\n\t\t\t*buf++ \u003d ',';\n\t\t\tlen--;\n\t\t\tlws_struct_pretty(js, \u0026buf, \u0026len);\n\t\t\tjs-\u003eoffset \u003d 0;\n\t\t\tj \u003d \u0026js-\u003est[++js-\u003esp];\n\t\t\tj-\u003emap_entry \u003d 0;\n\t\t\tmap \u003d \u0026j-\u003emap[j-\u003emap_entry];\n\n\t\t\t*buf++ \u003d '{';\n\t\t\tlen--;\n\t\t\tlws_struct_pretty(js, \u0026buf, \u0026len);\n\n\t\t\tj-\u003esubsequent \u003d 0;\n\t\t\tj-\u003eobj \u003d ((char *)p) - j-\u003emap-\u003eofs_clist;\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* there are no further items in the array */\n\n\t\tjs-\u003eoffset \u003d 0;\n\t\tlws_struct_pretty(js, \u0026buf, \u0026len);\n\t\t*buf++ \u003d ']';\n\t\tlen--;\n\t\tgoto up;\n\t}\n\n\t*written \u003d olen - len;\n\t*buf \u003d '\u005c0'; /* convenience, a NUL after the official end */\n\n\treturn LSJS_RESULT_FINISH;\n}\n","s":{"c":1660270174,"u": 882}} ],"g": 2088,"chitpc": 0,"ehitpc": 0,"indexed":0 , "ab": 0, "si": 0, "db":0, "di":0, "sat":0, "lfc": "7d0a"}