json: add json_tok_endswith and json_tok_startswith helpers.

I wanted this for offers, and it's generally useful.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2020-11-25 10:48:44 +10:30
parent 3408f8f998
commit d9586bbde1
3 changed files with 42 additions and 25 deletions

View file

@ -41,6 +41,28 @@ bool json_tok_streq(const char *buffer, const jsmntok_t *tok, const char *str)
return strncmp(buffer + tok->start, str, tok->end - tok->start) == 0; return strncmp(buffer + tok->start, str, tok->end - tok->start) == 0;
} }
bool json_tok_startswith(const char *buffer, const jsmntok_t *tok,
const char *prefix)
{
if (tok->type != JSMN_STRING)
return false;
if (tok->end - tok->start < strlen(prefix))
return false;
return memcmp(buffer + tok->start,
prefix, strlen(prefix)) == 0;
}
bool json_tok_endswith(const char *buffer, const jsmntok_t *tok,
const char *suffix)
{
if (tok->type != JSMN_STRING)
return false;
if (tok->end - tok->start < strlen(suffix))
return false;
return memcmp(buffer + tok->end - strlen(suffix),
suffix, strlen(suffix)) == 0;
}
char *json_strdup(const tal_t *ctx, const char *buffer, const jsmntok_t *tok) char *json_strdup(const tal_t *ctx, const char *buffer, const jsmntok_t *tok)
{ {
return tal_strndup(ctx, buffer + tok->start, tok->end - tok->start); return tal_strndup(ctx, buffer + tok->start, tok->end - tok->start);

View file

@ -26,6 +26,14 @@ int json_tok_full_len(const jsmntok_t *t);
/* Is this a string equal to str? */ /* Is this a string equal to str? */
bool json_tok_streq(const char *buffer, const jsmntok_t *tok, const char *str); bool json_tok_streq(const char *buffer, const jsmntok_t *tok, const char *str);
/* Does this string token start with prefix? */
bool json_tok_startswith(const char *buffer, const jsmntok_t *tok,
const char *prefix);
/* Does this string token end with suffix? */
bool json_tok_endswith(const char *buffer, const jsmntok_t *tok,
const char *suffix);
/* Allocate a tal string copy */ /* Allocate a tal string copy */
char *json_strdup(const tal_t *ctx, const char *buffer, const jsmntok_t *tok); char *json_strdup(const tal_t *ctx, const char *buffer, const jsmntok_t *tok);

View file

@ -313,41 +313,28 @@ struct command_result *param_feerate_val(struct command *cmd,
const jsmntok_t *tok, const jsmntok_t *tok,
u32 **feerate_per_kw) u32 **feerate_per_kw)
{ {
jsmntok_t base = *tok, suffix = *tok; jsmntok_t base = *tok;
enum feerate_style style; enum feerate_style style;
unsigned int num; unsigned int num;
/* We have to split the number and suffix. */ if (json_tok_endswith(buffer, tok,
suffix.start = suffix.end; feerate_style_name(FEERATE_PER_KBYTE))) {
while (suffix.start > base.start && !isdigit(buffer[suffix.start-1])) { style = FEERATE_PER_KBYTE;
suffix.start--; base.end -= strlen(feerate_style_name(FEERATE_PER_KBYTE));
base.end--; } else if (json_tok_endswith(buffer, tok,
} feerate_style_name(FEERATE_PER_KSIPA))) {
style = FEERATE_PER_KSIPA;
base.end -= strlen(feerate_style_name(FEERATE_PER_KSIPA));
} else
style = FEERATE_PER_KBYTE;
if (!json_to_number(buffer, &base, &num)) { if (!json_to_number(buffer, &base, &num)) {
return command_fail(cmd, JSONRPC2_INVALID_PARAMS, return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"'%s' prefix should be an integer, not '%.*s'", "'%s' should be an integer with optional perkw/perkb, not '%.*s'",
name, base.end - base.start, name, base.end - base.start,
buffer + base.start); buffer + base.start);
} }
if (suffix.end == suffix.start
|| json_tok_streq(buffer, &suffix,
feerate_style_name(FEERATE_PER_KBYTE))) {
style = FEERATE_PER_KBYTE;
} else if (json_tok_streq(buffer, &suffix,
feerate_style_name(FEERATE_PER_KSIPA))) {
style = FEERATE_PER_KSIPA;
} else {
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"'%s' suffix should be '%s' or '%s', not '%.*s'",
name,
feerate_style_name(FEERATE_PER_KSIPA),
feerate_style_name(FEERATE_PER_KBYTE),
suffix.end - suffix.start,
buffer + suffix.start);
}
*feerate_per_kw = tal(cmd, u32); *feerate_per_kw = tal(cmd, u32);
**feerate_per_kw = feerate_from_style(num, style); **feerate_per_kw = feerate_from_style(num, style);
if (**feerate_per_kw < FEERATE_FLOOR) if (**feerate_per_kw < FEERATE_FLOOR)