/* file-handler.c * Created: 2023-08-25 * Author: Aryadev Chavali * Description: Implementations of writing and loading state from files */ #include #include #include "./lib.h" #define CHUNK_SIZE 1024 typedef struct Buffer { char *data; size_t used, available; } buffer_t; void buffer_init(buffer_t *buffer) { *buffer = (buffer_t){calloc(CHUNK_SIZE, sizeof(*buffer->data)), 0, CHUNK_SIZE}; } void buffer_realloc(buffer_t *buffer, size_t new_size) { buffer->data = realloc(buffer->data, new_size); buffer->available = new_size; } void buffer_tighten(buffer_t *buffer) { buffer->data = realloc(buffer->data, buffer->used + 1); buffer->data[buffer->used] = '\0'; buffer->available = buffer->used; } #define IS_DIGIT(c) (c <= '9' && c >= '0') bool load_from_file(state_t *state, const char *filepath) { // Read file completely FILE *fp = fopen(filepath, "r"); if (!fp) return false; buffer_t buffer; buffer_init(&buffer); size_t acc = 0; size_t bytes_read = 0; while ((bytes_read = fread(buffer.data + acc, sizeof(*buffer.data), CHUNK_SIZE, fp)) != 0) { buffer.used += bytes_read; acc += bytes_read; buffer_realloc(&buffer, buffer.available + CHUNK_SIZE); } fclose(fp); buffer_tighten(&buffer); // first line is width state->dwidth = atoi(buffer.data); state->data = calloc(state->dwidth * state->dwidth, sizeof(*state->data)); state->multiplier = state->window_len / state->dwidth; size_t line_size = strcspn(buffer.data, "\n"); char *ptr = buffer.data + line_size + 1; size_t i = 0; for (ptr = strpbrk(ptr, "\n"); ptr && i < state->dwidth; ptr = strpbrk(ptr, "\n"), ++i) { if (ptr[1] == '\0') break; ++ptr; size_t j = 0; size_t line_size = strcspn(ptr, "\n"); for (size_t lptr = 0; lptr < line_size;) { size_t end_of_digit = lptr; for (; IS_DIGIT(ptr[end_of_digit]); ++end_of_digit) continue; state->data[(i * state->dwidth) + j] = atoi(ptr + lptr); lptr = end_of_digit + 1; ++j; } ++ptr; } free(buffer.data); return true; } bool write_to_file(state_t *state, const char *filepath) { FILE *fp = fopen(filepath, "w"); fprintf(fp, "%lu\n", state->dwidth); for (size_t i = 0; i < state->dwidth; ++i) { for (size_t j = 0; j < state->dwidth; ++j) { fprintf(fp, "%d", state->data[(i * state->dwidth) + j]); if (j != state->dwidth - 1) fprintf(fp, ","); } fprintf(fp, "\n"); } fclose(fp); return true; }