utils.h (3879B)
1 #ifndef UTILS_H 2 #define UTILS_H 3 4 #include "common.h" 5 6 #ifdef __cplusplus 7 extern "C" { 8 #endif /* __cplusplus */ 9 10 struct str_view { 11 char *ptr; 12 u64 len; 13 }; 14 15 static inline bool 16 str_view_equal(struct str_view a, struct str_view b) { 17 return a.len == b.len && strncmp(a.ptr, b.ptr, a.len) == 0; 18 } 19 20 #define CONST_CSTR_SV(ccstr) \ 21 ((struct str_view){ .ptr = ccstr, .len = sizeof(ccstr) - 1, }) 22 23 #define CSTR_SV(cstr) \ 24 ((struct str_view){ .ptr = cstr, .len = strlen(cstr), }) 25 26 struct mem_stream { 27 u8 *ptr; 28 u64 cur, len; 29 }; 30 31 static inline bool 32 mem_stream_eof(struct mem_stream *self) { 33 assert(self); 34 35 return self->len == self->cur; 36 } 37 38 static inline u8 * 39 mem_stream_headptr(struct mem_stream *self) { 40 assert(self); 41 42 return self->ptr + self->cur; 43 } 44 45 static inline bool 46 mem_stream_skip(struct mem_stream *self, u64 len) { 47 assert(self); 48 49 if (self->len - self->cur < len) 50 return false; 51 52 self->cur += len; 53 54 return true; 55 } 56 57 static inline bool 58 mem_stream_peek(struct mem_stream *self, u64 off, void *buf, u64 len) { 59 assert(self); 60 assert(buf); 61 62 if (self->len - off - self->cur < len) 63 return false; 64 65 memcpy(buf, self->ptr + self->cur + off, len); 66 67 return true; 68 } 69 70 static inline bool 71 mem_stream_consume(struct mem_stream *self, void *buf, u64 len) { 72 assert(self); 73 assert(buf); 74 75 return mem_stream_peek(self, 0, buf, len) && mem_stream_skip(self, len); 76 } 77 78 static inline bool 79 mem_stream_resize(struct mem_stream *self, u64 capacity) { 80 assert(self); 81 82 u8 *ptr = realloc(self->ptr, capacity); 83 if (!ptr) return false; 84 85 self->ptr = ptr; 86 self->len = capacity; 87 88 return true; 89 } 90 91 static inline u64 92 mem_stream_push(struct mem_stream *self, void *buf, u64 len) { 93 assert(self); 94 assert(buf); 95 96 if (self->len - self->cur < len && !mem_stream_resize(self, self->cur + len)) 97 return 0; 98 99 memcpy(self->ptr + self->cur, buf, len); 100 self->cur += len; 101 102 return len; 103 } 104 105 struct mem_pool { 106 u8 *ptr; 107 u64 cap, len; 108 }; 109 110 static inline bool 111 mem_pool_resize(struct mem_pool *self, u64 alignment, u64 capacity) { 112 assert(self); 113 114 #ifdef _WIN32 115 u8 *ptr = _aligned_realloc(self->ptr, capacity, alignment); 116 #else 117 u8 *ptr = realloc(self->ptr, capacity); 118 #endif 119 if (!ptr) return false; 120 121 self->ptr = ptr; 122 self->cap = capacity; 123 124 return true; 125 } 126 127 static inline bool 128 mem_pool_init(struct mem_pool *self, u64 alignment, u64 capacity) { 129 assert(self); 130 assert(alignment); 131 assert(alignment == 1 || alignment % 2 == 0); 132 assert(capacity % alignment == 0); 133 134 #ifdef _WIN32 135 u8 *ptr = _aligned_malloc(capacity, alignment); 136 #else 137 u8 *ptr = aligned_alloc(alignment, capacity); 138 #endif 139 if (!ptr) return false; 140 141 self->ptr = ptr; 142 self->cap = capacity; 143 self->len = 0; 144 145 return true; 146 } 147 148 #define MEM_POOL_INIT(pool, type, capacity) \ 149 mem_pool_init((pool), alignof(type), (capacity) * sizeof(type)) 150 151 static inline void 152 mem_pool_free(struct mem_pool *self) { 153 assert(self); 154 155 #ifdef _WIN32 156 _aligned_free(self->ptr); 157 #else 158 free(self->ptr); 159 #endif 160 } 161 162 static inline void 163 mem_pool_reset(struct mem_pool *self) { 164 assert(self); 165 166 self->len = 0; 167 } 168 169 static inline bool 170 mem_pool_prealloc(struct mem_pool *self, u64 alignment, u64 size) { 171 assert(self); 172 173 return self->len + size <= self->cap || 174 mem_pool_resize(self, alignment, self->len + size); 175 } 176 177 static inline void * 178 mem_pool_alloc(struct mem_pool *self, u64 alignment, u64 size) { 179 assert(self); 180 assert(alignment); 181 assert(alignment == 1 || alignment % 2 == 0); 182 assert(size % alignment == 0); 183 184 u64 alignment_off = alignment - 1; 185 u64 aligned_len = (self->len + alignment_off) & ~alignment_off; 186 187 if (!mem_pool_prealloc(self, alignment, (aligned_len - self->len) + size)) 188 return NULL; 189 190 void *ptr = self->ptr + aligned_len; 191 self->len = aligned_len + size; 192 193 return ptr; 194 } 195 196 #define MEM_POOL_ALLOC(pool, type, count) \ 197 (type *)mem_pool_alloc((pool), alignof(type), (count) * sizeof(type)) 198 199 #ifdef __cplusplus 200 }; 201 #endif /* __cplusplus */ 202 203 #endif /* UTILS_H */