nostril

A C cli tool for creating nostr events
git clone git://jb55.com/nostril
Log | Files | Refs | Submodules | README | LICENSE

cursor.h (6038B)


      1 
      2 #ifndef CURSOR_H
      3 #define CURSOR_H
      4 
      5 #include <stdio.h>
      6 #include <assert.h>
      7 #include <string.h>
      8 
      9 #define unlikely(x) __builtin_expect((x),0)
     10 #define likely(x)   __builtin_expect((x),1)
     11 
     12 struct cursor {
     13 	unsigned char *start;
     14 	unsigned char *p;
     15 	unsigned char *end;
     16 };
     17 
     18 struct array {
     19 	struct cursor cur;
     20 	unsigned int elem_size;
     21 };
     22 
     23 static inline void reset_cursor(struct cursor *cursor)
     24 {
     25 	cursor->p = cursor->start;
     26 }
     27 
     28 static inline void wipe_cursor(struct cursor *cursor)
     29 {
     30 	reset_cursor(cursor);
     31 	memset(cursor->start, 0, cursor->end - cursor->start);
     32 }
     33 
     34 static inline void make_cursor(unsigned char *start, unsigned char *end, struct cursor *cursor)
     35 {
     36 	cursor->start = start;
     37 	cursor->p = start;
     38 	cursor->end = end;
     39 }
     40 
     41 static inline void make_array(struct array *a, unsigned char* start, unsigned char *end, unsigned int elem_size)
     42 {
     43 	make_cursor(start, end, &a->cur);
     44 	a->elem_size = elem_size;
     45 }
     46 
     47 static inline int cursor_eof(struct cursor *c)
     48 {
     49 	return c->p == c->end;
     50 }
     51 
     52 static inline void *cursor_malloc(struct cursor *mem, unsigned long size)
     53 {
     54 	void *ret;
     55 
     56 	if (mem->p + size > mem->end) {
     57 		return NULL;
     58 	}
     59 
     60 	ret = mem->p;
     61 	mem->p += size;
     62 
     63 	return ret;
     64 }
     65 
     66 static inline void *cursor_alloc(struct cursor *mem, unsigned long size)
     67 {
     68 	void *ret;
     69 	if (!(ret = cursor_malloc(mem, size))) {
     70 		return 0;
     71 	}
     72 
     73 	memset(ret, 0, size);
     74 	return ret;
     75 }
     76 
     77 static inline int cursor_slice(struct cursor *mem, struct cursor *slice, size_t size)
     78 {
     79 	unsigned char *p;
     80 	if (!(p = cursor_alloc(mem, size))) {
     81 		return 0;
     82 	}
     83 	make_cursor(p, mem->p, slice);
     84 	return 1;
     85 }
     86 
     87 
     88 static inline void copy_cursor(struct cursor *src, struct cursor *dest)
     89 {
     90 	dest->start = src->start;
     91 	dest->p = src->p;
     92 	dest->end = src->end;
     93 }
     94 
     95 static inline int pull_byte(struct cursor *cursor, unsigned char *c)
     96 {
     97 	if (unlikely(cursor->p + 1 > cursor->end))
     98 		return 0;
     99 
    100 	*c = *cursor->p;
    101 	cursor->p++;
    102 
    103 	return 1;
    104 }
    105 
    106 static inline int cursor_pull_c_str(struct cursor *cursor, const char **str)
    107 {
    108 	*str = (const char*)cursor->p;
    109 
    110 	for (; cursor->p < cursor->end; cursor->p++) {
    111 		if (*cursor->p == 0) {
    112 			cursor->p++;
    113 			return 1;
    114 		}
    115 	}
    116 
    117 	return 0;
    118 }
    119 
    120 
    121 static inline int cursor_push_byte(struct cursor *cursor, unsigned char c)
    122 {
    123 	if (unlikely(cursor->p + 1 > cursor->end)) {
    124 		return 0;
    125 	}
    126 
    127 	*cursor->p = c;
    128 	cursor->p++;
    129 
    130 	return 1;
    131 }
    132 
    133 static inline int cursor_pull(struct cursor *cursor, unsigned char *data, int len)
    134 {
    135 	if (unlikely(cursor->p + len > cursor->end)) {
    136 		return 0;
    137 	}
    138 
    139 	memcpy(data, cursor->p, len);
    140 	cursor->p += len;
    141 
    142 	return 1;
    143 }
    144 
    145 static inline int pull_data_into_cursor(struct cursor *cursor,
    146 			  struct cursor *dest,
    147 			  unsigned char **data,
    148 			  int len)
    149 {
    150 	int ok;
    151 
    152 	if (unlikely(dest->p + len > dest->end)) {
    153 		printf("not enough room in dest buffer\n");
    154 		return 0;
    155 	}
    156 
    157 	ok = cursor_pull(cursor, dest->p, len);
    158 	if (!ok) return 0;
    159 
    160 	*data = dest->p;
    161 	dest->p += len;
    162 
    163 	return 1;
    164 }
    165 
    166 static inline int cursor_dropn(struct cursor *cur, int size, int n)
    167 {
    168 	if (n == 0)
    169 		return 1;
    170 
    171 	if (unlikely(cur->p - size*n < cur->start)) {
    172 		return 0;
    173 	}
    174 
    175 	cur->p -= size*n;
    176 	return 1;
    177 }
    178 
    179 static inline int cursor_drop(struct cursor *cur, int size)
    180 {
    181 	return cursor_dropn(cur, size, 1);
    182 }
    183 
    184 static inline unsigned char *cursor_topn(struct cursor *cur, int len, int n)
    185 {
    186 	n += 1;
    187 	if (unlikely(cur->p - len*n < cur->start)) {
    188 		return NULL;
    189 	}
    190 	return cur->p - len*n;
    191 }
    192 
    193 static inline unsigned char *cursor_top(struct cursor *cur, int len)
    194 {
    195 	if (unlikely(cur->p - len < cur->start)) {
    196 		return NULL;
    197 	}
    198 	return cur->p - len;
    199 }
    200 
    201 static inline int cursor_top_int(struct cursor *cur, int *i)
    202 {
    203 	unsigned char *p;
    204 	if (unlikely(!(p = cursor_top(cur, sizeof(*i))))) {
    205 		return 0;
    206 	}
    207 	*i = *((int*)p);
    208 	return 1;
    209 }
    210 
    211 static inline int cursor_pop(struct cursor *cur, unsigned char *data, int len)
    212 {
    213 	if (unlikely(cur->p - len < cur->start)) {
    214 		return 0;
    215 	}
    216 
    217 	cur->p -= len;
    218 	memcpy(data, cur->p, len);
    219 
    220 	return 1;
    221 }
    222 
    223 static inline int cursor_push(struct cursor *cursor, unsigned char *data, int len)
    224 {
    225 	if (unlikely(cursor->p + len >= cursor->end)) {
    226 		return 0;
    227 	}
    228 
    229 	if (cursor->p != data)
    230 		memcpy(cursor->p, data, len);
    231 
    232 	cursor->p += len;
    233 
    234 	return 1;
    235 }
    236 
    237 static inline int cursor_push_int(struct cursor *cursor, int i)
    238 {
    239 	return cursor_push(cursor, (unsigned char*)&i, sizeof(i));
    240 }
    241 
    242 static inline int cursor_len(struct cursor *cursor)
    243 {
    244 	return cursor->p - cursor->start;
    245 }
    246 
    247 static inline size_t cursor_count(struct cursor *cursor, size_t elem_size)
    248 {
    249 	return cursor_len(cursor)/elem_size;
    250 }
    251 
    252 static inline int cursor_pull_int(struct cursor *cursor, int *i)
    253 {
    254 	return cursor_pull(cursor, (unsigned char*)i, sizeof(*i));
    255 }
    256 
    257 static inline int cursor_push_u16(struct cursor *cursor, unsigned short i)
    258 {
    259 	return cursor_push(cursor, (unsigned char*)&i, sizeof(i));
    260 }
    261 
    262 static inline void *index_cursor(struct cursor *cursor, unsigned int index, int elem_size)
    263 {
    264 	unsigned char *p;
    265 	p = &cursor->start[elem_size * index];
    266 
    267 	if (unlikely(p >= cursor->end))
    268 		return NULL;
    269 
    270 	return (void*)p;
    271 }
    272 
    273 
    274 static inline int push_sized_str(struct cursor *cursor, const char *str, int len)
    275 {
    276 	return cursor_push(cursor, (unsigned char*)str, len);
    277 }
    278 
    279 static inline int cursor_push_str(struct cursor *cursor, const char *str)
    280 {
    281 	return cursor_push(cursor, (unsigned char*)str, strlen(str));
    282 }
    283 
    284 static inline int cursor_push_c_str(struct cursor *cursor, const char *str)
    285 {
    286 	return cursor_push_str(cursor, str) && cursor_push_byte(cursor, 0);
    287 }
    288 
    289 static inline int cursor_remaining_capacity(struct cursor *cursor)
    290 {
    291 	return cursor->end - cursor->p;
    292 }
    293 
    294 
    295 #define max(a,b) ((a) > (b) ? (a) : (b))
    296 static inline void cursor_print_around(struct cursor *cur, int range)
    297 {
    298 	unsigned char *c;
    299 
    300 	printf("[%ld/%ld]\n", cur->p - cur->start, cur->end - cur->start);
    301 
    302 	c = max(cur->p - range, cur->start);
    303 	for (; c < cur->end && c < (cur->p + range); c++) {
    304 		printf("%02x", *c);
    305 	}
    306 	printf("\n");
    307 
    308 	c = max(cur->p - range, cur->start);
    309 	for (; c < cur->end && c < (cur->p + range); c++) {
    310 		if (c == cur->p) {
    311 			printf("^");
    312 			continue;
    313 		}
    314 		printf("  ");
    315 	}
    316 	printf("\n");
    317 }
    318 #undef max
    319 
    320 #endif