chibipub

experimental activitypub node in C
git clone git://jb55.com/chibipub
Log | Files | Refs | README | LICENSE

cursor.h (3607B)


      1 
      2 #ifndef CHIBIPUB_CURSOR_H
      3 #define CHIBIPUB_CURSOR_H
      4 
      5 #include <stdio.h>
      6 #include <string.h>
      7 
      8 #define unlikely(x)     __builtin_expect((x),0)
      9 
     10 struct cursor {
     11 	unsigned char *start;
     12 	unsigned char *p;
     13 	unsigned char *end;
     14 };
     15 
     16 static inline int cursor_eof(struct cursor *c)
     17 {
     18 	return c->p == c->end;
     19 }
     20 
     21 static inline void *cursor_alloc(struct cursor *mem, unsigned long size)
     22 {
     23 	void *ret;
     24 
     25 	if (mem->p + size > mem->end) {
     26 		return NULL;
     27 	}
     28 
     29 	ret = mem->p;
     30 	memset(ret, 0, size);
     31 	mem->p += size;
     32 
     33 	return ret;
     34 }
     35 
     36 static inline void reset_cursor(struct cursor *cur)
     37 {
     38 	cur->p = cur->start;
     39 }
     40 
     41 static inline void copy_cursor(struct cursor *src, struct cursor *dest)
     42 {
     43 	dest->start = src->start;
     44 	dest->p = src->p;
     45 	dest->end = src->end;
     46 }
     47 
     48 static inline void make_cursor(unsigned char *start, unsigned char *end, struct cursor *cursor)
     49 {
     50 	cursor->start = start;
     51 	cursor->p = start;
     52 	cursor->end = end;
     53 }
     54 
     55 static inline int cursor_peek_byte(struct cursor *cursor, unsigned char *c, int offset)
     56 {
     57 	if (unlikely(cursor->p + offset >= cursor->end))
     58 		return 0;
     59 	*c = *(cursor->p + offset);
     60 	return 1;
     61 }
     62 
     63 static inline int cursor_index(struct cursor *cursor, int elem_size)
     64 {
     65 	return (cursor->p - cursor->start) / elem_size;
     66 }
     67 
     68 
     69 static inline int pull_byte(struct cursor *cursor, unsigned char *c)
     70 {
     71 	if (unlikely(cursor->p + 1 >= cursor->end))
     72 		return 0;
     73 
     74 	*c = *cursor->p;
     75 	cursor->p++;
     76 
     77 	return 1;
     78 }
     79 
     80 
     81 static inline int push_byte(struct cursor *cursor, unsigned char c)
     82 {
     83 	if (unlikely(cursor->p + 1 >= cursor->end)) {
     84 		return 0;
     85 	}
     86 
     87 	*cursor->p = c;
     88 	cursor->p++;
     89 
     90 	return 1;
     91 }
     92 
     93 static inline int pull_data(struct cursor *cursor, unsigned char *data, int len)
     94 {
     95 	if (unlikely(cursor->p + len > cursor->end)) {
     96 		return 0;
     97 	}
     98 
     99 	memcpy(data, cursor->p, len);
    100 	cursor->p += len;
    101 
    102 	return 1;
    103 }
    104 
    105 static inline int pull_data_into_cursor(struct cursor *cursor,
    106 			  struct cursor *dest,
    107 			  unsigned char **data,
    108 			  int len)
    109 {
    110 	int ok;
    111 
    112 	if (unlikely(dest->p + len > dest->end)) {
    113 		printf("not enough room in dest buffer\n");
    114 		return 0;
    115 	}
    116 
    117 	ok = pull_data(cursor, dest->p, len);
    118 	if (!ok) return 0;
    119 
    120 	*data = dest->p;
    121 	dest->p += len;
    122 
    123 	return 1;
    124 }
    125 
    126 
    127 static inline int push_data(struct cursor *cursor, unsigned char *data, int len)
    128 {
    129 	if (unlikely(cursor->p + len > cursor->end)) {
    130 		printf("push_data oob: %ld + %d len (end: %ld)\n",
    131 				cursor->p - cursor->start,
    132 				len,
    133 				cursor->end - cursor->start
    134 				);
    135 		return 0;
    136 	}
    137 
    138 	memcpy(cursor->p, data, len);
    139 	cursor->p += len;
    140 
    141 	return 1;
    142 }
    143 
    144 static inline int push_int(struct cursor *cursor, int i)
    145 {
    146 	return push_data(cursor, (unsigned char*)&i, sizeof(i));
    147 }
    148 
    149 
    150 static inline int pull_int(struct cursor *cursor, int *i)
    151 {
    152 	return pull_data(cursor, (unsigned char*)i, sizeof(*i));
    153 }
    154 
    155 static inline int push_u16(struct cursor *cursor, unsigned short i)
    156 {
    157 	return push_data(cursor, (unsigned char*)&i, sizeof(i));
    158 }
    159 
    160 static inline void *index_cursor(struct cursor *cursor, unsigned short index, int elem_size)
    161 {
    162 	unsigned char *p;
    163 	p = &cursor->start[elem_size * index];
    164 
    165 	if (unlikely(p > cursor->end))
    166 		return NULL;
    167 
    168 	return (void*)p;
    169 }
    170 
    171 
    172 static inline int push_sized_str(struct cursor *cursor, const char *str, int len)
    173 {
    174 	return push_data(cursor, (unsigned char*)str, len);
    175 }
    176 
    177 static inline int push_str(struct cursor *cursor, const char *str)
    178 {
    179 	return push_data(cursor, (unsigned char*)str, strlen(str));
    180 }
    181 
    182 static inline int push_c_str(struct cursor *cursor, const char *str)
    183 {
    184 	return push_str(cursor, str) && push_byte(cursor, 0);
    185 }
    186 
    187 static inline int cursor_remaining_capacity(struct cursor *cursor)
    188 {
    189 	return cursor->end - cursor->p;
    190 }
    191 
    192 
    193 #endif