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