readfile: use regular file access when not a gzip
Allows for different behavior w/ compressed files, will also make it simpler to support other compression types, see: T56162
This commit is contained in:
@@ -1118,6 +1118,30 @@ static int *read_file_thumbnail(FileData *fd)
|
||||
/** \name File Data API
|
||||
* \{ */
|
||||
|
||||
/* Regular file reading. */
|
||||
|
||||
static int fd_read_data_from_file(FileData *filedata, void *buffer, uint size)
|
||||
{
|
||||
int readsize = read(filedata->filedes, buffer, size);
|
||||
|
||||
if (readsize < 0) {
|
||||
readsize = EOF;
|
||||
}
|
||||
else {
|
||||
filedata->file_offset += readsize;
|
||||
}
|
||||
|
||||
return (readsize);
|
||||
}
|
||||
|
||||
static off_t fd_seek_data_from_file(FileData *filedata, off_t offset, int whence)
|
||||
{
|
||||
filedata->file_offset = lseek(filedata->filedes, offset, whence);
|
||||
return filedata->file_offset;
|
||||
}
|
||||
|
||||
/* GZip file reading. */
|
||||
|
||||
static int fd_read_gzip_from_file(FileData *filedata, void *buffer, uint size)
|
||||
{
|
||||
int readsize = gzread(filedata->gzfiledes, buffer, size);
|
||||
@@ -1138,6 +1162,8 @@ static off_t fd_seek_gzip_from_file(FileData *filedata, off_t offset, int whence
|
||||
return filedata->file_offset;
|
||||
}
|
||||
|
||||
/* Memory reading. */
|
||||
|
||||
static int fd_read_from_memory(FileData *filedata, void *buffer, uint size)
|
||||
{
|
||||
/* don't read more bytes then there are available in the buffer */
|
||||
@@ -1149,6 +1175,8 @@ static int fd_read_from_memory(FileData *filedata, void *buffer, uint size)
|
||||
return (readsize);
|
||||
}
|
||||
|
||||
/* MemFile reading. */
|
||||
|
||||
static int fd_read_from_memfile(FileData *filedata, void *buffer, uint size)
|
||||
{
|
||||
static size_t seek = SIZE_MAX; /* the current position */
|
||||
@@ -1214,6 +1242,7 @@ static FileData *filedata_new(void)
|
||||
{
|
||||
FileData *fd = MEM_callocN(sizeof(FileData), "FileData");
|
||||
|
||||
fd->filedes = -1;
|
||||
fd->gzfiledes = NULL;
|
||||
|
||||
fd->memsdna = DNA_sdna_current_get();
|
||||
@@ -1250,18 +1279,72 @@ static FileData *blo_decode_and_check(FileData *fd, ReportList *reports)
|
||||
|
||||
static FileData *blo_filedata_from_file_open(const char *filepath, ReportList *reports)
|
||||
{
|
||||
FileDataReadFn *read_fn = NULL;
|
||||
FileDataSeekFn *seek_fn = NULL; /* Optional. */
|
||||
|
||||
int file = -1;
|
||||
gzFile gzfile = (gzFile)Z_NULL;
|
||||
|
||||
char header[7];
|
||||
|
||||
/* Regular file. */
|
||||
errno = 0;
|
||||
gzFile gzfile = BLI_gzopen(filepath, "rb");
|
||||
if (gzfile == (gzFile)Z_NULL) {
|
||||
file = BLI_open(filepath, O_BINARY | O_RDONLY, 0);
|
||||
if (file == -1) {
|
||||
BKE_reportf(reports, RPT_WARNING, "Unable to open '%s': %s",
|
||||
filepath, errno ? strerror(errno) : TIP_("unknown error reading file"));
|
||||
return NULL;
|
||||
}
|
||||
else if (read(file, header, sizeof(header)) != sizeof(header)) {
|
||||
BKE_reportf(reports, RPT_WARNING, "Unable to read '%s': %s",
|
||||
filepath, errno ? strerror(errno) : TIP_("insufficient content"));
|
||||
close(file);
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
lseek(file, 0, SEEK_SET);
|
||||
}
|
||||
|
||||
/* Regular file. */
|
||||
if (memcmp(header, "BLENDER", sizeof(header)) == 0) {
|
||||
read_fn = fd_read_data_from_file;
|
||||
seek_fn = fd_seek_data_from_file;
|
||||
}
|
||||
else {
|
||||
close(file);
|
||||
file = -1;
|
||||
}
|
||||
|
||||
/* Gzip file. */
|
||||
errno = 0;
|
||||
if ((read_fn == NULL) &&
|
||||
/* Check header magic. */
|
||||
(header[0] == 0x1f && header[1] == 0x8b))
|
||||
{
|
||||
gzfile = BLI_gzopen(filepath, "rb");
|
||||
if (gzfile == (gzFile)Z_NULL) {
|
||||
BKE_reportf(reports, RPT_WARNING, "Unable to open '%s': %s",
|
||||
filepath, errno ? strerror(errno) : TIP_("unknown error reading file"));
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
read_fn = fd_read_gzip_from_file;
|
||||
seek_fn = fd_seek_gzip_from_file;
|
||||
}
|
||||
}
|
||||
|
||||
if (read_fn == NULL) {
|
||||
BKE_reportf(reports, RPT_WARNING, "Unrecognized file format '%s'", filepath);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FileData *fd = filedata_new();
|
||||
|
||||
fd->filedes = file;
|
||||
fd->gzfiledes = gzfile;
|
||||
fd->read = fd_read_gzip_from_file;
|
||||
fd->seek = fd_seek_gzip_from_file;
|
||||
|
||||
fd->read = read_fn;
|
||||
fd->seek = seek_fn;
|
||||
|
||||
return fd;
|
||||
}
|
||||
@@ -1387,6 +1470,10 @@ FileData *blo_filedata_from_memfile(MemFile *memfile, ReportList *reports)
|
||||
void blo_filedata_free(FileData *fd)
|
||||
{
|
||||
if (fd) {
|
||||
if (fd->filedes != -1) {
|
||||
close(fd->filedes);
|
||||
}
|
||||
|
||||
if (fd->gzfiledes != NULL) {
|
||||
gzclose(fd->gzfiledes);
|
||||
}
|
||||
|
||||
@@ -48,6 +48,11 @@ enum eFileDataFlag {
|
||||
FD_FLAGS_NOT_MY_LIBMAP = 1 << 5,
|
||||
};
|
||||
|
||||
|
||||
|
||||
typedef int (FileDataReadFn)(struct FileData *filedata, void *buffer, unsigned int size);
|
||||
typedef off_t (FileDataSeekFn)(struct FileData *filedata, off_t offset, int whence);
|
||||
|
||||
typedef struct FileData {
|
||||
/** Linked list of BHeadN's. */
|
||||
ListBase listbase;
|
||||
@@ -55,8 +60,12 @@ typedef struct FileData {
|
||||
bool is_eof;
|
||||
int buffersize;
|
||||
off_t file_offset;
|
||||
int (*read)(struct FileData *filedata, void *buffer, unsigned int size);
|
||||
off_t (*seek)(struct FileData *filedata, off_t offset, int whence);
|
||||
|
||||
FileDataReadFn *read;
|
||||
FileDataSeekFn *seek;
|
||||
|
||||
/** Regular file reading. */
|
||||
int filedes;
|
||||
|
||||
/** Variables needed for reading from memory / stream. */
|
||||
const char *buffer;
|
||||
@@ -65,12 +74,12 @@ typedef struct FileData {
|
||||
|
||||
/** Variables needed for reading from file. */
|
||||
gzFile gzfiledes;
|
||||
/** Gzip stream for memory decompression. */
|
||||
z_stream strm;
|
||||
|
||||
/** Now only in use for library appending. */
|
||||
char relabase[FILE_MAX];
|
||||
|
||||
/** Gzip stream for memory decompression. */
|
||||
z_stream strm;
|
||||
|
||||
/** General reading variables. */
|
||||
struct SDNA *filesdna;
|
||||
|
||||
Reference in New Issue
Block a user