Cleanup: de-duplicate file reading code
Also remove goto's.
This commit is contained in:
@@ -297,56 +297,72 @@ bool BLI_is_file(const char *path)
|
|||||||
return (mode && !S_ISDIR(mode));
|
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)
|
void *BLI_file_read_text_as_mem(const char *filepath, size_t pad_bytes, size_t *r_size)
|
||||||
{
|
{
|
||||||
FILE *fp = BLI_fopen(filepath, "r");
|
FILE *fp = BLI_fopen(filepath, "r");
|
||||||
void *mem = NULL;
|
void *mem = NULL;
|
||||||
|
|
||||||
if (fp) {
|
if (fp) {
|
||||||
struct stat st;
|
mem = file_read_data_as_mem_impl(fp, true, pad_bytes, r_size);
|
||||||
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:
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mem;
|
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");
|
FILE *fp = BLI_fopen(filepath, "rb");
|
||||||
void *mem = NULL;
|
void *mem = NULL;
|
||||||
|
|
||||||
if (fp) {
|
if (fp) {
|
||||||
struct stat st;
|
mem = file_read_data_as_mem_impl(fp, false, pad_bytes, r_size);
|
||||||
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:
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mem;
|
return mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user