Skip to content

Instantly share code, notes, and snippets.

@justinmeiners
Last active October 25, 2022 20:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save justinmeiners/df2dfd383cc3903bf4b39dac3bdc716c to your computer and use it in GitHub Desktop.
Save justinmeiners/df2dfd383cc3903bf4b39dac3bdc716c to your computer and use it in GitHub Desktop.
Read an entire file into a buffer (without race conditions or seeking).
void* fread_all(FILE* file, size_t* out_size) {
const size_t BLOCK_SIZE = 32 * 1024;
const size_t MEDIUM_SIZE = 10 * 1024 * 1024;
*out_size = 0;
size_t cap = 0;
char* data = NULL;
while (1) {
if (*out_size + BLOCK_SIZE > cap) {
if (cap > MEDIUM_SIZE) {
cap = (cap * 3) / 2;
} else if (cap < BLOCK_SIZE) {
cap = BLOCK_SIZE;
} else {
cap *= 2;
}
void* new_data = realloc(data, cap);
if (!new_data) {
*out_size = 0;
free(data);
return NULL;
}
data = new_data;
}
size_t read = fread(data + *out_size, 1, BLOCK_SIZE, file);
*out_size += read;
if (read < BLOCK_SIZE) {
if (ferror(file)) {
*out_size = 0;
free(data);
return NULL;
} else {
return data;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment