Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2019-02-24 04:34:41 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-02-24 04:41:37 +0300
commit8ed82e82e6a29461cbf2836fbbe7ca2f0557cc6e (patch)
tree0ea42d30a070e589dae8379edf25f75d1d896eaf /source/blender/blenloader
parent519982fd3ea0ab240029db5b095bbc31c6d0cb05 (diff)
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
Diffstat (limited to 'source/blender/blenloader')
-rw-r--r--source/blender/blenloader/intern/readfile.c95
-rw-r--r--source/blender/blenloader/intern/readfile.h17
2 files changed, 104 insertions, 8 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index df12a4f4321..b04fa5d433e 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -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);
}
diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h
index 4fe65934107..49ae2849f4f 100644
--- a/source/blender/blenloader/intern/readfile.h
+++ b/source/blender/blenloader/intern/readfile.h
@@ -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;