From 628ae0a15b98ac3ca66e6ed8bcfb50a12eccfd7d Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 20 Aug 2020 23:10:34 +0930 Subject: [PATCH] libplugin: do incremental parsing on lightningd commands. This doesn't make any difference, since lightningd generally sends us short commands (command responses are via the rpc loop, which is already done), but it's harmless. Signed-off-by: Rusty Russell --- plugins/libplugin.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/plugins/libplugin.c b/plugins/libplugin.c index a514153f4..ff26d05dd 100644 --- a/plugins/libplugin.c +++ b/plugins/libplugin.c @@ -40,6 +40,8 @@ struct plugin { /* To read from lightningd */ char *buffer; size_t used, len_read; + jsmn_parser parser; + jsmntok_t *toks; /* To write to lightningd */ struct json_stream **js_arr; @@ -1090,18 +1092,11 @@ static void ld_command_handle(struct plugin *plugin, static bool ld_read_json_one(struct plugin *plugin) { bool complete; - jsmntok_t *toks; struct command *cmd = tal(plugin, struct command); - jsmn_parser parser; - /* FIXME: This could be done more efficiently by storing the - * toks and doing an incremental parse, like lightning-cli - * does. */ - toks = toks_alloc(NULL); - jsmn_init(&parser); - if (!json_parse_input(&parser, &toks, plugin->buffer, plugin->used, + if (!json_parse_input(&plugin->parser, &plugin->toks, + plugin->buffer, plugin->used, &complete)) { - tal_free(toks); plugin_err(plugin, "Failed to parse JSON response '%.*s'", (int)plugin->used, plugin->buffer); return false; @@ -1113,20 +1108,23 @@ static bool ld_read_json_one(struct plugin *plugin) } /* Empty buffer? (eg. just whitespace). */ - if (tal_count(toks) == 1) { + if (tal_count(plugin->toks) == 1) { + toks_reset(plugin->toks); + jsmn_init(&plugin->parser); plugin->used = 0; return false; } /* FIXME: Spark doesn't create proper jsonrpc 2.0! So we don't * check for "jsonrpc" here. */ - ld_command_handle(plugin, cmd, toks); + ld_command_handle(plugin, cmd, plugin->toks); /* Move this object out of the buffer */ - memmove(plugin->buffer, plugin->buffer + toks[0].end, - tal_count(plugin->buffer) - toks[0].end); - plugin->used -= toks[0].end; - tal_free(toks); + memmove(plugin->buffer, plugin->buffer + plugin->toks[0].end, + tal_count(plugin->buffer) - plugin->toks[0].end); + plugin->used -= plugin->toks[0].end; + toks_reset(plugin->toks); + jsmn_init(&plugin->parser); return true; } @@ -1225,6 +1223,8 @@ static struct plugin *new_plugin(const tal_t *ctx, p->js_arr = tal_arr(p, struct json_stream *, 0); p->used = 0; p->len_read = 0; + jsmn_init(&p->parser); + p->toks = toks_alloc(p); /* Async RPC */ p->rpc_buffer = tal_arr(p, char, 64); p->rpc_js_arr = tal_arr(p, struct json_stream *, 0);