common: make json_parse_input API retry friendly.

The jsmn parser is a beautiful piece of code.  In particular, you can parse
part of a string, then continue where you left off.

We don't take advantage of this, however, meaning for large JSON objects
we parse them multiple times before finally having enough to complete.

Expose the parser state and tokens through the API, so the caller can pass
them in repeatedly.  For the moment, every caller is allocates each time
(except the unit tests).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2020-08-20 23:10:32 +09:30
parent f2d0a1d406
commit 3ed03f9c8f
7 changed files with 164 additions and 79 deletions

View File

@@ -85,9 +85,35 @@ const jsmntok_t *json_get_member(const char *buffer, const jsmntok_t tok[],
/* Get index'th array member. */
const jsmntok_t *json_get_arr(const jsmntok_t tok[], size_t index);
/* If input is complete and valid, return tokens. */
jsmntok_t *json_parse_input(const tal_t *ctx,
const char *input, int len, bool *valid);
/* Allocate a starter array of tokens for json_parse_input */
jsmntok_t *toks_alloc(const tal_t *ctx);
/* Reset a token array to reuse it. */
void toks_reset(jsmntok_t *toks);
/**
* json_parse_input: parse and validate JSON.
* @parser: parser initialized with jsmn_init.
* @toks: tallocated array from toks_alloc()
* @input, @len: input string.
* @complete: set to true if the valid JSON is complete, or NULL if must be.
*
* This returns false if the JSON is invalid, true otherwise.
* If it returns true, *@complete indicates that (*@toks)[0] points to a
* valid, complete JSON element. If @complete is NULL, then incomplete
* JSON returns false (i.e. is considered invalid).
*
* *@toks is resized to the complete set of tokens, with a dummy
* terminator (type == -1) at the end.
*
* If it returns true, and *@complete is false, you can append more
* data to @input and call it again (with the same perser) and the parser
* will continue where it left off.
*/
bool json_parse_input(jsmn_parser *parser,
jsmntok_t **toks,
const char *input, int len,
bool *complete);
/* Simplified version of above which parses only a complete, valid
* JSON string */