brzeszczot

brzeszczot.git
git clone git://git.lenczewski.org/brzeszczot.git
Log | Files | Refs

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 */