diff --git a/includes/futil.h b/includes/futil.h new file mode 100644 index 0000000..d062d45 --- /dev/null +++ b/includes/futil.h @@ -0,0 +1,15 @@ +#ifndef FUTIL_H +#define FUTIL_H + +#include +#include +#include +#include + +#ifndef FUTIL_READ_SIZE +#define FUTIL_READ_SIZE 2097152 //Default here is 2MiB +#endif + +int ReadAllString(const char*, char**, size_t*); + +#endif \ No newline at end of file diff --git a/src/futil.c b/src/futil.c new file mode 100644 index 0000000..ee18f6c --- /dev/null +++ b/src/futil.c @@ -0,0 +1,59 @@ +#include "../includes/futil.h" +#include + +//Reference: https://stackoverflow.com/a/44894946 +int ReadAllString(const char* path, char** content_ptr, size_t* bytes_read) { + if (!path || !content_ptr || !bytes_read) return 0; + + FILE *file; + file = fopen(path, "rb"); + + if (!file) { + fprintf(stderr, "Failed to open '%s'. %s.\n", path, strerror(errno)); + return 0; + } + + char *content = NULL, *temp; + size_t used, capacity, read; + + while(1) { + if (used + FUTIL_READ_SIZE + 1 > capacity) { + capacity = used + FUTIL_READ_SIZE + 1; + + temp = realloc(content, capacity); + + if (!temp) { + fprintf(stderr, "Failed to realloc space for file contents. %s.\n", strerror(errno)); + free(content); + fclose(file); + return 0; + } + + content = temp; + } + + read = fread(content + used, 1, FUTIL_READ_SIZE, file); + + if (read == 0) break; + + used += read; + } + + fclose(file); + //Shrink the buffer to fit just the contents of the buffer. + temp = realloc(content, used + 1); + + if (!temp) { + fprintf(stderr, "Failed to realloc to only hold the file contents. %s.\n", strerror(errno)); + free(content); + return 0; + } + + content = temp; + content[used] = '\0'; + + *content_ptr = content; + *bytes_read = used; + + return 1; +} \ No newline at end of file