commit 93cfa17bd6d24aa3326ba000ed62bc5c0a9e3cd0
parent bd7487d34d684d776cb051baa36ca9ad92b6b193
Author: William Casarin <jb55@jb55.com>
Date: Sat, 22 Jul 2023 15:23:39 -0700
add content length to ndb_note
We don't need this for every string, but it's nice to have for content
so you don't have to strlen it if its very large.
Diffstat:
3 files changed, 27 insertions(+), 4 deletions(-)
diff --git a/nostrdb.c b/nostrdb.c
@@ -207,6 +207,7 @@ int ndb_builder_make_str(struct ndb_builder *builder, const char *str, int len,
int ndb_builder_set_content(struct ndb_builder *builder, const char *content,
int len)
{
+ builder->note->content_length = len;
return ndb_builder_make_str(builder, content, len, &builder->note->content);
}
@@ -238,12 +239,14 @@ static int ndb_builder_finalize_tag(struct ndb_builder *builder,
/// Unescape and push json strings
static int ndb_builder_make_json_str(struct ndb_builder *builder,
const char *str, int len,
- union packed_str *pstr)
+ union packed_str *pstr,
+ int *written)
{
// let's not care about de-duping these. we should just unescape
// in-place directly into the strings table.
const char *p, *end, *start;
+ unsigned char *builder_start;
// always try compact strings first
if (ndb_builder_try_compact_str(builder, str, len, pstr))
@@ -253,6 +256,7 @@ static int ndb_builder_make_json_str(struct ndb_builder *builder,
start = str; // Initialize start to the beginning of the string
*pstr = ndb_offset_str(builder->strings.p - builder->strings.start);
+ builder_start = builder->strings.p;
for (p = str; p < end; p++) {
if (*p == '\\' && p+1 < end) {
@@ -313,6 +317,9 @@ static int ndb_builder_make_json_str(struct ndb_builder *builder,
return 0;
}
+ if (written)
+ *written = builder->strings.p - builder_start;
+
// TODO: dedupe these!?
return cursor_push_byte(&builder->strings, '\0');
}
@@ -321,7 +328,7 @@ static int ndb_builder_push_json_tag(struct ndb_builder *builder,
const char *str, int len)
{
union packed_str pstr;
- if (!ndb_builder_make_json_str(builder, str, len, &pstr))
+ if (!ndb_builder_make_json_str(builder, str, len, &pstr, NULL))
return 0;
return ndb_builder_finalize_tag(builder, pstr);
}
@@ -468,11 +475,15 @@ int ndb_note_from_json(const char *json, int len, struct ndb_note **note,
// content
tok = &parser.toks[i+1];
union packed_str pstr;
+ tok_len = toksize(tok);
+ int written;
if (!ndb_builder_make_json_str(&parser.builder,
json + tok->start,
- toksize(tok), &pstr)) {
+ tok_len, &pstr,
+ &written)) {
return 0;
}
+ parser.builder.note->content_length = written;
parser.builder.note->content = pstr;
}
} else if (start[0] == 't' && jsoneq(json, tok, tok_len, "tags")) {
diff --git a/nostrdb.h b/nostrdb.h
@@ -40,6 +40,7 @@ struct ndb_note {
uint32_t created_at;
uint32_t kind;
+ uint32_t content_length;
union packed_str content;
uint32_t strings;
uint32_t json;
@@ -84,6 +85,7 @@ static inline int ndb_str_is_packed(union packed_str str)
return (str.offset >> 31) & 0x1;
}
+
static inline const char * ndb_note_str(struct ndb_note *note,
union packed_str *str)
{
@@ -146,6 +148,11 @@ static inline const char * ndb_note_content(struct ndb_note *note)
return ndb_note_str(note, ¬e->content);
}
+static inline uint32_t ndb_note_content_length(struct ndb_note *note)
+{
+ return note->content_length;
+}
+
static inline struct ndb_note * ndb_note_from_bytes(unsigned char *bytes)
{
struct ndb_note *note = (struct ndb_note *)bytes;
diff --git a/test.c b/test.c
@@ -108,7 +108,7 @@ static void test_parse_contact_list()
size = ndb_note_from_json((const char*)json, written, ¬e, buf, alloc_size);
printf("ndb_note_from_json size %d\n", size);
assert(size > 0);
- assert(size == 59058);
+ assert(size == 59062);
const char* expected_content =
"{\"wss://nos.lol\":{\"write\":true,\"read\":true},"
@@ -123,6 +123,11 @@ static void test_parse_contact_list()
assert(!strcmp(expected_content, ndb_note_content(note)));
assert(ndb_note_created_at(note) == 1689904312);
assert(ndb_note_kind(note) == 3);
+ //printf("note content length %d\n", ndb_note_content_length(note));
+ printf("ndb_content_len %d, expected_len %ld\n",
+ ndb_note_content_length(note),
+ strlen(expected_content));
+ assert(ndb_note_content_length(note) == strlen(expected_content));
write_file("test_contacts_ndb_note", (unsigned char *)note, size);
printf("wrote test_contacts_ndb_note (raw ndb_note)\n");