diff --git a/slibs.h b/slibs.h index 98699f5..144e64b 100644 --- a/slibs.h +++ b/slibs.h @@ -42,6 +42,73 @@ #define sl_stringify(x) #x +typedef struct sl_metadata { + uint8_t magic; + uint32_t size; +} sl_metadata; +#define MD_SZ sizeof(sl_metadata) +#define MD_MAGIC 0xDE + +typedef void* sl_mem; + +void* sl_get_memory(sl_metadata* m); +sl_metadata* sl_get_metadata(sl_mem ptr); +void* sl_malloc(uint32_t size); +void* sl_realloc(sl_mem ptr, uint32_t size); +sl_mem __sl_serialize_struct(void* struc, size_t size); +#define sl_serialize_struct(struc) __sl_serialize_struct((void*)&struc, sizeof(struc)) + +#ifdef SL_IMPLEMENTATION +sl_mem sl_get_memory(sl_metadata* md) { + return (sl_mem)((uintptr_t)md + MD_SZ); +} + +sl_metadata* sl_get_metadata(sl_mem ptr) { + sl_metadata* md = (sl_metadata*)((uintptr_t)ptr - MD_SZ); + assert(md->magic == MD_MAGIC && "Metadata magic does not match."); + return md; +} + +sl_mem sl_malloc(uint32_t size) { + sl_metadata* md = (sl_metadata*)malloc(size + MD_SZ); + md->magic = MD_MAGIC; + md->size = size; + return sl_get_memory(md); +} + +void* sl_realloc(sl_mem ptr, uint32_t size) { + sl_metadata* md = (sl_metadata*)realloc(sl_get_metadata(ptr), size); + md->size = size; + return sl_get_memory(md); +} + +sl_mem __sl_serialize_struct(sl_mem struc, size_t size) { + sl_mem mem = NULL; + size_t offset = 0; + + for(int i = 0; i < size / sizeof(uintptr_t); i++) { + sl_mem ptr = *(sl_mem*)(struc + i * sizeof(void*)); + sl_metadata* md = sl_get_metadata(ptr); + + size_t full_size = md->size + MD_SZ; + + if(mem == NULL) { + mem = sl_malloc(full_size); + } else { + sl_metadata* mem_md = sl_get_metadata(mem); + mem = sl_realloc(mem, mem_md->size + full_size); + } + + memcpy(mem + offset, md, MD_SZ); + offset += MD_SZ; + memcpy(mem + offset, ptr, md->size); + offset += md->size; + } + + return mem; +} +#endif + #pragma endregion #pragma region Vector @@ -167,6 +234,14 @@ typedef sl_vec(char) sl_string; sl_ptr_release(smart_ptr); \ }); +void sl_read_file(const char *filename, sl_string *buffer); +void sl_write_file(const char *filename, const sl_string *buffer); +void sl_write_bytes(const char *filename, const uint8_t *data, size_t length); +uint8_t* sl_read_bytes(const char *filename, size_t *length); +void sl_write_metadata(const char* filename, sl_metadata* m); +void sl_write_memory(const char* filename, void* ptr); + +#ifdef SL_IMPLEMENTATION void sl_read_file(const char *filename, sl_string *buffer) { FILE *file = fopen(filename, "r"); if (!file) { @@ -185,6 +260,77 @@ void sl_read_file(const char *filename, sl_string *buffer) { fclose(file); } +void sl_write_file(const char *filename, const sl_string *buffer) { + FILE *file = fopen(filename, "w"); + if (!file) { + fprintf(stderr, "Error: could not open file %s\n", filename); + exit(1); + } + + for (size_t i = 0; i < buffer->size; i++) { + fputc(buffer->data[i], file); + } + + fclose(file); +} + +void sl_write_bytes(const char *filename, const uint8_t *data, size_t length) { + FILE *file = fopen(filename, "wb"); + if (!file) { + fprintf(stderr, "Error: could not open file %s\n", filename); + exit(1); + } + + size_t written = fwrite(data, sizeof(uint8_t), length, file); + if (written != length) { + fprintf(stderr, "Error: could not write all data to file %s\n", filename); + fclose(file); + exit(1); + } + + fclose(file); +} + +uint8_t* sl_read_bytes(const char *filename, size_t *length) { + FILE *file = fopen(filename, "rb"); + if (!file) { + fprintf(stderr, "Error: could not open file %s\n", filename); + exit(1); + } + + fseek(file, 0, SEEK_END); + size_t file_size = ftell(file); + fseek(file, 0, SEEK_SET); + + uint8_t *data = (uint8_t *)malloc(file_size); + if (!data) { + fprintf(stderr, "Error: could not allocate memory\n"); + fclose(file); + exit(1); + } + + size_t read = fread(data, sizeof(uint8_t), file_size, file); + if (read != file_size) { + fprintf(stderr, "Error: could not read all data from file %s\n", filename); + free(data); + fclose(file); + exit(1); + } + + fclose(file); + if(length != NULL) *length = file_size; + return data; +} + +void sl_write_metadata(const char* filename, sl_metadata* m) { + sl_write_bytes(filename, sl_get_memory(m), m->size); +} + +void sl_write_memory(const char* filename, void* ptr) { + sl_write_metadata(filename, sl_get_metadata(ptr)); +} +#endif + #pragma endregion #endif // SLIBS_H