diff --git a/docs/README.md b/docs/README.md index d8ae81ab..60f95a82 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2802,18 +2802,17 @@ which is described below. ```c enum { MG_JSON_TOO_DEEP = -1, MG_JSON_INVALID = -2, MG_JSON_NOT_FOUND = -3 }; -int mg_json_get(const char *buf, int len, const char *path, int *toklen); +int mg_json_get(struct mg_str json, const char *path, int *toklen); ``` -Parse JSON string `buf`, `len` and return the offset of the element -specified by the JSON path `path`. The length of the element is stored +Parse JSON string `json` and return the offset of the element +specified by the JSON `path`. The length of the element is stored in the `toklen`. Parameters: -- `buf` - a string containing valid JSON -- `len` - a string length -- `path` - a JSON path. Must start with `$` -- `toklen` - a placeholder for element length, can be NULL +- `json` - a string containing valid JSON +- `path` - a JSON path. Must start with `$`, e.g. `$.user` +- `toklen` - a pointer that receives element's length, can be NULL Return value: offset of the element, or negative `MG_JSON_*` on error. @@ -2823,19 +2822,20 @@ Usage example: ```c // Create a json string: { "a": 1, "b": [2, 3] } char *buf = mg_mprintf("{ %Q: %d, %Q: [%d, %d] }", "a", 1, "b", 2, 3); -int offset, length, len = (int) strlen(buf); +struct mg_str json = mg_str(buf); +int offset, length; // Lookup "$", which is the whole JSON. Can be used for validation -offset = mg_json_get(buf, len, "$", &length); // offset = 0, length = 23 +offset = mg_json_get(json, "$", &length); // offset = 0, length = 23 // Lookup attribute "a". Point to value "1" -offset = mg_json_get(buf, len, "$.a", &length); // offset = 7, length = 1 +offset = mg_json_get(json, "$.a", &length); // offset = 7, length = 1 // Lookup attribute "b". Point to array [2, 3] -offset = mg_json_get(buf, len, "$.b", &length); // offset = 15, length = 6 +offset = mg_json_get(json, "$.b", &length); // offset = 15, length = 6 // Lookup attribute "b[1]". Point to value "3" -offset = mg_json_get(buf, len, "$.b[1]", &length); // offset = 19, length = 1 +offset = mg_json_get(json, "$.b[1]", &length); // offset = 19, length = 1 free(buf); ``` diff --git a/examples/json-rpc-over-websocket/main.c b/examples/json-rpc-over-websocket/main.c index 21aeb529..567f0b12 100644 --- a/examples/json-rpc-over-websocket/main.c +++ b/examples/json-rpc-over-websocket/main.c @@ -46,8 +46,9 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { // Got websocket frame. Received data is wm->data struct mg_ws_message *wm = (struct mg_ws_message *) ev_data; char *resp = NULL; - mg_rpc_process(&s_rpc_head, wm->data, mg_pfn_realloc, &resp); - mg_ws_send(c, resp, strlen(resp), WEBSOCKET_OP_TEXT); + struct mg_rpc_req r = {&s_rpc_head, mg_pfn_realloc, &resp, 0, 0, wm->data}; + mg_rpc_process(&r); + if (resp) mg_ws_send(c, resp, strlen(resp), WEBSOCKET_OP_TEXT); free(resp); } (void) fn_data; diff --git a/examples/uart-bridge/packed_fs.c b/examples/uart-bridge/packed_fs.c index 3a17bc34..bb7e1766 100644 --- a/examples/uart-bridge/packed_fs.c +++ b/examples/uart-bridge/packed_fs.c @@ -37,6 +37,500 @@ static const unsigned char v1[] = { 10, 0 // . }; static const unsigned char v2[] = { + 39, 117, 115, 101, 32, 115, 116, 114, 105, 99, 116, 39, // 'use strict' + 59, 10, 105, 109, 112, 111, 114, 116, 32, 123, 67, 111, // ;.import {Co + 109, 112, 111, 110, 101, 110, 116, 44, 32, 104, 44, 32, // mponent, h, + 104, 116, 109, 108, 44, 32, 114, 101, 110, 100, 101, 114, // html, render + 44, 32, 117, 115, 101, 69, 102, 102, 101, 99, 116, 44, // , useEffect, + 32, 117, 115, 101, 83, 116, 97, 116, 101, 44, 32, 117, // useState, u + 115, 101, 82, 101, 102, 125, 32, 102, 114, 111, 109, 32, // seRef} from + 39, 46, 47, 112, 114, 101, 97, 99, 116, 46, 109, 105, // './preact.mi + 110, 46, 106, 115, 39, 59, 10, 10, 99, 111, 110, 115, // n.js';..cons + 116, 32, 77, 101, 115, 115, 97, 103, 101, 32, 61, 32, // t Message = + 109, 32, 61, 62, 32, 104, 116, 109, 108, 96, 60, 115, // m => html`. + 32, 36, 123, 109, 46, 109, 101, 115, 115, 97, 103, 101, // ${m.message + 46, 100, 97, 116, 97, 125, 10, 60, 47, 115, 112, 97, // .data}.`;..const + 65, 112, 112, 32, 61, 32, 102, 117, 110, 99, 116, 105, // App = functi + 111, 110, 40, 112, 114, 111, 112, 115, 41, 32, 123, 10, // on(props) {. + 32, 32, 99, 111, 110, 115, 116, 32, 91, 99, 102, 103, // const [cfg + 44, 32, 115, 101, 116, 67, 102, 103, 93, 32, 61, 32, // , setCfg] = + 117, 115, 101, 83, 116, 97, 116, 101, 40, 123, 116, 99, // useState({tc + 112, 58, 32, 123, 125, 44, 32, 119, 115, 58, 32, 123, // p: {}, ws: { + 125, 44, 32, 109, 113, 116, 116, 58, 32, 123, 125, 125, // }, mqtt: {}} + 41, 59, 10, 32, 32, 99, 111, 110, 115, 116, 32, 91, // );. const [ + 109, 101, 115, 115, 97, 103, 101, 115, 44, 32, 115, 101, // messages, se + 116, 77, 101, 115, 115, 97, 103, 101, 115, 93, 32, 61, // tMessages] = + 32, 117, 115, 101, 83, 116, 97, 116, 101, 40, 91, 93, // useState([] + 41, 59, 10, 32, 32, 99, 111, 110, 115, 116, 32, 91, // );. const [ + 99, 111, 110, 110, 101, 99, 116, 101, 100, 44, 32, 115, // connected, s + 101, 116, 67, 111, 110, 110, 101, 99, 116, 101, 100, 93, // etConnected] + 32, 61, 32, 117, 115, 101, 83, 116, 97, 116, 101, 40, // = useState( + 102, 97, 108, 115, 101, 41, 59, 10, 32, 32, 99, 111, // false);. co + 110, 115, 116, 32, 91, 116, 120, 116, 44, 32, 115, 101, // nst [txt, se + 116, 84, 120, 116, 93, 32, 61, 32, 117, 115, 101, 83, // tTxt] = useS + 116, 97, 116, 101, 40, 39, 39, 41, 59, 10, 32, 32, // tate('');. + 99, 111, 110, 115, 116, 32, 91, 119, 115, 44, 32, 115, // const [ws, s + 101, 116, 87, 115, 93, 32, 61, 32, 117, 115, 101, 83, // etWs] = useS + 116, 97, 116, 101, 40, 110, 117, 108, 108, 41, 59, 10, // tate(null);. + 10, 32, 32, 99, 111, 110, 115, 116, 32, 114, 101, 102, // . const ref + 114, 101, 115, 104, 32, 61, 32, 40, 41, 32, 61, 62, // resh = () => + 10, 32, 32, 32, 32, 32, 32, 102, 101, 116, 99, 104, // . fetch + 40, 39, 47, 97, 112, 105, 47, 99, 111, 110, 102, 105, // ('/api/confi + 103, 47, 103, 101, 116, 39, 41, 46, 116, 104, 101, 110, // g/get').then + 40, 114, 32, 61, 62, 32, 114, 46, 106, 115, 111, 110, // (r => r.json + 40, 41, 41, 46, 116, 104, 101, 110, 40, 114, 32, 61, // ()).then(r = + 62, 32, 115, 101, 116, 67, 102, 103, 40, 114, 41, 41, // > setCfg(r)) + 59, 10, 10, 32, 32, 99, 111, 110, 115, 116, 32, 103, // ;.. const g + 101, 116, 112, 111, 114, 116, 32, 61, 32, 40, 117, 114, // etport = (ur + 108, 44, 32, 118, 41, 32, 61, 62, 32, 40, 40, 117, // l, v) => ((u + 114, 108, 32, 124, 124, 32, 39, 39, 41, 46, 109, 97, // rl || '').ma + 116, 99, 104, 40, 47, 46, 42, 58, 40, 92, 100, 43, // tch(/.*:(.d+ + 41, 47, 41, 32, 124, 124, 32, 91, 39, 39, 44, 32, // )/) || ['', + 118, 93, 41, 91, 49, 93, 59, 10, 10, 32, 32, 99, // v])[1];.. c + 111, 110, 115, 116, 32, 119, 97, 116, 99, 104, 87, 101, // onst watchWe + 98, 115, 111, 99, 107, 101, 116, 32, 61, 32, 102, 117, // bsocket = fu + 110, 99, 116, 105, 111, 110, 40, 41, 32, 123, 10, 32, // nction() {. + 32, 32, 32, 47, 47, 32, 67, 111, 110, 110, 101, 99, // // Connec + 116, 32, 116, 111, 32, 119, 101, 98, 115, 111, 99, 107, // t to websock + 101, 114, 32, 112, 111, 114, 116, 44, 32, 116, 111, 32, // er port, to + 105, 109, 112, 108, 101, 109, 101, 110, 116, 32, 87, 83, // implement WS + 32, 99, 111, 110, 115, 111, 108, 101, 10, 32, 32, 32, // console. + 32, 118, 97, 114, 32, 114, 101, 99, 111, 110, 110, 101, // var reconne + 99, 116, 32, 61, 32, 102, 117, 110, 99, 116, 105, 111, // ct = functio + 110, 40, 41, 32, 123, 10, 32, 32, 32, 32, 32, 32, // n() {. + 118, 97, 114, 32, 112, 111, 114, 116, 32, 61, 32, 103, // var port = g + 101, 116, 112, 111, 114, 116, 40, 99, 102, 103, 46, 119, // etport(cfg.w + 115, 46, 117, 114, 108, 44, 32, 52, 48, 48, 50, 41, // s.url, 4002) + 59, 10, 32, 32, 32, 32, 32, 32, 118, 97, 114, 32, // ;. var + 108, 32, 61, 32, 119, 105, 110, 100, 111, 119, 46, 108, // l = window.l + 111, 99, 97, 116, 105, 111, 110, 44, 32, 112, 114, 111, // ocation, pro + 116, 111, 32, 61, 32, 108, 46, 112, 114, 111, 116, 111, // to = l.proto + 99, 111, 108, 46, 114, 101, 112, 108, 97, 99, 101, 40, // col.replace( + 39, 104, 116, 116, 112, 39, 44, 32, 39, 119, 115, 39, // 'http', 'ws' + 41, 59, 10, 32, 32, 32, 32, 32, 32, 118, 97, 114, // );. var + 32, 116, 105, 100, 44, 32, 117, 114, 108, 32, 61, 32, // tid, url = + 96, 36, 123, 112, 114, 111, 116, 111, 125, 47, 47, 36, // `${proto}//$ + 123, 108, 46, 104, 111, 115, 116, 110, 97, 109, 101, 125, // {l.hostname} + 58, 36, 123, 112, 111, 114, 116, 125, 47, 119, 115, 96, // :${port}/ws` + 59, 10, 32, 32, 32, 32, 32, 32, 47, 47, 32, 99, // ;. // c + 111, 110, 115, 111, 108, 101, 46, 108, 111, 103, 40, 117, // onsole.log(u + 114, 108, 41, 59, 10, 32, 32, 32, 32, 32, 32, 118, // rl);. v + 97, 114, 32, 119, 115, 32, 61, 32, 110, 101, 119, 32, // ar ws = new + 87, 101, 98, 83, 111, 99, 107, 101, 116, 40, 117, 114, // WebSocket(ur + 108, 41, 59, 10, 32, 32, 32, 32, 32, 32, 119, 115, // l);. ws + 46, 111, 110, 111, 112, 101, 110, 32, 61, 32, 40, 41, // .onopen = () + 32, 61, 62, 32, 123, 10, 32, 32, 32, 32, 32, 32, // => {. + 32, 32, 115, 101, 116, 67, 111, 110, 110, 101, 99, 116, // setConnect + 101, 100, 40, 116, 114, 117, 101, 41, 59, 10, 32, 32, // ed(true);. + 32, 32, 32, 32, 32, 32, 115, 101, 116, 87, 115, 40, // setWs( + 119, 115, 41, 59, 10, 32, 32, 32, 32, 32, 32, 125, // ws);. } + 59, 10, 32, 32, 32, 32, 32, 32, 119, 115, 46, 111, // ;. ws.o + 110, 109, 101, 115, 115, 97, 103, 101, 32, 61, 32, 101, // nmessage = e + 118, 32, 61, 62, 32, 123, 10, 32, 32, 32, 32, 32, // v => {. + 32, 32, 32, 47, 47, 32, 99, 111, 110, 115, 111, 108, // // consol + 101, 46, 108, 111, 103, 40, 101, 118, 44, 32, 101, 118, // e.log(ev, ev + 46, 100, 97, 116, 97, 41, 59, 10, 32, 32, 32, 32, // .data);. + 32, 32, 32, 32, 115, 101, 116, 77, 101, 115, 115, 97, // setMessa + 103, 101, 115, 40, 120, 32, 61, 62, 32, 120, 46, 99, // ges(x => x.c + 111, 110, 99, 97, 116, 40, 91, 123, 100, 97, 116, 97, // oncat([{data + 58, 32, 101, 118, 46, 100, 97, 116, 97, 44, 32, 117, // : ev.data, u + 97, 114, 116, 58, 32, 116, 114, 117, 101, 125, 93, 41, // art: true}]) + 41, 59, 10, 32, 32, 32, 32, 32, 32, 125, 59, 10, // );. };. + 32, 32, 32, 32, 32, 32, 119, 115, 46, 111, 110, 99, // ws.onc + 108, 111, 115, 101, 32, 61, 32, 102, 117, 110, 99, 116, // lose = funct + 105, 111, 110, 40, 41, 32, 123, 10, 32, 32, 32, 32, // ion() {. + 32, 32, 32, 32, 99, 108, 101, 97, 114, 84, 105, 109, // clearTim + 101, 111, 117, 116, 40, 116, 105, 100, 41, 59, 10, 32, // eout(tid);. + 32, 32, 32, 32, 32, 32, 32, 116, 105, 100, 32, 61, // tid = + 32, 115, 101, 116, 84, 105, 109, 101, 111, 117, 116, 40, // setTimeout( + 114, 101, 99, 111, 110, 110, 101, 99, 116, 44, 32, 49, // reconnect, 1 + 48, 48, 48, 41, 59, 10, 32, 32, 32, 32, 32, 32, // 000);. + 32, 32, 115, 101, 116, 67, 111, 110, 110, 101, 99, 116, // setConnect + 101, 100, 40, 102, 97, 108, 115, 101, 41, 59, 10, 32, // ed(false);. + 32, 32, 32, 32, 32, 32, 32, 115, 101, 116, 87, 115, // setWs + 40, 110, 117, 108, 108, 41, 59, 10, 32, 32, 32, 32, // (null);. + 32, 32, 125, 59, 10, 32, 32, 32, 32, 125, 59, 10, // };. };. + 32, 32, 32, 32, 114, 101, 99, 111, 110, 110, 101, 99, // reconnec + 116, 40, 41, 59, 10, 32, 32, 125, 59, 10, 10, 32, // t();. };.. + 32, 117, 115, 101, 69, 102, 102, 101, 99, 116, 40, 40, // useEffect(( + 41, 32, 61, 62, 32, 123, 10, 32, 32, 32, 32, 114, // ) => {. r + 101, 102, 114, 101, 115, 104, 40, 41, 59, 10, 32, 32, // efresh();. + 32, 32, 119, 97, 116, 99, 104, 87, 101, 98, 115, 111, // watchWebso + 99, 107, 101, 116, 40, 41, 59, 10, 32, 32, 125, 44, // cket();. }, + 32, 91, 93, 41, 59, 10, 10, 10, 32, 32, 99, 111, // []);... co + 110, 115, 116, 32, 115, 101, 110, 100, 109, 101, 115, 115, // nst sendmess + 97, 103, 101, 32, 61, 32, 101, 118, 32, 61, 62, 32, // age = ev => + 123, 10, 32, 32, 32, 32, 115, 101, 116, 77, 101, 115, // {. setMes + 115, 97, 103, 101, 115, 40, 120, 32, 61, 62, 32, 120, // sages(x => x + 46, 99, 111, 110, 99, 97, 116, 40, 91, 123, 100, 97, // .concat([{da + 116, 97, 58, 32, 116, 120, 116, 32, 43, 32, 39, 92, // ta: txt + '. + 110, 39, 44, 32, 117, 97, 114, 116, 58, 32, 102, 97, // n', uart: fa + 108, 115, 101, 125, 93, 41, 41, 59, 10, 32, 32, 32, // lse}]));. + 32, 105, 102, 32, 40, 119, 115, 41, 32, 119, 115, 46, // if (ws) ws. + 115, 101, 110, 100, 40, 116, 120, 116, 32, 43, 32, 39, // send(txt + ' + 92, 110, 39, 41, 59, 10, 32, 32, 32, 32, 115, 101, // .n');. se + 116, 84, 120, 116, 40, 39, 39, 41, 59, 10, 32, 32, // tTxt('');. + 125, 59, 10, 10, 32, 32, 99, 111, 110, 115, 116, 32, // };.. const + 111, 110, 99, 104, 97, 110, 103, 101, 32, 61, 32, 101, // onchange = e + 118, 32, 61, 62, 32, 102, 101, 116, 99, 104, 40, 39, // v => fetch(' + 47, 97, 112, 105, 47, 99, 111, 110, 102, 105, 103, 47, // /api/config/ + 115, 101, 116, 39, 44, 32, 123, 10, 32, 32, 32, 32, // set', {. + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, // + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 109, // m + 101, 116, 104, 111, 100, 58, 32, 39, 80, 79, 83, 84, // ethod: 'POST + 39, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, // ',. + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, // + 32, 32, 32, 32, 32, 32, 104, 101, 97, 100, 101, 114, // header + 115, 58, 32, 123, 39, 67, 111, 110, 116, 101, 110, 116, // s: {'Content + 45, 84, 121, 112, 101, 39, 58, 32, 39, 97, 112, 112, // -Type': 'app + 108, 105, 99, 97, 116, 105, 111, 110, 47, 106, 115, 111, // lication/jso + 110, 39, 125, 44, 10, 32, 32, 32, 32, 32, 32, 32, // n'},. + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, // + 32, 32, 32, 32, 32, 32, 32, 32, 98, 111, 100, 121, // body + 58, 32, 74, 83, 79, 78, 46, 115, 116, 114, 105, 110, // : JSON.strin + 103, 105, 102, 121, 40, 99, 102, 103, 41, 44, 10, 32, // gify(cfg),. + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, // + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, // + 125, 41, 46, 116, 104, 101, 110, 40, 114, 32, 61, 62, // }).then(r => + 32, 119, 115, 32, 38, 38, 32, 119, 115, 46, 99, 108, // ws && ws.cl + 111, 115, 101, 40, 41, 41, 59, 10, 10, 32, 32, 99, // ose());.. c + 111, 110, 115, 116, 32, 115, 101, 116, 32, 61, 32, 111, // onst set = o + 98, 106, 32, 61, 62, 32, 115, 101, 116, 67, 102, 103, // bj => setCfg + 40, 120, 32, 61, 62, 32, 79, 98, 106, 101, 99, 116, // (x => Object + 46, 97, 115, 115, 105, 103, 110, 40, 120, 44, 32, 111, // .assign(x, o + 98, 106, 41, 41, 59, 10, 32, 32, 99, 111, 110, 115, // bj));. cons + 116, 32, 110, 115, 101, 116, 32, 61, 32, 40, 110, 44, // t nset = (n, + 111, 98, 106, 41, 32, 61, 62, 32, 115, 101, 116, 67, // obj) => setC + 102, 103, 40, 120, 32, 61, 62, 32, 79, 98, 106, 101, // fg(x => Obje + 99, 116, 46, 97, 115, 115, 105, 103, 110, 40, 120, 44, // ct.assign(x, + 32, 123, 91, 110, 93, 58, 32, 79, 98, 106, 101, 99, // {[n]: Objec + 116, 46, 97, 115, 115, 105, 103, 110, 40, 120, 91, 110, // t.assign(x[n + 93, 44, 111, 98, 106, 41, 125, 41, 41, 59, 10, 32, // ],obj)}));. + 32, 99, 111, 110, 115, 116, 32, 115, 101, 116, 84, 120, // const setTx + 32, 61, 32, 101, 118, 32, 61, 62, 32, 115, 101, 116, // = ev => set + 40, 123, 116, 120, 58, 32, 112, 97, 114, 115, 101, 73, // ({tx: parseI + 110, 116, 40, 101, 118, 46, 116, 97, 114, 103, 101, 116, // nt(ev.target + 46, 118, 97, 108, 117, 101, 41, 125, 41, 59, 10, 32, // .value)});. + 32, 99, 111, 110, 115, 116, 32, 115, 101, 116, 82, 120, // const setRx + 32, 61, 32, 101, 118, 32, 61, 62, 32, 115, 101, 116, // = ev => set + 40, 123, 114, 120, 58, 32, 112, 97, 114, 115, 101, 73, // ({rx: parseI + 110, 116, 40, 101, 118, 46, 116, 97, 114, 103, 101, 116, // nt(ev.target + 46, 118, 97, 108, 117, 101, 41, 125, 41, 59, 10, 32, // .value)});. + 32, 99, 111, 110, 115, 116, 32, 115, 101, 116, 66, 97, // const setBa + 117, 100, 32, 61, 32, 101, 118, 32, 61, 62, 32, 115, // ud = ev => s + 101, 116, 40, 123, 98, 97, 117, 100, 58, 32, 112, 97, // et({baud: pa + 114, 115, 101, 73, 110, 116, 40, 101, 118, 46, 116, 97, // rseInt(ev.ta + 114, 103, 101, 116, 46, 118, 97, 108, 117, 101, 41, 125, // rget.value)} + 41, 59, 10, 32, 32, 99, 111, 110, 115, 116, 32, 115, // );. const s + 101, 116, 84, 99, 112, 85, 114, 108, 32, 61, 32, 101, // etTcpUrl = e + 118, 32, 61, 62, 32, 110, 115, 101, 116, 40, 39, 116, // v => nset('t + 99, 112, 39, 44, 32, 123, 117, 114, 108, 58, 32, 96, // cp', {url: ` + 116, 99, 112, 58, 47, 47, 48, 46, 48, 46, 48, 46, // tcp://0.0.0. + 48, 58, 36, 123, 101, 118, 46, 116, 97, 114, 103, 101, // 0:${ev.targe + 116, 46, 118, 97, 108, 117, 101, 125, 96, 125, 41, 59, // t.value}`}); + 10, 32, 32, 99, 111, 110, 115, 116, 32, 115, 101, 116, // . const set + 87, 115, 85, 114, 108, 32, 61, 32, 101, 118, 32, 61, // WsUrl = ev = + 62, 32, 110, 115, 101, 116, 40, 39, 119, 115, 39, 44, // > nset('ws', + 123, 117, 114, 108, 58, 32, 96, 119, 115, 58, 47, 47, // {url: `ws:// + 48, 46, 48, 46, 48, 46, 48, 58, 36, 123, 101, 118, // 0.0.0.0:${ev + 46, 116, 97, 114, 103, 101, 116, 46, 118, 97, 108, 117, // .target.valu + 101, 125, 96, 125, 41, 59, 10, 32, 32, 99, 111, 110, // e}`});. con + 115, 116, 32, 115, 101, 116, 77, 113, 116, 116, 85, 114, // st setMqttUr + 108, 32, 61, 32, 101, 118, 32, 61, 62, 32, 110, 115, // l = ev => ns + 101, 116, 40, 39, 109, 113, 116, 116, 39, 44, 123, 117, // et('mqtt',{u + 114, 108, 58, 32, 101, 118, 46, 116, 97, 114, 103, 101, // rl: ev.targe + 116, 46, 118, 97, 108, 117, 101, 125, 41, 59, 10, 32, // t.value});. + 32, 99, 111, 110, 115, 116, 32, 115, 101, 116, 84, 99, // const setTc + 112, 69, 110, 97, 32, 61, 32, 101, 118, 32, 61, 62, // pEna = ev => + 32, 40, 110, 115, 101, 116, 40, 39, 116, 99, 112, 39, // (nset('tcp' + 44, 123, 101, 110, 97, 98, 108, 101, 58, 32, 101, 118, // ,{enable: ev + 46, 116, 97, 114, 103, 101, 116, 46, 99, 104, 101, 99, // .target.chec + 107, 101, 100, 125, 41, 44, 32, 111, 110, 99, 104, 97, // ked}), oncha + 110, 103, 101, 40, 41, 41, 59, 10, 32, 32, 99, 111, // nge());. co + 110, 115, 116, 32, 115, 101, 116, 87, 115, 69, 110, 97, // nst setWsEna + 32, 61, 32, 101, 118, 32, 61, 62, 32, 40, 110, 115, // = ev => (ns + 101, 116, 40, 39, 119, 115, 39, 44, 123, 101, 110, 97, // et('ws',{ena + 98, 108, 101, 58, 32, 101, 118, 46, 116, 97, 114, 103, // ble: ev.targ + 101, 116, 46, 99, 104, 101, 99, 107, 101, 100, 125, 41, // et.checked}) + 44, 32, 111, 110, 99, 104, 97, 110, 103, 101, 40, 41, // , onchange() + 41, 59, 10, 32, 32, 99, 111, 110, 115, 116, 32, 115, // );. const s + 101, 116, 77, 113, 116, 116, 69, 110, 97, 32, 61, 32, // etMqttEna = + 101, 118, 32, 61, 62, 40, 110, 115, 101, 116, 40, 39, // ev =>(nset(' + 109, 113, 116, 116, 39, 44, 32, 123, 101, 110, 97, 98, // mqtt', {enab + 108, 101, 58, 32, 101, 118, 46, 116, 97, 114, 103, 101, // le: ev.targe + 116, 46, 99, 104, 101, 99, 107, 101, 100, 125, 41, 44, // t.checked}), + 32, 111, 110, 99, 104, 97, 110, 103, 101, 40, 41, 41, // onchange()) + 59, 10, 10, 32, 32, 114, 101, 116, 117, 114, 110, 32, // ;.. return + 104, 116, 109, 108, 96, 10, 60, 100, 105, 118, 32, 99, // html`.
.

UART .u27F + 55, 32, 110, 101, 116, 119, 111, 114, 107, 32, 98, 114, // 7 network br + 105, 100, 103, 101, 32, 60, 47, 104, 49, 62, 10, 32, // idge

. + 32, 60, 112, 114, 101, 32, 99, 108, 97, 115, 115, 61, //
${J
+  83,  79,  78,  46, 115, 116, 114, 105, 110, 103, 105, 102, // SON.stringif
+ 121,  40,  99, 102, 103,  44,  32, 110, 117, 108, 108,  44, // y(cfg, null,
+  32,  50,  41, 125,  60,  47, 112, 114, 101,  62,  10,  32, //  2)}
. + 32, 60, 100, 105, 118, 32, 99, 108, 97, 115, 115, 61, //
. < + 100, 105, 118, 32, 99, 108, 97, 115, 115, 61, 34, 99, // div class="c + 111, 108, 32, 99, 111, 108, 45, 52, 34, 62, 10, 32, // ol col-4">. + 32, 32, 32, 32, 32, 60, 104, 51, 62, 85, 65, 82, //

UAR + 84, 32, 99, 111, 110, 102, 105, 103, 117, 114, 97, 116, // T configurat + 105, 111, 110, 60, 47, 104, 51, 62, 10, 32, 32, 32, // ion

. + 32, 32, 32, 60, 100, 105, 118, 32, 99, 108, 97, 115, //
. + 32, 32, 32, 32, 32, 32, 60, 108, 97, 98, 101, 108, // . + 32, 32, 32, 32, 32, 32, 32, 60, 105, 110, 112, 117, // . < + 47, 100, 105, 118, 62, 60, 100, 105, 118, 32, 99, 108, // /div>
. + 32, 32, 32, 32, 32, 32, 32, 32, 60, 108, 97, 98, // UART RX + 32, 112, 105, 110, 60, 47, 108, 97, 98, 101, 108, 62, // pin + 10, 32, 32, 32, 32, 32, 32, 32, 32, 60, 105, 110, // . . + 32, 60, 47, 100, 105, 118, 62, 60, 100, 105, 118, 32, //
. UART + 66, 97, 117, 100, 60, 47, 108, 97, 98, 101, 108, 62, // Baud + 10, 32, 32, 32, 32, 32, 32, 32, 32, 60, 105, 110, // . . + 32, 32, 32, 32, 32, 60, 47, 100, 105, 118, 62, 10, //
. + 32, 32, 32, 32, 60, 47, 100, 105, 118, 62, 10, 32, //
. + 32, 32, 32, 60, 100, 105, 118, 32, 99, 108, 97, 115, //
.

Network con + 102, 105, 103, 117, 114, 97, 116, 105, 111, 110, 60, 47, // figuration. . + 32, 32, 32, 32, 32, 32, 32, 32, 60, 108, 97, 98, // Local T + 67, 80, 32, 112, 111, 114, 116, 60, 47, 108, 97, 98, // CP port. + 60, 105, 110, 112, 117, 116, 32, 115, 116, 121, 108, 101, // . enabl + 101, 60, 47, 108, 97, 98, 101, 108, 62, 10, 32, 32, // e. + 32, 32, 32, 32, 60, 47, 100, 105, 118, 62, 60, 100, //

. + 32, 32, 32, 32, 32, 32, 32, 32, 60, 108, 97, 98, // Local W + 83, 32, 112, 111, 114, 116, 60, 47, 108, 97, 98, 101, // S port. < + 105, 110, 112, 117, 116, 32, 115, 116, 121, 108, 101, 61, // input style= + 34, 102, 108, 101, 120, 58, 32, 49, 32, 49, 48, 48, // "flex: 1 100 + 37, 59, 34, 10, 32, 32, 32, 32, 32, 32, 32, 32, // %;". + 32, 32, 118, 97, 108, 117, 101, 61, 36, 123, 103, 101, // value=${ge + 116, 112, 111, 114, 116, 40, 99, 102, 103, 46, 119, 115, // tport(cfg.ws + 46, 117, 114, 108, 44, 32, 52, 48, 48, 50, 41, 125, // .url, 4002)} + 32, 111, 110, 99, 104, 97, 110, 103, 101, 61, 36, 123, // onchange=${ + 111, 110, 99, 104, 97, 110, 103, 101, 125, 10, 32, 32, // onchange}. + 32, 32, 32, 32, 32, 32, 32, 32, 111, 110, 105, 110, // onin + 112, 117, 116, 61, 36, 123, 115, 101, 116, 87, 115, 85, // put=${setWsU + 114, 108, 125, 32, 47, 62, 10, 32, 32, 32, 32, 32, // rl} />. + 32, 32, 32, 60, 108, 97, 98, 101, 108, 32, 99, 108, // + 10, 32, 32, 32, 32, 32, 32, 60, 47, 100, 105, 118, // .
. < + 108, 97, 98, 101, 108, 32, 99, 108, 97, 115, 115, 61, // label class= + 34, 97, 100, 100, 111, 110, 34, 62, 82, 101, 109, 111, // "addon">Remo + 116, 101, 32, 77, 81, 84, 84, 60, 47, 108, 97, 98, // te MQTT. + 60, 105, 110, 112, 117, 116, 32, 115, 116, 121, 108, 101, // . + 32, 32, 32, 32, 32, 60, 108, 97, 98, 101, 108, 32, //
. + 60, 47, 100, 105, 118, 62, 10, 32, 32, 60, 47, 100, //
. ..
+ 10, 32, 32, 32, 32, 78, 111, 116, 101, 58, 32, 116, // . Note: t + 111, 32, 99, 111, 110, 110, 101, 99, 116, 32, 111, 118, // o connect ov + 101, 114, 32, 77, 81, 84, 84, 44, 32, 10, 32, 32, // er MQTT, . + 32, 32, 32, 32, 111, 112, 101, 110, 32, 60, 97, 32, // open . + 32, 32, 99, 111, 110, 115, 111, 108, 101, 60, 47, 97, // console, subscribe + 32, 116, 111, 32, 98, 47, 116, 120, 32, 97, 110, 100, // to b/tx and + 32, 112, 117, 98, 108, 105, 115, 104, 32, 116, 111, 32, // publish to + 98, 47, 114, 120, 60, 98, 114, 47, 62, 10, 32, 32, // b/rx
. + 32, 32, 78, 111, 116, 101, 58, 32, 116, 111, 32, 99, // Note: to c + 111, 110, 110, 101, 99, 116, 32, 111, 118, 101, 114, 32, // onnect over + 84, 67, 80, 44, 32, 117, 115, 101, 32, 110, 101, 116, // TCP, use net + 99, 97, 116, 32, 117, 116, 105, 108, 105, 116, 121, 58, // cat utility: + 60, 98, 114, 47, 62, 10, 32, 32, 32, 32, 36, 32, //
. $ + 110, 99, 32, 36, 123, 108, 111, 99, 97, 116, 105, 111, // nc ${locatio + 110, 46, 104, 111, 115, 116, 110, 97, 109, 101, 125, 32, // n.hostname} + 36, 123, 103, 101, 116, 112, 111, 114, 116, 40, 99, 102, // ${getport(cf + 103, 46, 116, 99, 112, 46, 117, 114, 108, 44, 32, 52, // g.tcp.url, 4 + 48, 48, 49, 41, 125, 10, 32, 32, 60, 47, 100, 105, // 001)}. ..
+ 10, 32, 32, 32, 32, 60, 98, 62, 85, 65, 82, 84, // . UART + 32, 99, 111, 110, 115, 111, 108, 101, 60, 47, 98, 62, // console + 60, 115, 112, 97, 110, 32, 115, 116, 121, 108, 101, 61, // wor + 107, 115, 32, 10, 32, 32, 32, 32, 111, 118, 101, 114, // ks . over + 32, 116, 104, 101, 32, 108, 111, 99, 97, 108, 32, 87, // the local W + 83, 32, 112, 111, 114, 116, 46, 32, 87, 101, 98, 83, // S port. WebS + 111, 99, 107, 101, 116, 32, 115, 116, 97, 116, 117, 115, // ocket status + 58, 32, 60, 47, 115, 112, 97, 110, 62, 60, 115, 112, // : . + 32, 32, 92, 117, 50, 53, 99, 102, 32, 36, 123, 99, // .u25cf ${c + 111, 110, 110, 101, 99, 116, 101, 100, 32, 63, 32, 39, // onnected ? ' + 99, 111, 110, 110, 101, 99, 116, 101, 100, 39, 32, 58, // connected' : + 32, 39, 100, 105, 115, 99, 111, 110, 110, 101, 99, 116, // 'disconnect + 101, 100, 39, 125, 32, 60, 47, 115, 112, 97, 110, 62, // ed'} + 10, 32, 32, 60, 47, 100, 105, 118, 62, 10, 32, 32, // .
. + 60, 100, 105, 118, 32, 115, 116, 121, 108, 101, 61, 34, //
. + 32, 60, 105, 110, 112, 117, 116, 32, 112, 108, 97, 99, // setTxt(ev + 46, 116, 97, 114, 103, 101, 116, 46, 118, 97, 108, 117, // .target.valu + 101, 41, 125, 32, 47, 62, 10, 32, 32, 32, 32, 60, // e)} />. < + 98, 117, 116, 116, 111, 110, 32, 115, 116, 121, 108, 101, // button style + 61, 34, 109, 97, 114, 103, 105, 110, 45, 108, 101, 102, // ="margin-lef + 116, 58, 32, 49, 101, 109, 59, 34, 10, 32, 32, 32, // t: 1em;". + 32, 32, 32, 111, 110, 99, 108, 105, 99, 107, 61, 36, // onclick=$ + 123, 101, 118, 32, 61, 62, 32, 115, 101, 116, 77, 101, // {ev => setMe + 115, 115, 97, 103, 101, 115, 40, 91, 93, 41, 125, 62, // ssages([])}> + 99, 108, 101, 97, 114, 60, 47, 98, 117, 116, 116, 111, // clear.
. + 32, 32, 60, 112, 114, 101, 32, 115, 116, 121, 108, 101, //
.  
+  32,  32,  36, 123, 109, 101, 115, 115,  97, 103, 101, 115, //   ${messages
+  46, 109,  97, 112,  40, 109, 101, 115, 115,  97, 103, 101, // .map(message
+  32,  61,  62,  32, 104,  40,  77, 101, 115, 115,  97, 103, //  => h(Messag
+ 101,  44,  32, 123, 109, 101, 115, 115,  97, 103, 101, 125, // e, {message}
+  41,  41, 125,  10,  32,  32,  60,  47, 112, 114, 101,  62, // ))}.  
+ 10, 10, 60, 47, 100, 105, 118, 62, 96, 59, 10, 125, // ..
`;.} + 59, 10, 10, 119, 105, 110, 100, 111, 119, 46, 111, 110, // ;..window.on + 108, 111, 97, 100, 32, 61, 32, 40, 41, 32, 61, 62, // load = () => + 32, 114, 101, 110, 100, 101, 114, 40, 104, 40, 65, 112, // render(h(Ap + 112, 41, 44, 32, 100, 111, 99, 117, 109, 101, 110, 116, // p), document + 46, 98, 111, 100, 121, 41, 59, 10, 0 // .body);. +}; +static const unsigned char v3[] = { 118, 97, 114, 32, 101, 44, 110, 44, 95, 44, 116, 44, // var e,n,_,t, 111, 44, 114, 44, 117, 44, 108, 61, 123, 125, 44, 105, // o,r,u,l={},i 61, 91, 93, 44, 99, 61, 47, 97, 99, 105, 116, 124, // =[],c=/acit| @@ -1138,7 +1632,7 @@ static const unsigned char v2[] = { 115, 101, 69, 114, 114, 111, 114, 66, 111, 117, 110, 100, // seErrorBound 97, 114, 121, 125, 59, 10, 0 // ary};. }; -static const unsigned char v3[] = { +static const unsigned char v4[] = { 42, 32, 123, 32, 98, 111, 120, 45, 115, 105, 122, 105, // * { box-sizi 110, 103, 58, 32, 98, 111, 114, 100, 101, 114, 45, 98, // ng: border-b 111, 120, 59, 32, 125, 10, 104, 116, 109, 108, 44, 32, // ox; }.html, @@ -1311,500 +1805,6 @@ static const unsigned char v3[] = { 32, 119, 105, 100, 116, 104, 58, 32, 49, 48, 48, 37, // width: 100% 59, 32, 125, 32, 125, 10, 0 // ; } }. }; -static const unsigned char v4[] = { - 39, 117, 115, 101, 32, 115, 116, 114, 105, 99, 116, 39, // 'use strict' - 59, 10, 105, 109, 112, 111, 114, 116, 32, 123, 67, 111, // ;.import {Co - 109, 112, 111, 110, 101, 110, 116, 44, 32, 104, 44, 32, // mponent, h, - 104, 116, 109, 108, 44, 32, 114, 101, 110, 100, 101, 114, // html, render - 44, 32, 117, 115, 101, 69, 102, 102, 101, 99, 116, 44, // , useEffect, - 32, 117, 115, 101, 83, 116, 97, 116, 101, 44, 32, 117, // useState, u - 115, 101, 82, 101, 102, 125, 32, 102, 114, 111, 109, 32, // seRef} from - 39, 46, 47, 112, 114, 101, 97, 99, 116, 46, 109, 105, // './preact.mi - 110, 46, 106, 115, 39, 59, 10, 10, 99, 111, 110, 115, // n.js';..cons - 116, 32, 77, 101, 115, 115, 97, 103, 101, 32, 61, 32, // t Message = - 109, 32, 61, 62, 32, 104, 116, 109, 108, 96, 60, 115, // m => html`. - 32, 36, 123, 109, 46, 109, 101, 115, 115, 97, 103, 101, // ${m.message - 46, 100, 97, 116, 97, 125, 10, 60, 47, 115, 112, 97, // .data}.`;..const - 65, 112, 112, 32, 61, 32, 102, 117, 110, 99, 116, 105, // App = functi - 111, 110, 40, 112, 114, 111, 112, 115, 41, 32, 123, 10, // on(props) {. - 32, 32, 99, 111, 110, 115, 116, 32, 91, 99, 102, 103, // const [cfg - 44, 32, 115, 101, 116, 67, 102, 103, 93, 32, 61, 32, // , setCfg] = - 117, 115, 101, 83, 116, 97, 116, 101, 40, 123, 116, 99, // useState({tc - 112, 58, 32, 123, 125, 44, 32, 119, 115, 58, 32, 123, // p: {}, ws: { - 125, 44, 32, 109, 113, 116, 116, 58, 32, 123, 125, 125, // }, mqtt: {}} - 41, 59, 10, 32, 32, 99, 111, 110, 115, 116, 32, 91, // );. const [ - 109, 101, 115, 115, 97, 103, 101, 115, 44, 32, 115, 101, // messages, se - 116, 77, 101, 115, 115, 97, 103, 101, 115, 93, 32, 61, // tMessages] = - 32, 117, 115, 101, 83, 116, 97, 116, 101, 40, 91, 93, // useState([] - 41, 59, 10, 32, 32, 99, 111, 110, 115, 116, 32, 91, // );. const [ - 99, 111, 110, 110, 101, 99, 116, 101, 100, 44, 32, 115, // connected, s - 101, 116, 67, 111, 110, 110, 101, 99, 116, 101, 100, 93, // etConnected] - 32, 61, 32, 117, 115, 101, 83, 116, 97, 116, 101, 40, // = useState( - 102, 97, 108, 115, 101, 41, 59, 10, 32, 32, 99, 111, // false);. co - 110, 115, 116, 32, 91, 116, 120, 116, 44, 32, 115, 101, // nst [txt, se - 116, 84, 120, 116, 93, 32, 61, 32, 117, 115, 101, 83, // tTxt] = useS - 116, 97, 116, 101, 40, 39, 39, 41, 59, 10, 32, 32, // tate('');. - 99, 111, 110, 115, 116, 32, 91, 119, 115, 44, 32, 115, // const [ws, s - 101, 116, 87, 115, 93, 32, 61, 32, 117, 115, 101, 83, // etWs] = useS - 116, 97, 116, 101, 40, 110, 117, 108, 108, 41, 59, 10, // tate(null);. - 10, 32, 32, 99, 111, 110, 115, 116, 32, 114, 101, 102, // . const ref - 114, 101, 115, 104, 32, 61, 32, 40, 41, 32, 61, 62, // resh = () => - 10, 32, 32, 32, 32, 32, 32, 102, 101, 116, 99, 104, // . fetch - 40, 39, 47, 97, 112, 105, 47, 99, 111, 110, 102, 105, // ('/api/confi - 103, 47, 103, 101, 116, 39, 41, 46, 116, 104, 101, 110, // g/get').then - 40, 114, 32, 61, 62, 32, 114, 46, 106, 115, 111, 110, // (r => r.json - 40, 41, 41, 46, 116, 104, 101, 110, 40, 114, 32, 61, // ()).then(r = - 62, 32, 115, 101, 116, 67, 102, 103, 40, 114, 41, 41, // > setCfg(r)) - 59, 10, 10, 32, 32, 99, 111, 110, 115, 116, 32, 103, // ;.. const g - 101, 116, 112, 111, 114, 116, 32, 61, 32, 40, 117, 114, // etport = (ur - 108, 44, 32, 118, 41, 32, 61, 62, 32, 40, 40, 117, // l, v) => ((u - 114, 108, 32, 124, 124, 32, 39, 39, 41, 46, 109, 97, // rl || '').ma - 116, 99, 104, 40, 47, 46, 42, 58, 40, 92, 100, 43, // tch(/.*:(.d+ - 41, 47, 41, 32, 124, 124, 32, 91, 39, 39, 44, 32, // )/) || ['', - 118, 93, 41, 91, 49, 93, 59, 10, 10, 32, 32, 99, // v])[1];.. c - 111, 110, 115, 116, 32, 119, 97, 116, 99, 104, 87, 101, // onst watchWe - 98, 115, 111, 99, 107, 101, 116, 32, 61, 32, 102, 117, // bsocket = fu - 110, 99, 116, 105, 111, 110, 40, 41, 32, 123, 10, 32, // nction() {. - 32, 32, 32, 47, 47, 32, 67, 111, 110, 110, 101, 99, // // Connec - 116, 32, 116, 111, 32, 119, 101, 98, 115, 111, 99, 107, // t to websock - 101, 114, 32, 112, 111, 114, 116, 44, 32, 116, 111, 32, // er port, to - 105, 109, 112, 108, 101, 109, 101, 110, 116, 32, 87, 83, // implement WS - 32, 99, 111, 110, 115, 111, 108, 101, 10, 32, 32, 32, // console. - 32, 118, 97, 114, 32, 114, 101, 99, 111, 110, 110, 101, // var reconne - 99, 116, 32, 61, 32, 102, 117, 110, 99, 116, 105, 111, // ct = functio - 110, 40, 41, 32, 123, 10, 32, 32, 32, 32, 32, 32, // n() {. - 118, 97, 114, 32, 112, 111, 114, 116, 32, 61, 32, 103, // var port = g - 101, 116, 112, 111, 114, 116, 40, 99, 102, 103, 46, 119, // etport(cfg.w - 115, 46, 117, 114, 108, 44, 32, 52, 48, 48, 50, 41, // s.url, 4002) - 59, 10, 32, 32, 32, 32, 32, 32, 118, 97, 114, 32, // ;. var - 108, 32, 61, 32, 119, 105, 110, 100, 111, 119, 46, 108, // l = window.l - 111, 99, 97, 116, 105, 111, 110, 44, 32, 112, 114, 111, // ocation, pro - 116, 111, 32, 61, 32, 108, 46, 112, 114, 111, 116, 111, // to = l.proto - 99, 111, 108, 46, 114, 101, 112, 108, 97, 99, 101, 40, // col.replace( - 39, 104, 116, 116, 112, 39, 44, 32, 39, 119, 115, 39, // 'http', 'ws' - 41, 59, 10, 32, 32, 32, 32, 32, 32, 118, 97, 114, // );. var - 32, 116, 105, 100, 44, 32, 117, 114, 108, 32, 61, 32, // tid, url = - 96, 36, 123, 112, 114, 111, 116, 111, 125, 47, 47, 36, // `${proto}//$ - 123, 108, 46, 104, 111, 115, 116, 110, 97, 109, 101, 125, // {l.hostname} - 58, 36, 123, 112, 111, 114, 116, 125, 47, 119, 115, 96, // :${port}/ws` - 59, 10, 32, 32, 32, 32, 32, 32, 47, 47, 32, 99, // ;. // c - 111, 110, 115, 111, 108, 101, 46, 108, 111, 103, 40, 117, // onsole.log(u - 114, 108, 41, 59, 10, 32, 32, 32, 32, 32, 32, 118, // rl);. v - 97, 114, 32, 119, 115, 32, 61, 32, 110, 101, 119, 32, // ar ws = new - 87, 101, 98, 83, 111, 99, 107, 101, 116, 40, 117, 114, // WebSocket(ur - 108, 41, 59, 10, 32, 32, 32, 32, 32, 32, 119, 115, // l);. ws - 46, 111, 110, 111, 112, 101, 110, 32, 61, 32, 40, 41, // .onopen = () - 32, 61, 62, 32, 123, 10, 32, 32, 32, 32, 32, 32, // => {. - 32, 32, 115, 101, 116, 67, 111, 110, 110, 101, 99, 116, // setConnect - 101, 100, 40, 116, 114, 117, 101, 41, 59, 10, 32, 32, // ed(true);. - 32, 32, 32, 32, 32, 32, 115, 101, 116, 87, 115, 40, // setWs( - 119, 115, 41, 59, 10, 32, 32, 32, 32, 32, 32, 125, // ws);. } - 59, 10, 32, 32, 32, 32, 32, 32, 119, 115, 46, 111, // ;. ws.o - 110, 109, 101, 115, 115, 97, 103, 101, 32, 61, 32, 101, // nmessage = e - 118, 32, 61, 62, 32, 123, 10, 32, 32, 32, 32, 32, // v => {. - 32, 32, 32, 47, 47, 32, 99, 111, 110, 115, 111, 108, // // consol - 101, 46, 108, 111, 103, 40, 101, 118, 44, 32, 101, 118, // e.log(ev, ev - 46, 100, 97, 116, 97, 41, 59, 10, 32, 32, 32, 32, // .data);. - 32, 32, 32, 32, 115, 101, 116, 77, 101, 115, 115, 97, // setMessa - 103, 101, 115, 40, 120, 32, 61, 62, 32, 120, 46, 99, // ges(x => x.c - 111, 110, 99, 97, 116, 40, 91, 123, 100, 97, 116, 97, // oncat([{data - 58, 32, 101, 118, 46, 100, 97, 116, 97, 44, 32, 117, // : ev.data, u - 97, 114, 116, 58, 32, 116, 114, 117, 101, 125, 93, 41, // art: true}]) - 41, 59, 10, 32, 32, 32, 32, 32, 32, 125, 59, 10, // );. };. - 32, 32, 32, 32, 32, 32, 119, 115, 46, 111, 110, 99, // ws.onc - 108, 111, 115, 101, 32, 61, 32, 102, 117, 110, 99, 116, // lose = funct - 105, 111, 110, 40, 41, 32, 123, 10, 32, 32, 32, 32, // ion() {. - 32, 32, 32, 32, 99, 108, 101, 97, 114, 84, 105, 109, // clearTim - 101, 111, 117, 116, 40, 116, 105, 100, 41, 59, 10, 32, // eout(tid);. - 32, 32, 32, 32, 32, 32, 32, 116, 105, 100, 32, 61, // tid = - 32, 115, 101, 116, 84, 105, 109, 101, 111, 117, 116, 40, // setTimeout( - 114, 101, 99, 111, 110, 110, 101, 99, 116, 44, 32, 49, // reconnect, 1 - 48, 48, 48, 41, 59, 10, 32, 32, 32, 32, 32, 32, // 000);. - 32, 32, 115, 101, 116, 67, 111, 110, 110, 101, 99, 116, // setConnect - 101, 100, 40, 102, 97, 108, 115, 101, 41, 59, 10, 32, // ed(false);. - 32, 32, 32, 32, 32, 32, 32, 115, 101, 116, 87, 115, // setWs - 40, 110, 117, 108, 108, 41, 59, 10, 32, 32, 32, 32, // (null);. - 32, 32, 125, 59, 10, 32, 32, 32, 32, 125, 59, 10, // };. };. - 32, 32, 32, 32, 114, 101, 99, 111, 110, 110, 101, 99, // reconnec - 116, 40, 41, 59, 10, 32, 32, 125, 59, 10, 10, 32, // t();. };.. - 32, 117, 115, 101, 69, 102, 102, 101, 99, 116, 40, 40, // useEffect(( - 41, 32, 61, 62, 32, 123, 10, 32, 32, 32, 32, 114, // ) => {. r - 101, 102, 114, 101, 115, 104, 40, 41, 59, 10, 32, 32, // efresh();. - 32, 32, 119, 97, 116, 99, 104, 87, 101, 98, 115, 111, // watchWebso - 99, 107, 101, 116, 40, 41, 59, 10, 32, 32, 125, 44, // cket();. }, - 32, 91, 93, 41, 59, 10, 10, 10, 32, 32, 99, 111, // []);... co - 110, 115, 116, 32, 115, 101, 110, 100, 109, 101, 115, 115, // nst sendmess - 97, 103, 101, 32, 61, 32, 101, 118, 32, 61, 62, 32, // age = ev => - 123, 10, 32, 32, 32, 32, 115, 101, 116, 77, 101, 115, // {. setMes - 115, 97, 103, 101, 115, 40, 120, 32, 61, 62, 32, 120, // sages(x => x - 46, 99, 111, 110, 99, 97, 116, 40, 91, 123, 100, 97, // .concat([{da - 116, 97, 58, 32, 116, 120, 116, 32, 43, 32, 39, 92, // ta: txt + '. - 110, 39, 44, 32, 117, 97, 114, 116, 58, 32, 102, 97, // n', uart: fa - 108, 115, 101, 125, 93, 41, 41, 59, 10, 32, 32, 32, // lse}]));. - 32, 105, 102, 32, 40, 119, 115, 41, 32, 119, 115, 46, // if (ws) ws. - 115, 101, 110, 100, 40, 116, 120, 116, 32, 43, 32, 39, // send(txt + ' - 92, 110, 39, 41, 59, 10, 32, 32, 32, 32, 115, 101, // .n');. se - 116, 84, 120, 116, 40, 39, 39, 41, 59, 10, 32, 32, // tTxt('');. - 125, 59, 10, 10, 32, 32, 99, 111, 110, 115, 116, 32, // };.. const - 111, 110, 99, 104, 97, 110, 103, 101, 32, 61, 32, 101, // onchange = e - 118, 32, 61, 62, 32, 102, 101, 116, 99, 104, 40, 39, // v => fetch(' - 47, 97, 112, 105, 47, 99, 111, 110, 102, 105, 103, 47, // /api/config/ - 115, 101, 116, 39, 44, 32, 123, 10, 32, 32, 32, 32, // set', {. - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, // - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 109, // m - 101, 116, 104, 111, 100, 58, 32, 39, 80, 79, 83, 84, // ethod: 'POST - 39, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, // ',. - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, // - 32, 32, 32, 32, 32, 32, 104, 101, 97, 100, 101, 114, // header - 115, 58, 32, 123, 39, 67, 111, 110, 116, 101, 110, 116, // s: {'Content - 45, 84, 121, 112, 101, 39, 58, 32, 39, 97, 112, 112, // -Type': 'app - 108, 105, 99, 97, 116, 105, 111, 110, 47, 106, 115, 111, // lication/jso - 110, 39, 125, 44, 10, 32, 32, 32, 32, 32, 32, 32, // n'},. - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, // - 32, 32, 32, 32, 32, 32, 32, 32, 98, 111, 100, 121, // body - 58, 32, 74, 83, 79, 78, 46, 115, 116, 114, 105, 110, // : JSON.strin - 103, 105, 102, 121, 40, 99, 102, 103, 41, 44, 10, 32, // gify(cfg),. - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, // - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, // - 125, 41, 46, 116, 104, 101, 110, 40, 114, 32, 61, 62, // }).then(r => - 32, 119, 115, 32, 38, 38, 32, 119, 115, 46, 99, 108, // ws && ws.cl - 111, 115, 101, 40, 41, 41, 59, 10, 10, 32, 32, 99, // ose());.. c - 111, 110, 115, 116, 32, 115, 101, 116, 32, 61, 32, 111, // onst set = o - 98, 106, 32, 61, 62, 32, 115, 101, 116, 67, 102, 103, // bj => setCfg - 40, 120, 32, 61, 62, 32, 79, 98, 106, 101, 99, 116, // (x => Object - 46, 97, 115, 115, 105, 103, 110, 40, 120, 44, 32, 111, // .assign(x, o - 98, 106, 41, 41, 59, 10, 32, 32, 99, 111, 110, 115, // bj));. cons - 116, 32, 110, 115, 101, 116, 32, 61, 32, 40, 110, 44, // t nset = (n, - 111, 98, 106, 41, 32, 61, 62, 32, 115, 101, 116, 67, // obj) => setC - 102, 103, 40, 120, 32, 61, 62, 32, 79, 98, 106, 101, // fg(x => Obje - 99, 116, 46, 97, 115, 115, 105, 103, 110, 40, 120, 44, // ct.assign(x, - 32, 123, 91, 110, 93, 58, 32, 79, 98, 106, 101, 99, // {[n]: Objec - 116, 46, 97, 115, 115, 105, 103, 110, 40, 120, 91, 110, // t.assign(x[n - 93, 44, 111, 98, 106, 41, 125, 41, 41, 59, 10, 32, // ],obj)}));. - 32, 99, 111, 110, 115, 116, 32, 115, 101, 116, 84, 120, // const setTx - 32, 61, 32, 101, 118, 32, 61, 62, 32, 115, 101, 116, // = ev => set - 40, 123, 116, 120, 58, 32, 112, 97, 114, 115, 101, 73, // ({tx: parseI - 110, 116, 40, 101, 118, 46, 116, 97, 114, 103, 101, 116, // nt(ev.target - 46, 118, 97, 108, 117, 101, 41, 125, 41, 59, 10, 32, // .value)});. - 32, 99, 111, 110, 115, 116, 32, 115, 101, 116, 82, 120, // const setRx - 32, 61, 32, 101, 118, 32, 61, 62, 32, 115, 101, 116, // = ev => set - 40, 123, 114, 120, 58, 32, 112, 97, 114, 115, 101, 73, // ({rx: parseI - 110, 116, 40, 101, 118, 46, 116, 97, 114, 103, 101, 116, // nt(ev.target - 46, 118, 97, 108, 117, 101, 41, 125, 41, 59, 10, 32, // .value)});. - 32, 99, 111, 110, 115, 116, 32, 115, 101, 116, 66, 97, // const setBa - 117, 100, 32, 61, 32, 101, 118, 32, 61, 62, 32, 115, // ud = ev => s - 101, 116, 40, 123, 98, 97, 117, 100, 58, 32, 112, 97, // et({baud: pa - 114, 115, 101, 73, 110, 116, 40, 101, 118, 46, 116, 97, // rseInt(ev.ta - 114, 103, 101, 116, 46, 118, 97, 108, 117, 101, 41, 125, // rget.value)} - 41, 59, 10, 32, 32, 99, 111, 110, 115, 116, 32, 115, // );. const s - 101, 116, 84, 99, 112, 85, 114, 108, 32, 61, 32, 101, // etTcpUrl = e - 118, 32, 61, 62, 32, 110, 115, 101, 116, 40, 39, 116, // v => nset('t - 99, 112, 39, 44, 32, 123, 117, 114, 108, 58, 32, 96, // cp', {url: ` - 116, 99, 112, 58, 47, 47, 48, 46, 48, 46, 48, 46, // tcp://0.0.0. - 48, 58, 36, 123, 101, 118, 46, 116, 97, 114, 103, 101, // 0:${ev.targe - 116, 46, 118, 97, 108, 117, 101, 125, 96, 125, 41, 59, // t.value}`}); - 10, 32, 32, 99, 111, 110, 115, 116, 32, 115, 101, 116, // . const set - 87, 115, 85, 114, 108, 32, 61, 32, 101, 118, 32, 61, // WsUrl = ev = - 62, 32, 110, 115, 101, 116, 40, 39, 119, 115, 39, 44, // > nset('ws', - 123, 117, 114, 108, 58, 32, 96, 119, 115, 58, 47, 47, // {url: `ws:// - 48, 46, 48, 46, 48, 46, 48, 58, 36, 123, 101, 118, // 0.0.0.0:${ev - 46, 116, 97, 114, 103, 101, 116, 46, 118, 97, 108, 117, // .target.valu - 101, 125, 96, 125, 41, 59, 10, 32, 32, 99, 111, 110, // e}`});. con - 115, 116, 32, 115, 101, 116, 77, 113, 116, 116, 85, 114, // st setMqttUr - 108, 32, 61, 32, 101, 118, 32, 61, 62, 32, 110, 115, // l = ev => ns - 101, 116, 40, 39, 109, 113, 116, 116, 39, 44, 123, 117, // et('mqtt',{u - 114, 108, 58, 32, 101, 118, 46, 116, 97, 114, 103, 101, // rl: ev.targe - 116, 46, 118, 97, 108, 117, 101, 125, 41, 59, 10, 32, // t.value});. - 32, 99, 111, 110, 115, 116, 32, 115, 101, 116, 84, 99, // const setTc - 112, 69, 110, 97, 32, 61, 32, 101, 118, 32, 61, 62, // pEna = ev => - 32, 40, 110, 115, 101, 116, 40, 39, 116, 99, 112, 39, // (nset('tcp' - 44, 123, 101, 110, 97, 98, 108, 101, 58, 32, 101, 118, // ,{enable: ev - 46, 116, 97, 114, 103, 101, 116, 46, 99, 104, 101, 99, // .target.chec - 107, 101, 100, 125, 41, 44, 32, 111, 110, 99, 104, 97, // ked}), oncha - 110, 103, 101, 40, 41, 41, 59, 10, 32, 32, 99, 111, // nge());. co - 110, 115, 116, 32, 115, 101, 116, 87, 115, 69, 110, 97, // nst setWsEna - 32, 61, 32, 101, 118, 32, 61, 62, 32, 40, 110, 115, // = ev => (ns - 101, 116, 40, 39, 119, 115, 39, 44, 123, 101, 110, 97, // et('ws',{ena - 98, 108, 101, 58, 32, 101, 118, 46, 116, 97, 114, 103, // ble: ev.targ - 101, 116, 46, 99, 104, 101, 99, 107, 101, 100, 125, 41, // et.checked}) - 44, 32, 111, 110, 99, 104, 97, 110, 103, 101, 40, 41, // , onchange() - 41, 59, 10, 32, 32, 99, 111, 110, 115, 116, 32, 115, // );. const s - 101, 116, 77, 113, 116, 116, 69, 110, 97, 32, 61, 32, // etMqttEna = - 101, 118, 32, 61, 62, 40, 110, 115, 101, 116, 40, 39, // ev =>(nset(' - 109, 113, 116, 116, 39, 44, 32, 123, 101, 110, 97, 98, // mqtt', {enab - 108, 101, 58, 32, 101, 118, 46, 116, 97, 114, 103, 101, // le: ev.targe - 116, 46, 99, 104, 101, 99, 107, 101, 100, 125, 41, 44, // t.checked}), - 32, 111, 110, 99, 104, 97, 110, 103, 101, 40, 41, 41, // onchange()) - 59, 10, 10, 32, 32, 114, 101, 116, 117, 114, 110, 32, // ;.. return - 104, 116, 109, 108, 96, 10, 60, 100, 105, 118, 32, 99, // html`.
.

UART .u27F - 55, 32, 110, 101, 116, 119, 111, 114, 107, 32, 98, 114, // 7 network br - 105, 100, 103, 101, 32, 60, 47, 104, 49, 62, 10, 32, // idge

. - 32, 60, 112, 114, 101, 32, 99, 108, 97, 115, 115, 61, //
${J
-  83,  79,  78,  46, 115, 116, 114, 105, 110, 103, 105, 102, // SON.stringif
- 121,  40,  99, 102, 103,  44,  32, 110, 117, 108, 108,  44, // y(cfg, null,
-  32,  50,  41, 125,  60,  47, 112, 114, 101,  62,  10,  32, //  2)}
. - 32, 60, 100, 105, 118, 32, 99, 108, 97, 115, 115, 61, //
. < - 100, 105, 118, 32, 99, 108, 97, 115, 115, 61, 34, 99, // div class="c - 111, 108, 32, 99, 111, 108, 45, 52, 34, 62, 10, 32, // ol col-4">. - 32, 32, 32, 32, 32, 60, 104, 51, 62, 85, 65, 82, //

UAR - 84, 32, 99, 111, 110, 102, 105, 103, 117, 114, 97, 116, // T configurat - 105, 111, 110, 60, 47, 104, 51, 62, 10, 32, 32, 32, // ion

. - 32, 32, 32, 60, 100, 105, 118, 32, 99, 108, 97, 115, //
. - 32, 32, 32, 32, 32, 32, 60, 108, 97, 98, 101, 108, // . - 32, 32, 32, 32, 32, 32, 32, 60, 105, 110, 112, 117, // . < - 47, 100, 105, 118, 62, 60, 100, 105, 118, 32, 99, 108, // /div>
. - 32, 32, 32, 32, 32, 32, 32, 32, 60, 108, 97, 98, // UART RX - 32, 112, 105, 110, 60, 47, 108, 97, 98, 101, 108, 62, // pin - 10, 32, 32, 32, 32, 32, 32, 32, 32, 60, 105, 110, // . . - 32, 60, 47, 100, 105, 118, 62, 60, 100, 105, 118, 32, //
. UART - 66, 97, 117, 100, 60, 47, 108, 97, 98, 101, 108, 62, // Baud - 10, 32, 32, 32, 32, 32, 32, 32, 32, 60, 105, 110, // . . - 32, 32, 32, 32, 32, 60, 47, 100, 105, 118, 62, 10, //
. - 32, 32, 32, 32, 60, 47, 100, 105, 118, 62, 10, 32, //
. - 32, 32, 32, 60, 100, 105, 118, 32, 99, 108, 97, 115, //
.

Network con - 102, 105, 103, 117, 114, 97, 116, 105, 111, 110, 60, 47, // figuration. . - 32, 32, 32, 32, 32, 32, 32, 32, 60, 108, 97, 98, // Local T - 67, 80, 32, 112, 111, 114, 116, 60, 47, 108, 97, 98, // CP port. - 60, 105, 110, 112, 117, 116, 32, 115, 116, 121, 108, 101, // . enabl - 101, 60, 47, 108, 97, 98, 101, 108, 62, 10, 32, 32, // e. - 32, 32, 32, 32, 60, 47, 100, 105, 118, 62, 60, 100, //

. - 32, 32, 32, 32, 32, 32, 32, 32, 60, 108, 97, 98, // Local W - 83, 32, 112, 111, 114, 116, 60, 47, 108, 97, 98, 101, // S port. < - 105, 110, 112, 117, 116, 32, 115, 116, 121, 108, 101, 61, // input style= - 34, 102, 108, 101, 120, 58, 32, 49, 32, 49, 48, 48, // "flex: 1 100 - 37, 59, 34, 10, 32, 32, 32, 32, 32, 32, 32, 32, // %;". - 32, 32, 118, 97, 108, 117, 101, 61, 36, 123, 103, 101, // value=${ge - 116, 112, 111, 114, 116, 40, 99, 102, 103, 46, 119, 115, // tport(cfg.ws - 46, 117, 114, 108, 44, 32, 52, 48, 48, 50, 41, 125, // .url, 4002)} - 32, 111, 110, 99, 104, 97, 110, 103, 101, 61, 36, 123, // onchange=${ - 111, 110, 99, 104, 97, 110, 103, 101, 125, 10, 32, 32, // onchange}. - 32, 32, 32, 32, 32, 32, 32, 32, 111, 110, 105, 110, // onin - 112, 117, 116, 61, 36, 123, 115, 101, 116, 87, 115, 85, // put=${setWsU - 114, 108, 125, 32, 47, 62, 10, 32, 32, 32, 32, 32, // rl} />. - 32, 32, 32, 60, 108, 97, 98, 101, 108, 32, 99, 108, // - 10, 32, 32, 32, 32, 32, 32, 60, 47, 100, 105, 118, // .
. < - 108, 97, 98, 101, 108, 32, 99, 108, 97, 115, 115, 61, // label class= - 34, 97, 100, 100, 111, 110, 34, 62, 82, 101, 109, 111, // "addon">Remo - 116, 101, 32, 77, 81, 84, 84, 60, 47, 108, 97, 98, // te MQTT. - 60, 105, 110, 112, 117, 116, 32, 115, 116, 121, 108, 101, // . - 32, 32, 32, 32, 32, 60, 108, 97, 98, 101, 108, 32, //
. - 60, 47, 100, 105, 118, 62, 10, 32, 32, 60, 47, 100, //
. ..
- 10, 32, 32, 32, 32, 78, 111, 116, 101, 58, 32, 116, // . Note: t - 111, 32, 99, 111, 110, 110, 101, 99, 116, 32, 111, 118, // o connect ov - 101, 114, 32, 77, 81, 84, 84, 44, 32, 10, 32, 32, // er MQTT, . - 32, 32, 32, 32, 111, 112, 101, 110, 32, 60, 97, 32, // open . - 32, 32, 99, 111, 110, 115, 111, 108, 101, 60, 47, 97, // console, subscribe - 32, 116, 111, 32, 98, 47, 116, 120, 32, 97, 110, 100, // to b/tx and - 32, 112, 117, 98, 108, 105, 115, 104, 32, 116, 111, 32, // publish to - 98, 47, 114, 120, 60, 98, 114, 47, 62, 10, 32, 32, // b/rx
. - 32, 32, 78, 111, 116, 101, 58, 32, 116, 111, 32, 99, // Note: to c - 111, 110, 110, 101, 99, 116, 32, 111, 118, 101, 114, 32, // onnect over - 84, 67, 80, 44, 32, 117, 115, 101, 32, 110, 101, 116, // TCP, use net - 99, 97, 116, 32, 117, 116, 105, 108, 105, 116, 121, 58, // cat utility: - 60, 98, 114, 47, 62, 10, 32, 32, 32, 32, 36, 32, //
. $ - 110, 99, 32, 36, 123, 108, 111, 99, 97, 116, 105, 111, // nc ${locatio - 110, 46, 104, 111, 115, 116, 110, 97, 109, 101, 125, 32, // n.hostname} - 36, 123, 103, 101, 116, 112, 111, 114, 116, 40, 99, 102, // ${getport(cf - 103, 46, 116, 99, 112, 46, 117, 114, 108, 44, 32, 52, // g.tcp.url, 4 - 48, 48, 49, 41, 125, 10, 32, 32, 60, 47, 100, 105, // 001)}. ..
- 10, 32, 32, 32, 32, 60, 98, 62, 85, 65, 82, 84, // . UART - 32, 99, 111, 110, 115, 111, 108, 101, 60, 47, 98, 62, // console - 60, 115, 112, 97, 110, 32, 115, 116, 121, 108, 101, 61, // wor - 107, 115, 32, 10, 32, 32, 32, 32, 111, 118, 101, 114, // ks . over - 32, 116, 104, 101, 32, 108, 111, 99, 97, 108, 32, 87, // the local W - 83, 32, 112, 111, 114, 116, 46, 32, 87, 101, 98, 83, // S port. WebS - 111, 99, 107, 101, 116, 32, 115, 116, 97, 116, 117, 115, // ocket status - 58, 32, 60, 47, 115, 112, 97, 110, 62, 60, 115, 112, // : . - 32, 32, 92, 117, 50, 53, 99, 102, 32, 36, 123, 99, // .u25cf ${c - 111, 110, 110, 101, 99, 116, 101, 100, 32, 63, 32, 39, // onnected ? ' - 99, 111, 110, 110, 101, 99, 116, 101, 100, 39, 32, 58, // connected' : - 32, 39, 100, 105, 115, 99, 111, 110, 110, 101, 99, 116, // 'disconnect - 101, 100, 39, 125, 32, 60, 47, 115, 112, 97, 110, 62, // ed'} - 10, 32, 32, 60, 47, 100, 105, 118, 62, 10, 32, 32, // .
. - 60, 100, 105, 118, 32, 115, 116, 121, 108, 101, 61, 34, //
. - 32, 60, 105, 110, 112, 117, 116, 32, 112, 108, 97, 99, // setTxt(ev - 46, 116, 97, 114, 103, 101, 116, 46, 118, 97, 108, 117, // .target.valu - 101, 41, 125, 32, 47, 62, 10, 32, 32, 32, 32, 60, // e)} />. < - 98, 117, 116, 116, 111, 110, 32, 115, 116, 121, 108, 101, // button style - 61, 34, 109, 97, 114, 103, 105, 110, 45, 108, 101, 102, // ="margin-lef - 116, 58, 32, 49, 101, 109, 59, 34, 10, 32, 32, 32, // t: 1em;". - 32, 32, 32, 111, 110, 99, 108, 105, 99, 107, 61, 36, // onclick=$ - 123, 101, 118, 32, 61, 62, 32, 115, 101, 116, 77, 101, // {ev => setMe - 115, 115, 97, 103, 101, 115, 40, 91, 93, 41, 125, 62, // ssages([])}> - 99, 108, 101, 97, 114, 60, 47, 98, 117, 116, 116, 111, // clear.
. - 32, 32, 60, 112, 114, 101, 32, 115, 116, 121, 108, 101, //
.  
-  32,  32,  36, 123, 109, 101, 115, 115,  97, 103, 101, 115, //   ${messages
-  46, 109,  97, 112,  40, 109, 101, 115, 115,  97, 103, 101, // .map(message
-  32,  61,  62,  32, 104,  40,  77, 101, 115, 115,  97, 103, //  => h(Messag
- 101,  44,  32, 123, 109, 101, 115, 115,  97, 103, 101, 125, // e, {message}
-  41,  41, 125,  10,  32,  32,  60,  47, 112, 114, 101,  62, // ))}.  
- 10, 10, 60, 47, 100, 105, 118, 62, 96, 59, 10, 125, // ..
`;.} - 59, 10, 10, 119, 105, 110, 100, 111, 119, 46, 111, 110, // ;..window.on - 108, 111, 97, 100, 32, 61, 32, 40, 41, 32, 61, 62, // load = () => - 32, 114, 101, 110, 100, 101, 114, 40, 104, 40, 65, 112, // render(h(Ap - 112, 41, 44, 32, 100, 111, 99, 117, 109, 101, 110, 116, // p), document - 46, 98, 111, 100, 121, 41, 59, 10, 0 // .body);. -}; static const struct packed_file { const char *name; @@ -1812,10 +1812,10 @@ static const struct packed_file { size_t size; time_t mtime; } packed_files[] = { - {"/web_root/index.html", v1, sizeof(v1), 1655487950}, - {"/web_root/preact.min.js", v2, sizeof(v2), 1655487950}, - {"/web_root/style.css", v3, sizeof(v3), 1655749961}, - {"/web_root/main.js", v4, sizeof(v4), 1658950918}, + {"/web_root/index.html", v1, sizeof(v1), 1654623573}, + {"/web_root/main.js", v2, sizeof(v2), 1659000445}, + {"/web_root/preact.min.js", v3, sizeof(v3), 1654623573}, + {"/web_root/style.css", v4, sizeof(v4), 1655548336}, {NULL, NULL, 0, 0} }; diff --git a/mongoose.c b/mongoose.c index c5f0f103..e67959cc 100644 --- a/mongoose.c +++ b/mongoose.c @@ -2470,7 +2470,9 @@ static int mg_pass_string(const char *s, int len) { return MG_JSON_INVALID; } -int mg_json_get(const char *s, int len, const char *path, int *toklen) { +int mg_json_get(struct mg_str json, const char *path, int *toklen) { + const char *s = json.ptr; + int len = (int) json.len; enum { S_VALUE, S_KEY, S_COLON, S_COMMA_OR_EOO } expecting = S_VALUE; unsigned char nesting[MG_JSON_MAX_DEPTH]; int i, j = 0, depth = 0; @@ -2607,7 +2609,7 @@ int mg_json_get(const char *s, int len, const char *path, int *toklen) { bool mg_json_get_num(struct mg_str json, const char *path, double *v) { int n, toklen, found = 0; - if ((n = mg_json_get(json.ptr, (int) json.len, path, &toklen)) >= 0 && + if ((n = mg_json_get(json, path, &toklen)) >= 0 && (json.ptr[n] == '-' || (json.ptr[n] >= '0' && json.ptr[n] <= '9'))) { if (v != NULL) *v = mg_atod(json.ptr + n, toklen, NULL); found = 1; @@ -2616,10 +2618,9 @@ bool mg_json_get_num(struct mg_str json, const char *path, double *v) { } bool mg_json_get_bool(struct mg_str json, const char *path, bool *v) { - int n, toklen, found = 0; - if ((n = mg_json_get(json.ptr, (int) json.len, path, &toklen)) >= 0 && - (json.ptr[n] == 't' || json.ptr[n] == 'f')) { - if (v != NULL) *v = json.ptr[n] == 't'; + int found = 0, off = mg_json_get(json, path, NULL); + if (off >= 0 && (json.ptr[off] == 't' || json.ptr[off] == 'f')) { + if (v != NULL) *v = json.ptr[off] == 't'; found = 1; } return found; @@ -2651,13 +2652,12 @@ static bool json_unescape(const char *s, size_t len, char *to, size_t n) { } char *mg_json_get_str(struct mg_str json, const char *path) { - int n, toklen; char *result = NULL; - if ((n = mg_json_get(json.ptr, (int) json.len, path, &toklen)) >= 0 && - json.ptr[n] == '"') { - if ((result = (char *) calloc(1, (size_t) toklen)) != NULL && - !json_unescape(json.ptr + n + 1, (size_t) (toklen - 2), result, - (size_t) toklen)) { + int len = 0, off = mg_json_get(json, path, &len); + if (off >= 0 && len > 1 && json.ptr[off] == '"') { + if ((result = (char *) calloc(1, (size_t) len)) != NULL && + !json_unescape(json.ptr + off + 1, (size_t) (len - 2), result, + (size_t) len)) { free(result); result = NULL; } @@ -2665,27 +2665,25 @@ char *mg_json_get_str(struct mg_str json, const char *path) { return result; } -char *mg_json_get_b64(struct mg_str json, const char *path, int *len) { - int n, toklen; +char *mg_json_get_b64(struct mg_str json, const char *path, int *slen) { char *result = NULL; - if ((n = mg_json_get(json.ptr, (int) json.len, path, &toklen)) >= 0 && - json.ptr[n] == '"' && toklen > 1 && - (result = (char *) calloc(1, (size_t) toklen)) != NULL) { - int k = mg_base64_decode(json.ptr + n + 1, toklen - 2, result); - if (len != NULL) *len = k; + int len = 0, off = mg_json_get(json, path, &len); + if (off >= 0 && json.ptr[off] == '"' && len > 1 && + (result = (char *) calloc(1, (size_t) len)) != NULL) { + int k = mg_base64_decode(json.ptr + off + 1, len - 2, result); + if (slen != NULL) *slen = k; } return result; } -char *mg_json_get_hex(struct mg_str json, const char *path, int *len) { - int n, toklen; +char *mg_json_get_hex(struct mg_str json, const char *path, int *slen) { char *result = NULL; - if ((n = mg_json_get(json.ptr, (int) json.len, path, &toklen)) >= 0 && - json.ptr[n] == '"' && toklen > 1 && - (result = (char *) calloc(1, (size_t) toklen / 2)) != NULL) { - mg_unhex(json.ptr + n + 1, (size_t) (toklen - 2), (uint8_t *) result); - result[(toklen - 2) / 2] = '\0'; - if (len != NULL) *len = (toklen - 2) / 2; + int len = 0, off = mg_json_get(json, path, &len); + if (off >= 0 && json.ptr[off] == '"' && len > 1 && + (result = (char *) calloc(1, (size_t) len / 2)) != NULL) { + mg_unhex(json.ptr + off + 1, (size_t) (len - 2), (uint8_t *) result); + result[len / 2 - 1] = '\0'; + if (slen != NULL) *slen = len / 2 - 1; } return result; } @@ -3584,26 +3582,25 @@ void mg_rpc_free(void **head) { } } -void mg_rpc_process(void **head, struct mg_str s, mg_pfn_t pfn, void *pfnd) { - struct mg_rpc_req req = {{s.ptr, s.len}, pfn, pfnd, NULL}; - int len, off = mg_json_get(s.ptr, (int) s.len, "$.method", &len); - if (off > 0 && s.ptr[off] == '"') { - struct mg_str m = mg_str_n(&s.ptr[off + 1], (size_t) len - 2); - struct mg_rpc *h = *(struct mg_rpc **) head; +void mg_rpc_process(struct mg_rpc_req *r) { + int len, off = mg_json_get(r->frame, "$.method", &len); + if (off > 0 && r->frame.ptr[off] == '"') { + struct mg_str m = mg_str_n(&r->frame.ptr[off + 1], (size_t) len - 2); + struct mg_rpc *h = *(struct mg_rpc **) r->head; while (h != NULL && !mg_match(m, h->method, NULL)) h = h->next; if (h != NULL) { - req.fn_data = h->fn_data; - h->fn(&req); + r->handler_data = h->fn_data; + h->fn(r); } else { - mg_rpc_err(&req, -32601, "\"%.*s not found\"", (int) m.len, m.ptr); + mg_rpc_err(r, -32601, "\"%.*s not found\"", (int) m.len, m.ptr); } } else { - mg_rpc_err(&req, -32700, "%.*Q", (int) s.len, s.ptr); + mg_rpc_err(r, -32700, "%.*Q", (int) r->frame.len, r->frame.ptr); } } void mg_rpc_vok(struct mg_rpc_req *r, const char *fmt, va_list *ap) { - int len, off = mg_json_get(r->frame.ptr, (int) r->frame.len, "$.id", &len); + int len, off = mg_json_get(r->frame, "$.id", &len); if (off > 0) { mg_rprintf(r->pfn, r->pfn_data, "{%Q:%.*s,%Q:", "id", len, &r->frame.ptr[off], "result"); @@ -3620,7 +3617,7 @@ void mg_rpc_ok(struct mg_rpc_req *r, const char *fmt, ...) { } void mg_rpc_verr(struct mg_rpc_req *r, int code, const char *fmt, va_list *ap) { - int len, off = mg_json_get(r->frame.ptr, (int) r->frame.len, "$.id", &len); + int len, off = mg_json_get(r->frame, "$.id", &len); mg_rprintf(r->pfn, r->pfn_data, "{"); if (off > 0) { mg_rprintf(r->pfn, r->pfn_data, "%Q:%.*s,", "id", len, &r->frame.ptr[off]); @@ -3649,7 +3646,7 @@ static size_t print_methods(mg_pfn_t pfn, void *pfn_data, va_list *ap) { } void mg_rpc_list(struct mg_rpc_req *r) { - mg_rpc_ok(r, "[%M]", print_methods, r->fn_data); + mg_rpc_ok(r, "[%M]", print_methods, r->head); } #ifdef MG_ENABLE_LINES diff --git a/mongoose.h b/mongoose.h index f918ccba..89c028e9 100644 --- a/mongoose.h +++ b/mongoose.h @@ -1350,7 +1350,7 @@ size_t mg_dns_parse_rr(const uint8_t *buf, size_t len, size_t ofs, // Error return values - negative. Successful returns are >= 0 enum { MG_JSON_TOO_DEEP = -1, MG_JSON_INVALID = -2, MG_JSON_NOT_FOUND = -3 }; -int mg_json_get(const char *buf, int len, const char *path, int *toklen); +int mg_json_get(struct mg_str json, const char *path, int *toklen); bool mg_json_get_num(struct mg_str json, const char *path, double *v); bool mg_json_get_bool(struct mg_str json, const char *path, bool *v); @@ -1364,16 +1364,18 @@ char *mg_json_get_b64(struct mg_str json, const char *path, int *len); // JSON-RPC request descriptor struct mg_rpc_req { - struct mg_str frame; // Request, e.g. {"id":1,"method":"add","params":[1,2]} + void **head; // List of all RPC handlers mg_pfn_t pfn; // Response printing function void *pfn_data; // Response printing function data - void *fn_data; // Endpoint handler data + void *handler_data; // Endpoint handler data + void *process_data; // Arbitrary user data + struct mg_str frame; // Request, e.g. {"id":1,"method":"add","params":[1,2]} }; void mg_rpc_add(void **head, struct mg_str method_pattern, void (*handler)(struct mg_rpc_req *), void *handler_data); void mg_rpc_free(void **head); -void mg_rpc_process(void **head, struct mg_str json, mg_pfn_t pfn, void *pfnd); +void mg_rpc_process(struct mg_rpc_req *); // Helper functions to print result or error frame void mg_rpc_ok(struct mg_rpc_req *, const char *fmt, ...); diff --git a/src/json.c b/src/json.c index 28c45274..4ad53450 100644 --- a/src/json.c +++ b/src/json.c @@ -28,7 +28,9 @@ static int mg_pass_string(const char *s, int len) { return MG_JSON_INVALID; } -int mg_json_get(const char *s, int len, const char *path, int *toklen) { +int mg_json_get(struct mg_str json, const char *path, int *toklen) { + const char *s = json.ptr; + int len = (int) json.len; enum { S_VALUE, S_KEY, S_COLON, S_COMMA_OR_EOO } expecting = S_VALUE; unsigned char nesting[MG_JSON_MAX_DEPTH]; int i, j = 0, depth = 0; @@ -165,7 +167,7 @@ int mg_json_get(const char *s, int len, const char *path, int *toklen) { bool mg_json_get_num(struct mg_str json, const char *path, double *v) { int n, toklen, found = 0; - if ((n = mg_json_get(json.ptr, (int) json.len, path, &toklen)) >= 0 && + if ((n = mg_json_get(json, path, &toklen)) >= 0 && (json.ptr[n] == '-' || (json.ptr[n] >= '0' && json.ptr[n] <= '9'))) { if (v != NULL) *v = mg_atod(json.ptr + n, toklen, NULL); found = 1; @@ -174,10 +176,9 @@ bool mg_json_get_num(struct mg_str json, const char *path, double *v) { } bool mg_json_get_bool(struct mg_str json, const char *path, bool *v) { - int n, toklen, found = 0; - if ((n = mg_json_get(json.ptr, (int) json.len, path, &toklen)) >= 0 && - (json.ptr[n] == 't' || json.ptr[n] == 'f')) { - if (v != NULL) *v = json.ptr[n] == 't'; + int found = 0, off = mg_json_get(json, path, NULL); + if (off >= 0 && (json.ptr[off] == 't' || json.ptr[off] == 'f')) { + if (v != NULL) *v = json.ptr[off] == 't'; found = 1; } return found; @@ -209,13 +210,12 @@ static bool json_unescape(const char *s, size_t len, char *to, size_t n) { } char *mg_json_get_str(struct mg_str json, const char *path) { - int n, toklen; char *result = NULL; - if ((n = mg_json_get(json.ptr, (int) json.len, path, &toklen)) >= 0 && - json.ptr[n] == '"') { - if ((result = (char *) calloc(1, (size_t) toklen)) != NULL && - !json_unescape(json.ptr + n + 1, (size_t) (toklen - 2), result, - (size_t) toklen)) { + int len = 0, off = mg_json_get(json, path, &len); + if (off >= 0 && len > 1 && json.ptr[off] == '"') { + if ((result = (char *) calloc(1, (size_t) len)) != NULL && + !json_unescape(json.ptr + off + 1, (size_t) (len - 2), result, + (size_t) len)) { free(result); result = NULL; } @@ -223,27 +223,25 @@ char *mg_json_get_str(struct mg_str json, const char *path) { return result; } -char *mg_json_get_b64(struct mg_str json, const char *path, int *len) { - int n, toklen; +char *mg_json_get_b64(struct mg_str json, const char *path, int *slen) { char *result = NULL; - if ((n = mg_json_get(json.ptr, (int) json.len, path, &toklen)) >= 0 && - json.ptr[n] == '"' && toklen > 1 && - (result = (char *) calloc(1, (size_t) toklen)) != NULL) { - int k = mg_base64_decode(json.ptr + n + 1, toklen - 2, result); - if (len != NULL) *len = k; + int len = 0, off = mg_json_get(json, path, &len); + if (off >= 0 && json.ptr[off] == '"' && len > 1 && + (result = (char *) calloc(1, (size_t) len)) != NULL) { + int k = mg_base64_decode(json.ptr + off + 1, len - 2, result); + if (slen != NULL) *slen = k; } return result; } -char *mg_json_get_hex(struct mg_str json, const char *path, int *len) { - int n, toklen; +char *mg_json_get_hex(struct mg_str json, const char *path, int *slen) { char *result = NULL; - if ((n = mg_json_get(json.ptr, (int) json.len, path, &toklen)) >= 0 && - json.ptr[n] == '"' && toklen > 1 && - (result = (char *) calloc(1, (size_t) toklen / 2)) != NULL) { - mg_unhex(json.ptr + n + 1, (size_t) (toklen - 2), (uint8_t *) result); - result[(toklen - 2) / 2] = '\0'; - if (len != NULL) *len = (toklen - 2) / 2; + int len = 0, off = mg_json_get(json, path, &len); + if (off >= 0 && json.ptr[off] == '"' && len > 1 && + (result = (char *) calloc(1, (size_t) len / 2)) != NULL) { + mg_unhex(json.ptr + off + 1, (size_t) (len - 2), (uint8_t *) result); + result[len / 2 - 1] = '\0'; + if (slen != NULL) *slen = len / 2 - 1; } return result; } diff --git a/src/json.h b/src/json.h index b5d1161e..43955e7e 100644 --- a/src/json.h +++ b/src/json.h @@ -9,7 +9,7 @@ // Error return values - negative. Successful returns are >= 0 enum { MG_JSON_TOO_DEEP = -1, MG_JSON_INVALID = -2, MG_JSON_NOT_FOUND = -3 }; -int mg_json_get(const char *buf, int len, const char *path, int *toklen); +int mg_json_get(struct mg_str json, const char *path, int *toklen); bool mg_json_get_num(struct mg_str json, const char *path, double *v); bool mg_json_get_bool(struct mg_str json, const char *path, bool *v); diff --git a/src/rpc.c b/src/rpc.c index e894c7be..03d6951a 100644 --- a/src/rpc.c +++ b/src/rpc.c @@ -23,26 +23,25 @@ void mg_rpc_free(void **head) { } } -void mg_rpc_process(void **head, struct mg_str s, mg_pfn_t pfn, void *pfnd) { - struct mg_rpc_req req = {{s.ptr, s.len}, pfn, pfnd, NULL}; - int len, off = mg_json_get(s.ptr, (int) s.len, "$.method", &len); - if (off > 0 && s.ptr[off] == '"') { - struct mg_str m = mg_str_n(&s.ptr[off + 1], (size_t) len - 2); - struct mg_rpc *h = *(struct mg_rpc **) head; +void mg_rpc_process(struct mg_rpc_req *r) { + int len, off = mg_json_get(r->frame, "$.method", &len); + if (off > 0 && r->frame.ptr[off] == '"') { + struct mg_str m = mg_str_n(&r->frame.ptr[off + 1], (size_t) len - 2); + struct mg_rpc *h = *(struct mg_rpc **) r->head; while (h != NULL && !mg_match(m, h->method, NULL)) h = h->next; if (h != NULL) { - req.fn_data = h->fn_data; - h->fn(&req); + r->handler_data = h->fn_data; + h->fn(r); } else { - mg_rpc_err(&req, -32601, "\"%.*s not found\"", (int) m.len, m.ptr); + mg_rpc_err(r, -32601, "\"%.*s not found\"", (int) m.len, m.ptr); } } else { - mg_rpc_err(&req, -32700, "%.*Q", (int) s.len, s.ptr); + mg_rpc_err(r, -32700, "%.*Q", (int) r->frame.len, r->frame.ptr); } } void mg_rpc_vok(struct mg_rpc_req *r, const char *fmt, va_list *ap) { - int len, off = mg_json_get(r->frame.ptr, (int) r->frame.len, "$.id", &len); + int len, off = mg_json_get(r->frame, "$.id", &len); if (off > 0) { mg_rprintf(r->pfn, r->pfn_data, "{%Q:%.*s,%Q:", "id", len, &r->frame.ptr[off], "result"); @@ -59,7 +58,7 @@ void mg_rpc_ok(struct mg_rpc_req *r, const char *fmt, ...) { } void mg_rpc_verr(struct mg_rpc_req *r, int code, const char *fmt, va_list *ap) { - int len, off = mg_json_get(r->frame.ptr, (int) r->frame.len, "$.id", &len); + int len, off = mg_json_get(r->frame, "$.id", &len); mg_rprintf(r->pfn, r->pfn_data, "{"); if (off > 0) { mg_rprintf(r->pfn, r->pfn_data, "%Q:%.*s,", "id", len, &r->frame.ptr[off]); @@ -88,5 +87,5 @@ static size_t print_methods(mg_pfn_t pfn, void *pfn_data, va_list *ap) { } void mg_rpc_list(struct mg_rpc_req *r) { - mg_rpc_ok(r, "[%M]", print_methods, r->fn_data); + mg_rpc_ok(r, "[%M]", print_methods, r->head); } diff --git a/src/rpc.h b/src/rpc.h index b16ae7e4..c066a18c 100644 --- a/src/rpc.h +++ b/src/rpc.h @@ -4,16 +4,18 @@ // JSON-RPC request descriptor struct mg_rpc_req { - struct mg_str frame; // Request, e.g. {"id":1,"method":"add","params":[1,2]} + void **head; // List of all RPC handlers mg_pfn_t pfn; // Response printing function void *pfn_data; // Response printing function data - void *fn_data; // Endpoint handler data + void *handler_data; // Endpoint handler data + void *process_data; // Arbitrary user data + struct mg_str frame; // Request, e.g. {"id":1,"method":"add","params":[1,2]} }; void mg_rpc_add(void **head, struct mg_str method_pattern, void (*handler)(struct mg_rpc_req *), void *handler_data); void mg_rpc_free(void **head); -void mg_rpc_process(void **head, struct mg_str json, mg_pfn_t pfn, void *pfnd); +void mg_rpc_process(struct mg_rpc_req *); // Helper functions to print result or error frame void mg_rpc_ok(struct mg_rpc_req *, const char *fmt, ...); diff --git a/test/fuzz.c b/test/fuzz.c index 2baaaeea..b96183ae 100644 --- a/test/fuzz.c +++ b/test/fuzz.c @@ -46,7 +46,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { while (mg_commalist(&s, &k, &v)) k.len = v.len = 0; int n; - mg_json_get((char *) data, (int) size, "$", &n); + mg_json_get(mg_str_n((char *) data, size), "$", &n); return 0; } diff --git a/test/unit_test.c b/test/unit_test.c index 6acd9809..e9917501 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -2315,108 +2315,121 @@ static void test_get_header_var(void) { } static void test_json(void) { - const char *s; const char *s1 = "{\"a\":{},\"b\":7,\"c\":[[],2]}"; const char *s2 = "{\"a\":{\"b1\":{}},\"c\":7,\"d\":{\"b2\":{}}}"; - int n, n1 = (int) strlen(s1), n2 = (int) strlen(s2); + int n; + struct mg_str json; - ASSERT(mg_json_get(" true ", 6, "", &n) == MG_JSON_INVALID); - ASSERT(mg_json_get(" true ", 6, "$", &n) == 1 && n == 4); - ASSERT(mg_json_get("null ", 5, "$", &n) == 0 && n == 4); - s = " \"hi\\nthere\""; - ASSERT(mg_json_get(s, (int) strlen(s), "$", &n) == 2 && n == 11); - ASSERT(mg_json_get(" { } ", 5, "$", &n) == 1); - ASSERT(mg_json_get(" [[]]", 5, "$", &n) == 1); - ASSERT(mg_json_get(" [ ] ", 5, "$", &n) == 1); + ASSERT(mg_json_get(mg_str_n(" true ", 6), "", &n) == MG_JSON_INVALID); + ASSERT(mg_json_get(mg_str_n(" true ", 6), "$", &n) == 1 && n == 4); + ASSERT(mg_json_get(mg_str_n("null ", 5), "$", &n) == 0 && n == 4); + json = mg_str(" \"hi\\nthere\""); + ASSERT(mg_json_get(json, "$", &n) == 2 && n == 11); + ASSERT(mg_json_get(mg_str_n(" { } ", 5), "$", &n) == 1); + ASSERT(mg_json_get(mg_str_n(" [[]]", 5), "$", &n) == 1); + ASSERT(mg_json_get(mg_str_n(" [ ] ", 5), "$", &n) == 1); - ASSERT(mg_json_get("[1,2]", 5, "$", &n) == 0 && n == 5); - ASSERT(mg_json_get("[1,2]", 5, "$[0]", &n) == 1 && n == 1); - ASSERT(mg_json_get("[1,2]", 5, "$[1]", &n) == 3 && n == 1); - ASSERT(mg_json_get("[1,2]", 5, "$[3]", &n) == MG_JSON_NOT_FOUND); + ASSERT(mg_json_get(mg_str_n("[1,2]", 5), "$", &n) == 0 && n == 5); + ASSERT(mg_json_get(mg_str_n("[1,2]", 5), "$[0]", &n) == 1 && n == 1); + ASSERT(mg_json_get(mg_str_n("[1,2]", 5), "$[1]", &n) == 3 && n == 1); + ASSERT(mg_json_get(mg_str_n("[1,2]", 5), "$[3]", &n) == MG_JSON_NOT_FOUND); - s = "{\"a\":[]}"; - ASSERT(mg_json_get(s, (int) strlen(s), "$.a", &n) == 5); - s = "{\"a\":[1,2]}"; - ASSERT(mg_json_get(s, (int) strlen(s), "$.a", &n) == 5); - s = "{\"a\":[1,[1]]}"; - ASSERT(mg_json_get(s, (int) strlen(s), "$.a", &n) == 5); - s = "{\"a\":[[]]}"; - ASSERT(mg_json_get(s, (int) strlen(s), "$.a", &n) == 5); - s = "{\"a\":[[1,2]]}"; - ASSERT(mg_json_get(s, (int) strlen(s), "$.a", &n) == 5); - s = "{\"a\":{}}"; - ASSERT(mg_json_get(s, (int) strlen(s), "$.a", &n) == 5); - s = "{\"a\":{\"a\":{}}}"; - ASSERT(mg_json_get(s, (int) strlen(s), "$.a", &n) == 5); - s = "{\"a\":{\"a\":[]}}"; - ASSERT(mg_json_get(s, (int) strlen(s), "$.a", &n) == 5); + json = mg_str("{\"a\":[]}"); + ASSERT(mg_json_get(json, "$.a", &n) == 5); + json = mg_str("{\"a\":[1,2]}"); + ASSERT(mg_json_get(json, "$.a", &n) == 5); + json = mg_str("{\"a\":[1,[1]]}"); + ASSERT(mg_json_get(json, "$.a", &n) == 5); + json = mg_str("{\"a\":[[]]}"); + ASSERT(mg_json_get(json, "$.a", &n) == 5); + json = mg_str("{\"a\":[[1,2]]}"); + ASSERT(mg_json_get(json, "$.a", &n) == 5); + json = mg_str("{\"a\":{}}"); + ASSERT(mg_json_get(json, "$.a", &n) == 5); + json = mg_str("{\"a\":{\"a\":{}}}"); + ASSERT(mg_json_get(json, "$.a", &n) == 5); + json = mg_str("{\"a\":{\"a\":[]}}"); + ASSERT(mg_json_get(json, "$.a", &n) == 5); - ASSERT(mg_json_get("[[1,[2,3]],4]", 13, "$", &n) == 0 && n == 13); - ASSERT(mg_json_get("[[1,[2,3]],4]", 13, "$[0]", &n) == 1 && n == 9); - ASSERT(mg_json_get("[[1,[2,3]],4]", 13, "$[1]", &n) == 11); - ASSERT(mg_json_get("[[1,[2,3]],4]", 13, "$[1]", &n) == 11 && n == 1); - ASSERT(mg_json_get("[[1,[2,3]],4]", 13, "$[2]", &n) == MG_JSON_NOT_FOUND); - ASSERT(mg_json_get("[[1,[2,3]],4]", 13, "$[0][0]", &n) == 2 && n == 1); - ASSERT(mg_json_get("[[1,[2,3]],4]", 13, "$[0][1]", &n) == 4 && n == 5); - ASSERT(mg_json_get("[[1,[2,3]],4]", 13, "$[0][2]", &n) == MG_JSON_NOT_FOUND); - ASSERT(mg_json_get("[[1,[2,3]],4]", 13, "$[0][1][0]", &n) == 5 && n == 1); - ASSERT(mg_json_get("[[1,[2,3]],4]", 13, "$[0][1][1]", &n) == 7 && n == 1); + json = mg_str("[[1,[2,3]],4]"); + ASSERT(mg_json_get(json, "$", &n) == 0 && n == 13); + ASSERT(mg_json_get(json, "$[0]", &n) == 1 && n == 9); + ASSERT(mg_json_get(json, "$[1]", &n) == 11); + ASSERT(mg_json_get(json, "$[1]", &n) == 11 && n == 1); + ASSERT(mg_json_get(json, "$[2]", &n) == MG_JSON_NOT_FOUND); + ASSERT(mg_json_get(json, "$[0][0]", &n) == 2 && n == 1); + ASSERT(mg_json_get(json, "$[0][1]", &n) == 4 && n == 5); + ASSERT(mg_json_get(json, "$[0][2]", &n) == MG_JSON_NOT_FOUND); + ASSERT(mg_json_get(json, "$[0][1][0]", &n) == 5 && n == 1); + ASSERT(mg_json_get(json, "$[0][1][1]", &n) == 7 && n == 1); - ASSERT(mg_json_get("[[1,2],3]", 9, "$", &n) == 0 && n == 9); - ASSERT(mg_json_get("[[1,2],3]", 9, "$[0][0]", &n) == 2 && n == 1); - ASSERT(mg_json_get("[[1,2],3]", 9, "$[0][1]", &n) == 4 && n == 1); - ASSERT(mg_json_get("[[1,2],3]", 9, "$[0][2]", &n) == MG_JSON_NOT_FOUND); - ASSERT(mg_json_get("[[1,2],3]", 9, "$[1][0]", &n) == MG_JSON_NOT_FOUND); - ASSERT(mg_json_get("[[1,2],3]", 9, "$[1]", &n) == 7 && n == 1); - ASSERT(mg_json_get("[[1,2],3]", 9, "$[1][0]", &n) == MG_JSON_NOT_FOUND); + json = mg_str("[[1,2],3]"); + ASSERT(mg_json_get(json, "$", &n) == 0 && n == 9); + ASSERT(mg_json_get(json, "$[0][0]", &n) == 2 && n == 1); + ASSERT(mg_json_get(json, "$[0][1]", &n) == 4 && n == 1); + ASSERT(mg_json_get(json, "$[0][2]", &n) == MG_JSON_NOT_FOUND); + ASSERT(mg_json_get(json, "$[1][0]", &n) == MG_JSON_NOT_FOUND); + ASSERT(mg_json_get(json, "$[1]", &n) == 7 && n == 1); + ASSERT(mg_json_get(json, "$[1][0]", &n) == MG_JSON_NOT_FOUND); - ASSERT(mg_json_get("[1,[2,3]]", 9, "$", &n) == 0 && n == 9); - ASSERT(mg_json_get("[1,[2,3]]", 9, "$[0][1]", &n) == MG_JSON_NOT_FOUND); - ASSERT(mg_json_get("[1,[2,3]]", 9, "$[1][0]", &n) == 4 && n == 1); + ASSERT(mg_json_get(json, "$", &n) == 0 && n == 9); + ASSERT(mg_json_get(json, "$[1][0]", &n) == MG_JSON_NOT_FOUND); + ASSERT(mg_json_get(json, "$[0][1]", &n) == 4 && n == 1); - ASSERT(mg_json_get(s1, n1, "$.a", &n) == 5 && n == 2); - ASSERT(mg_json_get(s1, n1, "$.b", &n) == 12 && n == 1); - ASSERT(mg_json_get(s1, n1, "$.c", &n) == 18 && n == 6); - ASSERT(mg_json_get(s1, n1, "$.c[0]", &n) == 19 && n == 2); - ASSERT(mg_json_get(s1, n1, "$.c[1]", &n) == 22 && n == 1); - ASSERT(mg_json_get(s1, n1, "$.c[3]", &n) == MG_JSON_NOT_FOUND); + json = mg_str(s1); + ASSERT(mg_json_get(json, "$.a", &n) == 5 && n == 2); + ASSERT(mg_json_get(json, "$.b", &n) == 12 && n == 1); + ASSERT(mg_json_get(json, "$.c", &n) == 18 && n == 6); + ASSERT(mg_json_get(json, "$.c[0]", &n) == 19 && n == 2); + ASSERT(mg_json_get(json, "$.c[1]", &n) == 22 && n == 1); + ASSERT(mg_json_get(json, "$.c[3]", &n) == MG_JSON_NOT_FOUND); - ASSERT(mg_json_get(s2, n2, "$.a", &n) == 5 && n == 9); - ASSERT(mg_json_get(s2, n2, "$.a.b1", &n) == 11 && n == 2); - ASSERT(mg_json_get(s2, n2, "$.a.b2", &n) == MG_JSON_NOT_FOUND); - ASSERT(mg_json_get(s2, n2, "$.a.b", &n) == MG_JSON_NOT_FOUND); - ASSERT(mg_json_get(s2, n2, "$.a1", &n) == MG_JSON_NOT_FOUND); - ASSERT(mg_json_get(s2, n2, "$.c", &n) == 19 && n == 1); + json = mg_str(s2); + ASSERT(mg_json_get(json, "$.a", &n) == 5 && n == 9); + ASSERT(mg_json_get(json, "$.a.b1", &n) == 11 && n == 2); + ASSERT(mg_json_get(json, "$.a.b2", &n) == MG_JSON_NOT_FOUND); + ASSERT(mg_json_get(json, "$.a.b", &n) == MG_JSON_NOT_FOUND); + ASSERT(mg_json_get(json, "$.a1", &n) == MG_JSON_NOT_FOUND); + ASSERT(mg_json_get(json, "$.c", &n) == 19 && n == 1); { double d = 0; bool b = false; int len; - const char *json = "{\"a\": \"hi\\nthere\",\"b\": [12345, true]}"; - char *str = mg_json_get_str(mg_str(json), "$.a"); + char *str = NULL; + + json = mg_str("{\"a\":\"b\"}"); + str = mg_json_get_str(json, "$.a"); + ASSERT(str != NULL); + // printf("---> [%s]\n", str); + ASSERT(strcmp(str, "b") == 0); + free(str); + + json = mg_str("{\"a\": \"hi\\nthere\",\"b\": [12345, true]}"); + str = mg_json_get_str(json, "$.a"); ASSERT(str != NULL); ASSERT(strcmp(str, "hi\nthere") == 0); free(str); - ASSERT(mg_json_get_long(mg_str(json), "$.foo", -42) == -42); - ASSERT(mg_json_get_long(mg_str(json), "$.b[0]", -42) == 12345); + ASSERT(mg_json_get_long(json, "$.foo", -42) == -42); + ASSERT(mg_json_get_long(json, "$.b[0]", -42) == 12345); - ASSERT(mg_json_get_num(mg_str(json), "$.a", &d) == false); - ASSERT(mg_json_get_num(mg_str(json), "$.c", &d) == false); - ASSERT(mg_json_get_num(mg_str(json), "$.b[0]", &d) == true); + ASSERT(mg_json_get_num(json, "$.a", &d) == false); + ASSERT(mg_json_get_num(json, "$.c", &d) == false); + ASSERT(mg_json_get_num(json, "$.b[0]", &d) == true); ASSERT(d == 12345); - ASSERT(mg_json_get_bool(mg_str(json), "$.b", &b) == false); - ASSERT(mg_json_get_bool(mg_str(json), "$.b[0]", &b) == false); - ASSERT(mg_json_get_bool(mg_str(json), "$.b[1]", &b) == true); + ASSERT(mg_json_get_bool(json, "$.b", &b) == false); + ASSERT(mg_json_get_bool(json, "$.b[0]", &b) == false); + ASSERT(mg_json_get_bool(json, "$.b[1]", &b) == true); ASSERT(b == true); - json = "[\"YWJj\", \"0100026869\"]"; - ASSERT((str = mg_json_get_b64(mg_str(json), "$[0]", &len)) != NULL); + json = mg_str("[\"YWJj\", \"0100026869\"]"); + ASSERT((str = mg_json_get_b64(json, "$[0]", &len)) != NULL); ASSERT(len == 3 && memcmp(str, "abc", (size_t) len) == 0); free(str); - ASSERT((str = mg_json_get_hex(mg_str(json), "$[1]", &len)) != NULL); + ASSERT((str = mg_json_get_hex(json, "$[1]", &len)) != NULL); ASSERT(len == 5 && memcmp(str, "\x01\x00\x02hi", (size_t) len) == 0); free(str); } @@ -2424,46 +2437,43 @@ static void test_json(void) { static void test_rpc(void) { void *head = NULL; - mg_rpc_add(&head, mg_str("rpc.list"), mg_rpc_list, &head); + char *s = NULL; + struct mg_rpc_req req = {&head, mg_pfn_realloc, &s, 0, 0, {0, 0}}; + mg_rpc_add(&head, mg_str("rpc.list"), mg_rpc_list, NULL); { - char *s = NULL; - const char *req = "{\"method\":\"rpc.list\"}"; - mg_rpc_process(&head, mg_str(req), mg_pfn_realloc, &s); + req.frame = mg_str("{\"method\":\"rpc.list\"}"); + mg_rpc_process(&req); ASSERT(s == NULL); } { - char *s = NULL; - const char *req = "{\"id\": 1,\"method\":\"rpc.list\"}"; const char *resp = "{\"id\":1,\"result\":[\"rpc.list\"]}"; - mg_rpc_process(&head, mg_str(req), mg_pfn_realloc, &s); + req.frame = mg_str("{\"id\": 1,\"method\":\"rpc.list\"}"); + mg_rpc_process(&req); MG_INFO(("-> %s", s)); ASSERT(strcmp(s, resp) == 0); - free(s); + free(s), s = NULL; } { - char *s = NULL; - const char *req = "{\"id\": true,\"method\":\"foo\"}"; const char *resp = "{\"id\":true,\"error\":{\"code\":-32601,\"message\":\"foo not " "found\"}}"; - mg_rpc_process(&head, mg_str(req), mg_pfn_realloc, &s); + req.frame = mg_str("{\"id\": true,\"method\":\"foo\"}"); + mg_rpc_process(&req); MG_INFO(("-> %s", s)); ASSERT(strcmp(s, resp) == 0); - free(s); + free(s), s = NULL; } { - char *s = NULL; - const char *req = "haha"; const char *resp = "{\"error\":{\"code\":-32700,\"message\":\"haha\"}}"; - mg_rpc_process(&head, mg_str(req), mg_pfn_realloc, &s); - ASSERT(s != NULL); + req.frame = mg_str("haha"); + mg_rpc_process(&req); MG_INFO(("-> %s", s)); ASSERT(strcmp(s, resp) == 0); - free(s); + free(s), s = NULL; } mg_rpc_free(&head);