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