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;
}
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)
{
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? */
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 */
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,
u32 **feerate_per_kw)
{
jsmntok_t base = *tok, suffix = *tok;
jsmntok_t base = *tok;
enum feerate_style style;
unsigned int num;
/* We have to split the number and suffix. */
suffix.start = suffix.end;
while (suffix.start > base.start && !isdigit(buffer[suffix.start-1])) {
suffix.start--;
base.end--;
}
if (json_tok_endswith(buffer, tok,
feerate_style_name(FEERATE_PER_KBYTE))) {
style = FEERATE_PER_KBYTE;
base.end -= strlen(feerate_style_name(FEERATE_PER_KBYTE));
} 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)) {
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,
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 = feerate_from_style(num, style);
if (**feerate_per_kw < FEERATE_FLOOR)