nostrdb

an unfairly fast embedded nostr database backed by lmdb
git clone git://jb55.com/nostrdb
Log | Files | Refs | README | LICENSE

commit 4e1e42cdfb46c582d865832aefef32c90c18fbec
parent 8c38ee7c08081928260a681a5747360f76f5a844
Author: William Casarin <jb55@jb55.com>
Date:   Thu, 20 Jul 2023 10:42:18 -0700

json: start on tags builder

mostly just trying to figure out how the jsmn token system works. I
think I get it now.

Before I continue I'm going to switch to an api where the user providers
the buffers so we don't do any memory allocation at all.

Diffstat:
Mnostrdb.c | 91+++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
Mtest.c | 3++-
2 files changed, 65 insertions(+), 29 deletions(-)

diff --git a/nostrdb.c b/nostrdb.c @@ -2,8 +2,19 @@ #include "nostrdb.h" #include "jsmn.h" #include "hex.h" +#include "cursor.h" #include <stdlib.h> +struct ndb_json_parser { + struct ndb_builder builder; + struct cursor buf; +}; + +static inline int +cursor_push_tag(struct cursor *cur, struct ndb_tag *tag) { + return cursor_push_u16(cur, tag->count); +} + int ndb_builder_new(struct ndb_builder *builder, int *bufsize) { struct ndb_note *note; @@ -115,16 +126,43 @@ jsoneq(const char *json, jsmntok_t *tok, int tok_len, const char *s) { return 0; } -int ndb_note_from_json(const char *json, int len, struct ndb_note **note) { - int i, r; - struct ndb_builder builder; - jsmn_parser p; +static inline int toksize(jsmntok_t *tok) { + return tok->end - tok->start; +} + +static inline int +build_tag_from_json_tokens(const char *json, jsmntok_t *tag, struct ndb_builder *builder) { + printf("tag %.*s %d\n", toksize(tag), json + tag->start, tag->type); + + return 1; +} + +static inline int +ndb_builder_process_json_tags(const char *json, jsmntok_t *array, struct ndb_builder *builder) { + jsmntok_t *tag = array; + printf("json_tags %.*s %d\n", toksize(tag), json + tag->start, tag->type); + + for (int i = 0; i < array->size; i++) { + if (!build_tag_from_json_tokens(json, &tag[i+1], builder)) + return 0; + tag += array->size; + } + + return 1; +} + + +int +ndb_note_from_json(const char *json, int len, struct ndb_note **note) { jsmntok_t toks[4096], *tok = NULL; unsigned char buf[64]; - jsmn_init(&p); - int tok_len; + struct ndb_builder builder; + jsmn_parser p; + + int i, r, tok_len; const char *start; + jsmn_init(&p); ndb_builder_new(&builder, &len); r = jsmn_parse(&p, json, len, toks, sizeof(toks)/sizeof(toks[0])); @@ -134,46 +172,48 @@ int ndb_note_from_json(const char *json, int len, struct ndb_note **note) { for (i = 1; i < r; i++) { tok = &toks[i]; - tok_len = tok->end - tok->start; start = json + tok->start; + tok_len = toksize(tok); + + //printf("toplevel %.*s %d\n", tok_len, json + tok->start, tok->type); if (tok_len == 0 || i + 1 >= r) continue; if (start[0] == 'p' && jsoneq(json, tok, tok_len, "pubkey")) { // pubkey - tok = &toks[i+1]; tok_len = tok->end - tok->start; - hex_decode(json + tok->start, tok_len, buf, sizeof(buf)); + tok = &toks[i+1]; + hex_decode(json + tok->start, toksize(tok), buf, sizeof(buf)); ndb_builder_set_pubkey(&builder, buf); } else if (tok_len == 2 && start[0] == 'i' && start[1] == 'd') { // id - tok = &toks[i+1]; tok_len = tok->end - tok->start; - hex_decode(json + tok->start, tok_len, buf, sizeof(buf)); + tok = &toks[i+1]; + hex_decode(json + tok->start, toksize(tok), buf, sizeof(buf)); // TODO: validate id ndb_builder_set_id(&builder, buf); } else if (tok_len == 3 && start[0] == 's' && start[1] == 'i' && start[2] == 'g') { // sig - tok = &toks[i+1]; tok_len = tok->end - tok->start; - hex_decode(json + tok->start, tok_len, buf, sizeof(buf)); + tok = &toks[i+1]; + hex_decode(json + tok->start, toksize(tok), buf, sizeof(buf)); ndb_builder_set_signature(&builder, buf); } else if (start[0] == 'k' && jsoneq(json, tok, tok_len, "kind")) { // kind - tok = &toks[i+1]; tok_len = tok->end - tok->start; - printf("json_kind %.*s\n", tok_len, json + tok->start); + tok = &toks[i+1]; + printf("json_kind %.*s\n", toksize(tok), json + tok->start); } else if (start[0] == 'c') { if (jsoneq(json, tok, tok_len, "created_at")) { // created_at - tok = &toks[i+1]; tok_len = tok->end - tok->start; - printf("json_created_at %.*s\n", tok_len, json + tok->start); + tok = &toks[i+1]; + printf("json_created_at %.*s\n", toksize(tok), json + tok->start); } else if (jsoneq(json, tok, tok_len, "content")) { // content - tok = &toks[i+1]; tok_len = tok->end - tok->start; - if (!ndb_builder_set_content(&builder, json + tok->start, tok_len)) - printf("json_content %.*s\n", tok_len, json + tok->start); + tok = &toks[i+1]; + if (!ndb_builder_set_content(&builder, json + tok->start, toksize(tok))) + return 0; } } else if (start[0] == 't' && jsoneq(json, tok, tok_len, "tags")) { - // tags - tok = &toks[i+1]; tok_len = tok->end - tok->start; - printf("json_tags %.*s\n", tok_len, json + tok->start); + tok = &toks[i+1]; + ndb_builder_process_json_tags(json, tok, &builder); + i += tok->size; } } @@ -200,11 +240,6 @@ ndb_builder_set_kind(struct ndb_builder *builder, uint32_t kind) { builder->note->kind = kind; } -static inline int -cursor_push_tag(struct cursor *cur, struct ndb_tag *tag) { - return cursor_push_u16(cur, tag->count); -} - int ndb_builder_add_tag(struct ndb_builder *builder, const char **strs, uint16_t num_strs) { int i; diff --git a/test.c b/test.c @@ -87,8 +87,9 @@ static void test_parse_json() { char hex_id[65] = {0}; struct ndb_note *note; #define HEX_ID "5004a081e397c6da9dc2f2d6b3134006a9d0e8c1b46689d9fe150bb2f21a204d" +#define HEX_PK "b169f596968917a1abeb4234d3cf3aa9baee2112e58998d17c6db416ad33fe40" static const char *json = - "{\"id\": \"" HEX_ID "\",\"pubkey\": \"b169f596968917a1abeb4234d3cf3aa9baee2112e58998d17c6db416ad33fe40\",\"created_at\": 1689836342,\"kind\": 1,\"tags\": [],\"content\": \"共通語\",\"sig\": \"e4d528651311d567f461d7be916c37cbf2b4d530e672f29f15f353291ed6df60c665928e67d2f18861c5ca88\"}"; + "{\"id\": \"" HEX_ID "\",\"pubkey\": \"" HEX_PK "\",\"created_at\": 1689836342,\"kind\": 1,\"tags\": [[\"p\",\"" HEX_ID "\"], [\"word\", \"words\"]],\"content\": \"共通語\",\"sig\": \"e4d528651311d567f461d7be916c37cbf2b4d530e672f29f15f353291ed6df60c665928e67d2f18861c5ca88\"}"; ndb_note_from_json(json, strlen(json), &note);