#include #include #include #include "common.h" struct blob blob_new(void) { return (struct blob) {.data = NULL, .size = 0}; } void blob_append(struct blob *const blob, void const *const data, size_t const size) { char *new = realloc(blob->data, blob->size + size); if (new == NULL) { abort(); } memcpy(new + blob->size, data, size); blob->data = new; blob->size += size; } void blob_free(struct blob *const blob) { free(blob->data); blob->data = NULL; blob->size = 0; } struct blob load_file(char const *const name) { const size_t START_SIZE = 8192; FILE *file = fopen(name, "rb"); if (file == NULL) { return (struct blob) {.data = NULL}; } char *data = malloc(START_SIZE); size_t allocated = START_SIZE; size_t used = 0; while (1) { size_t read = fread(data + used, 1, allocated - used, file); if (read != allocated - used) { used += read; break; } used += read; allocated *= 2; void *const newdata = realloc(data, allocated); if (newdata == NULL) { goto realloc_error; } data = newdata; } if (used == 0) { free(data); fclose(file); return (struct blob) {.data = NULL, .size = 0}; } void *const newdata = realloc(data, used); if (newdata == NULL) { goto realloc_error; } fclose(file); return (struct blob) {.data = newdata, .size = used}; realloc_error: free(data); fclose(file); return (struct blob) {.data = NULL}; }