block.c (4410B)
1 2 3 #include "nostrdb.h" 4 #include "block.h" 5 #include <stdlib.h> 6 7 int push_str_block(struct cursor *buf, const char *content, struct ndb_str_block *block) { 8 return cursor_push_varint(buf, block->str - content) && 9 cursor_push_varint(buf, block->len); 10 } 11 12 int pull_str_block(struct cursor *buf, const char *content, struct ndb_str_block *block) { 13 uint32_t start; 14 if (!cursor_pull_varint_u32(buf, &start)) 15 return 0; 16 17 block->str = content + start; 18 19 return cursor_pull_varint_u32(buf, &block->len); 20 } 21 22 static int pull_nostr_bech32_type(struct cursor *cur, enum nostr_bech32_type *type) 23 { 24 uint64_t inttype; 25 if (!cursor_pull_varint(cur, &inttype)) 26 return 0; 27 28 if (inttype <= 0 || inttype > NOSTR_BECH32_KNOWN_TYPES) 29 return 0; 30 31 *type = inttype; 32 return 1; 33 } 34 35 36 static int pull_bech32_mention(const char *content, struct cursor *cur, struct ndb_mention_bech32_block *block) { 37 uint16_t size; 38 unsigned char *start; 39 struct cursor bech32; 40 41 if (!pull_str_block(cur, content, &block->str)) 42 return 0; 43 44 if (!cursor_pull_u16(cur, &size)) 45 return 0; 46 47 if (!pull_nostr_bech32_type(cur, &block->bech32.type)) 48 return 0; 49 50 make_cursor(cur->p, cur->p + size, &bech32); 51 52 start = cur->p; 53 54 if (!parse_nostr_bech32_buffer(&bech32, block->bech32.type, &block->bech32)) 55 return 0; 56 57 //assert(bech32.p == start + size); 58 cur->p = start + size; 59 return 1; 60 } 61 62 static int pull_invoice(const char *content, struct cursor *cur, 63 struct ndb_invoice_block *block) 64 { 65 if (!pull_str_block(cur, content, &block->invstr)) 66 return 0; 67 68 return ndb_decode_invoice(cur, &block->invoice); 69 } 70 71 static int pull_block_type(struct cursor *cur, enum ndb_block_type *type) 72 { 73 uint32_t itype; 74 *type = 0; 75 if (!cursor_pull_varint_u32(cur, &itype)) 76 return 0; 77 78 if (itype <= 0 || itype > NDB_NUM_BLOCK_TYPES) 79 return 0; 80 81 *type = itype; 82 return 1; 83 } 84 85 static int pull_block(const char *content, struct cursor *cur, struct ndb_block *block) 86 { 87 unsigned char *start = cur->p; 88 89 if (!pull_block_type(cur, &block->type)) 90 return 0; 91 92 switch (block->type) { 93 case BLOCK_HASHTAG: 94 case BLOCK_TEXT: 95 case BLOCK_URL: 96 if (!pull_str_block(cur, content, &block->block.str)) 97 goto fail; 98 break; 99 100 case BLOCK_MENTION_INDEX: 101 if (!cursor_pull_varint_u32(cur, &block->block.mention_index)) 102 goto fail; 103 break; 104 105 case BLOCK_MENTION_BECH32: 106 if (!pull_bech32_mention(content, cur, &block->block.mention_bech32)) 107 goto fail; 108 break; 109 110 case BLOCK_INVOICE: 111 // we only push invoice strs here 112 if (!pull_invoice(content, cur, &block->block.invoice)) 113 goto fail; 114 break; 115 } 116 117 return 1; 118 fail: 119 cur->p = start; 120 return 0; 121 } 122 123 124 enum ndb_block_type ndb_get_block_type(struct ndb_block *block) { 125 return block->type; 126 } 127 128 // BLOCK ITERATORS 129 void ndb_blocks_iterate_start(const char *content, struct ndb_blocks *blocks, struct ndb_block_iterator *iter) { 130 iter->blocks = blocks; 131 iter->content = content; 132 iter->p = blocks->blocks; 133 } 134 135 struct ndb_block *ndb_blocks_iterate_next(struct ndb_block_iterator *iter) 136 { 137 struct cursor cur; 138 cur.start = iter->blocks->blocks; 139 cur.p = iter->p; 140 cur.end = iter->blocks->blocks + iter->blocks->blocks_size; 141 142 while (cur.p < cur.end) { 143 if (!pull_block(iter->content, &cur, &iter->block)) { 144 iter->p = cur.p; 145 return NULL; 146 } else { 147 iter->p = cur.p; 148 return &iter->block; 149 } 150 } 151 152 return NULL; 153 } 154 155 // STR BLOCKS 156 struct ndb_str_block *ndb_block_str(struct ndb_block *block) 157 { 158 switch (block->type) { 159 case BLOCK_HASHTAG: 160 case BLOCK_TEXT: 161 case BLOCK_URL: 162 return &block->block.str; 163 case BLOCK_MENTION_INDEX: 164 return NULL; 165 case BLOCK_MENTION_BECH32: 166 return &block->block.mention_bech32.str; 167 case BLOCK_INVOICE: 168 return &block->block.invoice.invstr; 169 } 170 171 return NULL; 172 } 173 174 const char *ndb_str_block_ptr(struct ndb_str_block *str_block) { 175 return str_block->str; 176 } 177 178 uint32_t ndb_str_block_len(struct ndb_str_block *str_block) { 179 return str_block->len; 180 } 181 182 struct nostr_bech32 *ndb_bech32_block(struct ndb_block *block) { 183 return &block->block.mention_bech32.bech32; 184 } 185 186 // total size including padding 187 size_t ndb_blocks_total_size(struct ndb_blocks *blocks) { 188 return blocks->total_size; 189 } 190 191 void ndb_blocks_free(struct ndb_blocks *blocks) { 192 if ((blocks->flags & NDB_BLOCK_FLAG_OWNED) != NDB_BLOCK_FLAG_OWNED) 193 return; 194 195 free(blocks); 196 } 197 198 int ndb_blocks_flags(struct ndb_blocks *blocks) { 199 return blocks->flags; 200 } 201 202 int ndb_blocks_word_count(struct ndb_blocks *blocks) { 203 return blocks->words; 204 }