[Bf-blender-cvs] [8ed82e82e6a] master: readfile: use regular file access when not a gzip

Campbell Barton noreply at git.blender.org
Sun Feb 24 02:51:39 CET 2019


Commit: 8ed82e82e6a29461cbf2836fbbe7ca2f0557cc6e
Author: Campbell Barton
Date:   Sun Feb 24 12:34:41 2019 +1100
Branches: master
https://developer.blender.org/rB8ed82e82e6a29461cbf2836fbbe7ca2f0557cc6e

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

===================================================================

M	source/blender/blenloader/intern/readfile.c
M	source/blender/blenloader/intern/readfile.h

===================================================================

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;



More information about the Bf-blender-cvs mailing list