From 0183098f9cb37a5389b8ff19dee98a4293752ce6 Mon Sep 17 00:00:00 2001 From: "Alex Xu (Hello71)" Date: Wed, 8 Aug 2018 15:16:14 -0400 Subject: Initial commit --- readall.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 readall.c (limited to 'readall.c') diff --git a/readall.c b/readall.c new file mode 100644 index 0000000..9f55697 --- /dev/null +++ b/readall.c @@ -0,0 +1,82 @@ +/* by Nominal Animal, 2017: https://stackoverflow.com/a/44894946 */ + +#include +#include +#include + +#include "readall.h" + +/* Size of each input chunk to be + read and allocate for. */ +#ifndef READALL_CHUNK +#define READALL_CHUNK 262144 +#endif + +/* This function returns one of the READALL_ constants above. + If the return value is zero == READALL_OK, then: + (*dataptr) points to a dynamically allocated buffer, with + (*sizeptr) chars read from the file. + The buffer is allocated for one extra char, which is NUL, + and automatically appended after the data. + Initial values of (*dataptr) and (*sizeptr) are ignored. +*/ +int readall(FILE *in, char **dataptr, size_t *sizeptr) +{ + char *data = NULL, *temp; + size_t size = 0; + size_t used = 0; + size_t n; + + /* None of the parameters can be NULL. */ + if (in == NULL || dataptr == NULL || sizeptr == NULL) + return READALL_INVALID; + + /* A read error already occurred? */ + if (ferror(in)) + return READALL_ERROR; + + while (1) { + + if (used + READALL_CHUNK + 1 > size) { + size = used + READALL_CHUNK + 1; + + /* Overflow check. Some ANSI C compilers + may optimize this away, though. */ + if (size <= used) { + free(data); + return READALL_TOOMUCH; + } + + temp = realloc(data, size); + if (temp == NULL) { + free(data); + return READALL_NOMEM; + } + data = temp; + } + + n = fread(data + used, 1, READALL_CHUNK, in); + if (n == 0) + break; + + used += n; + } + + if (ferror(in)) { + free(data); + return READALL_ERROR; + } + + temp = realloc(data, used + 1); + if (temp == NULL) { + free(data); + return READALL_NOMEM; + } + data = temp; + data[used] = '\0'; + + *dataptr = data; + *sizeptr = used; + + return READALL_OK; +} -- cgit v1.2.3-54-g00ecf