mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 15:14:23 +01:00
common/json: restore json_delve() for simple plugin parsing.
This was removed (as unused) in 6269a4c55d592e8720b7f2a304c21f61f7931238; now I've even added tests. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -4,6 +4,7 @@
|
|||||||
#include <ccan/build_assert/build_assert.h>
|
#include <ccan/build_assert/build_assert.h>
|
||||||
#include <ccan/str/hex/hex.h>
|
#include <ccan/str/hex/hex.h>
|
||||||
#include <ccan/tal/str/str.h>
|
#include <ccan/tal/str/str.h>
|
||||||
|
#include <common/utils.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@@ -273,3 +274,39 @@ void json_tok_remove(jsmntok_t **tokens, jsmntok_t *tok, size_t num)
|
|||||||
tal_resize(tokens, tal_count(*tokens) - remove_count);
|
tal_resize(tokens, tal_count(*tokens) - remove_count);
|
||||||
(*tokens)->size -= num;
|
(*tokens)->size -= num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const jsmntok_t *json_delve(const char *buffer,
|
||||||
|
const jsmntok_t *tok,
|
||||||
|
const char *guide)
|
||||||
|
{
|
||||||
|
while (*guide) {
|
||||||
|
const char *key;
|
||||||
|
size_t len = strcspn(guide+1, ".[]");
|
||||||
|
|
||||||
|
key = tal_strndup(tmpctx, guide+1, len);
|
||||||
|
switch (guide[0]) {
|
||||||
|
case '.':
|
||||||
|
if (tok->type != JSMN_OBJECT)
|
||||||
|
return NULL;
|
||||||
|
tok = json_get_member(buffer, tok, key);
|
||||||
|
if (!tok)
|
||||||
|
return NULL;
|
||||||
|
break;
|
||||||
|
case '[':
|
||||||
|
if (tok->type != JSMN_ARRAY)
|
||||||
|
return NULL;
|
||||||
|
tok = json_get_arr(tok, atol(key));
|
||||||
|
if (!tok)
|
||||||
|
return NULL;
|
||||||
|
/* Must be terminated */
|
||||||
|
assert(guide[1+strlen(key)] == ']');
|
||||||
|
len++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
guide += len + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tok;
|
||||||
|
}
|
||||||
|
|||||||
@@ -73,4 +73,9 @@ jsmntok_t *json_tok_copy(const tal_t *ctx, const jsmntok_t *tok);
|
|||||||
*/
|
*/
|
||||||
void json_tok_remove(jsmntok_t **tokens, jsmntok_t *tok, size_t num);
|
void json_tok_remove(jsmntok_t **tokens, jsmntok_t *tok, size_t num);
|
||||||
|
|
||||||
|
/* Guide is a string with . for members, [] around indexes. */
|
||||||
|
const jsmntok_t *json_delve(const char *buffer,
|
||||||
|
const jsmntok_t *tok,
|
||||||
|
const char *guide);
|
||||||
|
|
||||||
#endif /* LIGHTNING_COMMON_JSON_H */
|
#endif /* LIGHTNING_COMMON_JSON_H */
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "../json.c"
|
#include "../json.c"
|
||||||
|
#include <ccan/mem/mem.h>
|
||||||
#include <common/utils.h>
|
#include <common/utils.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
@@ -38,11 +39,103 @@ static int test_json_tok_bitcoin_amount(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_json_delve(void)
|
||||||
|
{
|
||||||
|
const jsmntok_t *toks, *t;
|
||||||
|
char *buf;
|
||||||
|
bool ok;
|
||||||
|
|
||||||
|
buf = "{\"1\":\"one\", \"2\":\"two\", \"3\":[\"three\", {\"deeper\": 17}]}";
|
||||||
|
toks = json_parse_input(tmpctx, buf, strlen(buf), &ok);
|
||||||
|
assert(ok);
|
||||||
|
|
||||||
|
t = json_delve(buf, toks, ".1");
|
||||||
|
assert(t);
|
||||||
|
assert(t->type == JSMN_STRING);
|
||||||
|
assert(json_tok_streq(buf, t, "one"));
|
||||||
|
assert(t == toks+2);
|
||||||
|
|
||||||
|
t = json_delve(buf, toks, ".2");
|
||||||
|
assert(t);
|
||||||
|
assert(t->type == JSMN_STRING);
|
||||||
|
assert(json_tok_streq(buf, t, "two"));
|
||||||
|
assert(t == toks+4);
|
||||||
|
|
||||||
|
t = json_delve(buf, toks, ".3");
|
||||||
|
assert(t);
|
||||||
|
assert(t->type == JSMN_ARRAY);
|
||||||
|
assert(t == toks+6);
|
||||||
|
|
||||||
|
t = json_delve(buf, toks, ".3[0]");
|
||||||
|
assert(t);
|
||||||
|
assert(t->type == JSMN_STRING);
|
||||||
|
assert(json_tok_streq(buf, t, "three"));
|
||||||
|
assert(t == toks+7);
|
||||||
|
|
||||||
|
t = json_delve(buf, toks, ".3[1]");
|
||||||
|
assert(t);
|
||||||
|
assert(t->type == JSMN_OBJECT);
|
||||||
|
assert(t == toks+8);
|
||||||
|
|
||||||
|
t = json_delve(buf, toks, ".3[1].deeper");
|
||||||
|
assert(t);
|
||||||
|
assert(t->type == JSMN_PRIMITIVE);
|
||||||
|
assert(memeq(buf + t->start, t->end - t->start, "17", strlen("17")));
|
||||||
|
assert(t == toks+10);
|
||||||
|
|
||||||
|
t = json_delve(buf, toks, ".4");
|
||||||
|
assert(!t);
|
||||||
|
t = json_delve(buf, toks, "[0]");
|
||||||
|
assert(!t);
|
||||||
|
t = json_delve(buf, toks, ".deeper");
|
||||||
|
assert(!t);
|
||||||
|
t = json_delve(buf, toks, ".3[2]");
|
||||||
|
assert(!t);
|
||||||
|
t = json_delve(buf, toks, ".3[2].deeper");
|
||||||
|
assert(!t);
|
||||||
|
t = json_delve(buf, toks, ".3[0].deeper");
|
||||||
|
assert(!t);
|
||||||
|
t = json_delve(buf, toks, ".3[1].deeper[0]");
|
||||||
|
assert(!t);
|
||||||
|
t = json_delve(buf, toks, ".3[1][0]");
|
||||||
|
assert(!t);
|
||||||
|
|
||||||
|
/* Now a real example. */
|
||||||
|
buf = "{\n"
|
||||||
|
" \"jsonrpc\": \"2.0\", \n"
|
||||||
|
" \"method\": \"init\", \n"
|
||||||
|
" \"id\": 1, \n"
|
||||||
|
" \"params\": {\n"
|
||||||
|
" \"options\": {\n"
|
||||||
|
" }, \n"
|
||||||
|
" \"configuration\": {\n"
|
||||||
|
" \"lightning-dir\": \"/tmp/ltests-n2hyd543/test_pay_plugin_1/lightning-2/\", \n"
|
||||||
|
" \"rpc-file\": \"lightning-rpc\"\n"
|
||||||
|
" }\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
"\n";
|
||||||
|
toks = json_parse_input(tmpctx, buf, strlen(buf), &ok);
|
||||||
|
assert(ok);
|
||||||
|
|
||||||
|
t = json_delve(buf, toks, ".rpcfile");
|
||||||
|
assert(!t);
|
||||||
|
t = json_delve(buf, toks, ".configuration.rpc-file");
|
||||||
|
assert(!t);
|
||||||
|
t = json_delve(buf, toks, ".params.configuration.rpc-file");
|
||||||
|
assert(t);
|
||||||
|
assert(t->type == JSMN_STRING);
|
||||||
|
assert(json_tok_streq(buf, t, "lightning-rpc"));
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
setup_locale();
|
setup_locale();
|
||||||
|
setup_tmpctx();
|
||||||
|
|
||||||
test_json_tok_bitcoin_amount();
|
test_json_tok_bitcoin_amount();
|
||||||
|
test_json_delve();
|
||||||
assert(!taken_any());
|
assert(!taken_any());
|
||||||
take_cleanup();
|
take_cleanup();
|
||||||
|
tal_free(tmpctx);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user