You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
194 lines
3.7 KiB
194 lines
3.7 KiB
|
|
#ifndef UTIL_H |
|
#define UTIL_H |
|
|
|
#include <cassert> |
|
#include <cstring> |
|
#include <cstdio> |
|
#include <cstdlib> |
|
|
|
#include "dumbLog.h" |
|
#include "types.h" |
|
|
|
|
|
//----------------- |
|
// Hashing |
|
|
|
// NOTE: FNV1a hashing algorithm http://www.isthe.com/chongo/tech/comp/fnv/ |
|
#define FNV1_64_INIT ((u64) 0xcbf29ce484222325ULL) |
|
#define FNV_64_PRIME ((u64) 0x100000001b3ULL) |
|
u64 utilFNV64a_str(const char* str, u64 hval = FNV1_64_INIT); |
|
|
|
//----------------- |
|
// Memory allocation |
|
|
|
struct MemoryArena |
|
{ |
|
size_t max_size; |
|
size_t free_size; |
|
void* head; |
|
void* next_free; |
|
}; |
|
|
|
#define DEFAULT_ARENA_SIZE 10 * 1024 * 1024 // 10MB |
|
MemoryArena* arenaInit(size_t initial_size = DEFAULT_ARENA_SIZE); |
|
|
|
void arenaFree(MemoryArena*& arena); |
|
|
|
u32 arenaGetFreeSize(MemoryArena* arena); |
|
|
|
#define ARENA_ALLOC(arena, type, count) \ |
|
(type*) arenaAllocateBlock(arena, sizeof(type) * count) |
|
void* arenaAllocateBlock(MemoryArena* arena, size_t block_size); |
|
|
|
void* arenaGetAddressOffset(void* address, u32 offset); |
|
|
|
#define MAX_NAME_LENGTH 256 |
|
char* arenaCopyCStr(MemoryArena* arena, |
|
const char* input, |
|
u32 max_len = MAX_NAME_LENGTH); |
|
|
|
#define UTIL_ALLOC(count, type) (type*) utilAllocate(count, sizeof(type)) |
|
void* utilAllocate(u32 count, u32 type_size); |
|
|
|
char* utilAllocateCStr(const char* str, u32 max_len = 256); |
|
|
|
void utilSafeFree(void* p); |
|
|
|
//--------------- |
|
// C string utils |
|
|
|
bool utilCStrMatch(const char* str1, const char* str2); |
|
|
|
|
|
#endif // UTIL_H |
|
|
|
|
|
#ifdef UTIL_IMPLEMENTATION |
|
|
|
//----------------- |
|
// Hashing |
|
|
|
u64 |
|
utilFNV64a_str(const char* str, u64 hval) |
|
{ |
|
unsigned char* s = (unsigned char *)str; // unsigned string |
|
|
|
// FNV-1a hash each octet of the string |
|
while (*s) { |
|
// xor the bottom with the current octet |
|
hval ^= (uint64_t)*s++; |
|
// multiply by the 64 bit FNV magic prime mod 2^64 |
|
hval *= FNV_64_PRIME; |
|
} |
|
|
|
return hval; |
|
} |
|
|
|
//----------------- |
|
// Memory allocation |
|
|
|
MemoryArena* |
|
arenaInit(size_t initial_size) |
|
{ |
|
u32 sz = sizeof(MemoryArena); |
|
MemoryArena* arena = |
|
(MemoryArena*) std::calloc(initial_size + sz, sizeof(u8)); |
|
arena->head = arena->next_free = (uint8_t*) arena + sz; |
|
arena->max_size = initial_size; |
|
return arena; |
|
} |
|
|
|
void |
|
arenaFree(MemoryArena*& arena) |
|
{ |
|
if (arena != nullptr) { |
|
std::free(arena); |
|
arena = nullptr; |
|
} |
|
} |
|
|
|
uint |
|
arenaGetFreeSize(MemoryArena* arena) |
|
{ |
|
return (uint8_t*) arena->head |
|
+ arena->max_size |
|
- (uint8_t*) arena->next_free; |
|
} |
|
|
|
void* |
|
arenaAllocateBlock(MemoryArena* arena, size_t block_size) |
|
{ |
|
// TODO: resizable memory arena |
|
assert(arenaGetFreeSize(arena) >= block_size); |
|
assert(block_size > 0); |
|
void* ret = arena->next_free; |
|
arena->next_free = (uint8_t*) arena->next_free + block_size; |
|
arena->free_size = arenaGetFreeSize(arena); |
|
return ret; |
|
} |
|
|
|
void* |
|
arenaGetAddressOffset(void* address, u32 offset) |
|
{ |
|
return (void*) ((u8*) address + offset); |
|
} |
|
|
|
char* |
|
arenaCopyCStr(MemoryArena* arena, const char* input, u32 max_len) |
|
{ |
|
u32 name_len = std::strlen(input) + 1; |
|
assert(name_len > 1 && name_len < max_len); |
|
char* out = ARENA_ALLOC(arena, char, name_len); |
|
std::strncpy(out, input, name_len); |
|
return out; |
|
} |
|
|
|
void* |
|
utilAllocate(u32 count, u32 type_size) |
|
{ |
|
void* out = std::calloc(count, type_size); |
|
assert(out != nullptr); |
|
return out; |
|
} |
|
|
|
char* |
|
utilAllocateCStr(const char* str, u32 max_len) |
|
{ |
|
u32 len = strlen(str) + 1; |
|
|
|
if (len > max_len) { |
|
LOGF(Error, "%s , longer than %i\n", str, max_len); |
|
return nullptr; |
|
} |
|
|
|
char* out = (char*) std::calloc(len, sizeof(u8)); |
|
strncpy(out, str, len - 1); |
|
return out; |
|
} |
|
|
|
void |
|
utilSafeFree(void* p) |
|
{ |
|
if (p) |
|
free(p); |
|
else |
|
LOGF(Error, "free called on nullptr\n"); |
|
} |
|
|
|
//--------------- |
|
// C string utils |
|
|
|
bool |
|
utilCStrMatch(const char* str1, const char* str2) |
|
{ |
|
if (!str1 || !str2) |
|
return false; |
|
|
|
u32 l1 = strlen(str1); |
|
u32 l2 = strlen(str2); |
|
|
|
return (l1 == l2 && strncmp(str1, str2, l1) == 0); |
|
} |
|
|
|
#endif
|
|
|