Cleanup: de-duplicate file reading code

Also remove goto's.
This commit is contained in:
2019-07-30 10:43:07 +10:00
parent f1516ae637
commit a345f56ce3

View File

@@ -297,56 +297,72 @@ bool BLI_is_file(const char *path)
return (mode && !S_ISDIR(mode));
}
/**
* Use for both text and binary file reading.
*/
static void *file_read_data_as_mem_impl(FILE *fp,
bool read_size_exact,
size_t pad_bytes,
size_t *r_size)
{
struct stat st;
if (fstat(fileno(fp), &st) == -1) {
return NULL;
}
if (S_ISDIR(st.st_mode)) {
return NULL;
}
if (fseek(fp, 0L, SEEK_END) == -1) {
return NULL;
}
/* Don't use the 'st_size' because it may be the symlink. */
const long int filelen = ftell(fp);
if (filelen == -1) {
return NULL;
}
if (fseek(fp, 0L, SEEK_SET) == -1) {
return NULL;
}
void *mem = MEM_mallocN(filelen + pad_bytes, __func__);
if (mem == NULL) {
return NULL;
}
const long int filelen_read = fread(mem, 1, filelen, fp);
if ((filelen_read < 0) || ferror(fp)) {
MEM_freeN(mem);
return NULL;
}
if (read_size_exact) {
if (filelen_read != filelen) {
MEM_freeN(mem);
return NULL;
}
}
else {
if (filelen_read < filelen) {
mem = MEM_reallocN(mem, filelen_read + pad_bytes);
if (mem == NULL) {
return NULL;
}
}
}
*r_size = filelen_read;
return mem;
}
void *BLI_file_read_text_as_mem(const char *filepath, size_t pad_bytes, size_t *r_size)
{
FILE *fp = BLI_fopen(filepath, "r");
void *mem = NULL;
if (fp) {
struct stat st;
if (fstat(fileno(fp), &st) == -1) {
goto finally;
}
if (S_ISDIR(st.st_mode)) {
goto finally;
}
if (fseek(fp, 0L, SEEK_END) == -1) {
goto finally;
}
/* Don't use the 'st_size' because it may be the symlink. */
const long int filelen = ftell(fp);
if (filelen == -1) {
goto finally;
}
if (fseek(fp, 0L, SEEK_SET) == -1) {
goto finally;
}
mem = MEM_mallocN(filelen + pad_bytes, __func__);
if (mem == NULL) {
goto finally;
}
const long int filelen_read = fread(mem, 1, filelen, fp);
if ((filelen_read < 0) || ferror(fp)) {
MEM_freeN(mem);
mem = NULL;
goto finally;
}
if (filelen_read < filelen) {
mem = MEM_reallocN(mem, filelen_read + pad_bytes);
if (mem == NULL) {
goto finally;
}
}
*r_size = filelen_read;
finally:
mem = file_read_data_as_mem_impl(fp, true, pad_bytes, r_size);
fclose(fp);
}
return mem;
}
@@ -354,45 +370,10 @@ void *BLI_file_read_binary_as_mem(const char *filepath, size_t pad_bytes, size_t
{
FILE *fp = BLI_fopen(filepath, "rb");
void *mem = NULL;
if (fp) {
struct stat st;
if (fstat(fileno(fp), &st) == -1) {
goto finally;
}
if (S_ISDIR(st.st_mode)) {
goto finally;
}
if (fseek(fp, 0L, SEEK_END) == -1) {
goto finally;
}
/* Don't use the 'st_size' because it may be the symlink. */
const long int filelen = ftell(fp);
if (filelen == -1) {
goto finally;
}
if (fseek(fp, 0L, SEEK_SET) == -1) {
goto finally;
}
mem = MEM_mallocN(filelen + pad_bytes, __func__);
if (mem == NULL) {
goto finally;
}
const long int filelen_read = fread(mem, 1, filelen, fp);
if ((filelen_read != filelen) || ferror(fp)) {
MEM_freeN(mem);
mem = NULL;
goto finally;
}
*r_size = filelen_read;
finally:
mem = file_read_data_as_mem_impl(fp, false, pad_bytes, r_size);
fclose(fp);
}
return mem;
}