[Bf-blender-cvs] [de0119d] master: BLI_storage: util function BLI_file_read_as_mem

Campbell Barton noreply at git.blender.org
Mon Dec 14 07:25:23 CET 2015


Commit: de0119d087acb4e38488d6f472fb7d4f0de26c17
Author: Campbell Barton
Date:   Mon Dec 14 17:12:16 2015 +1100
Branches: master
https://developer.blender.org/rBde0119d087acb4e38488d6f472fb7d4f0de26c17

BLI_storage: util function BLI_file_read_as_mem

Use for text loading and pasting from file.

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

M	source/blender/blenkernel/BKE_text.h
M	source/blender/blenkernel/intern/text.c
M	source/blender/blenlib/BLI_fileops.h
M	source/blender/blenlib/intern/storage.c
M	source/blender/editors/curve/editfont.c

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

diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h
index 50e4fa4..e4cba75 100644
--- a/source/blender/blenkernel/BKE_text.h
+++ b/source/blender/blenkernel/BKE_text.h
@@ -41,6 +41,7 @@ struct Main;
 struct Text;
 struct TextLine;
 
+void			BKE_text_free_lines	(struct Text *text);
 void			BKE_text_free		(struct Text *text);
 void 			txt_set_undostate	(int u);
 int 			txt_get_undostate	(void);
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 964599b..cdc4855 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -152,17 +152,28 @@ static void init_undo_text(Text *text)
 	text->undo_buf = MEM_mallocN(text->undo_len, "undo buf");
 }
 
-void BKE_text_free(Text *text)
+/**
+ * \note caller must handle `undo_buf` and `compiled` members.
+ */
+void BKE_text_free_lines(Text *text)
 {
-	TextLine *tmp;
-
-	for (tmp = text->lines.first; tmp; tmp = tmp->next) {
+	for (TextLine *tmp = text->lines.first, *tmp_next; tmp; tmp = tmp_next) {
+		tmp_next = tmp->next;
 		MEM_freeN(tmp->line);
-		if (tmp->format)
+		if (tmp->format) {
 			MEM_freeN(tmp->format);
+		}
+		MEM_freeN(tmp);
 	}
-	
-	BLI_freelistN(&text->lines);
+
+	BLI_listbase_clear(&text->lines);
+
+	text->curl = text->sell = NULL;
+}
+
+void BKE_text_free(Text *text)
+{
+	BKE_text_free_lines(text);
 
 	if (text->name) MEM_freeN(text->name);
 	MEM_freeN(text->undo_buf);
@@ -339,63 +350,40 @@ static void text_from_buf(Text *text, const unsigned char *buffer, const int len
 
 bool BKE_text_reload(Text *text)
 {
-	FILE *fp;
-	int len;
 	unsigned char *buffer;
-	TextLine *tmp;
-	char str[FILE_MAX];
+	size_t buffer_len;
+	char filepath_abs[FILE_MAX];
 	BLI_stat_t st;
 
 	if (!text->name) {
 		return false;
 	}
 
-	BLI_strncpy(str, text->name, FILE_MAX);
-	BLI_path_abs(str, G.main->name);
+	BLI_strncpy(filepath_abs, text->name, FILE_MAX);
+	BLI_path_abs(filepath_abs, G.main->name);
 	
-	fp = BLI_fopen(str, "r");
-	if (fp == NULL) {
-		return false;
-	}
-	fseek(fp, 0L, SEEK_END);
-	len = ftell(fp);
-	fseek(fp, 0L, SEEK_SET);
-	if (UNLIKELY(len == -1)) {
-		fclose(fp);
+	buffer = BLI_file_read_as_mem(filepath_abs, 0, &buffer_len);
+	if (buffer == NULL) {
 		return false;
 	}
 
 	/* free memory: */
-
-	for (tmp = text->lines.first; tmp; tmp = tmp->next) {
-		MEM_freeN(tmp->line);
-		if (tmp->format) MEM_freeN(tmp->format);
-	}
-	
-	BLI_freelistN(&text->lines);
-
-	BLI_listbase_clear(&text->lines);
-	text->curl = text->sell = NULL;
+	BKE_text_free_lines(text);
+	txt_make_dirty(text);
 
 	/* clear undo buffer */
 	MEM_freeN(text->undo_buf);
 	init_undo_text(text);
 
-	buffer = MEM_mallocN(len, "text_buffer");
-	/* under windows fread can return less than len bytes because
-	 * of CR stripping */
-	len = fread(buffer, 1, len, fp);
 
-	fclose(fp);
-
-	if (BLI_stat(str, &st) != -1) {
+	if (BLI_stat(filepath_abs, &st) != -1) {
 		text->mtime = st.st_mtime;
 	}
 	else {
 		text->mtime = 0;
 	}
 
-	text_from_buf(text, buffer, len);
+	text_from_buf(text, buffer, buffer_len);
 
 	MEM_freeN(buffer);
 	return true;
@@ -403,31 +391,22 @@ bool BKE_text_reload(Text *text)
 
 Text *BKE_text_load_ex(Main *bmain, const char *file, const char *relpath, const bool is_internal)
 {
-	FILE *fp;
-	int len;
 	unsigned char *buffer;
+	size_t buffer_len;
 	Text *ta;
-	char str[FILE_MAX];
+	char filepath_abs[FILE_MAX];
 	BLI_stat_t st;
 
-	BLI_strncpy(str, file, FILE_MAX);
+	BLI_strncpy(filepath_abs, file, FILE_MAX);
 	if (relpath) /* can be NULL (bg mode) */
-		BLI_path_abs(str, relpath);
+		BLI_path_abs(filepath_abs, relpath);
 	
-	fp = BLI_fopen(str, "r");
-	if (fp == NULL) {
-		return NULL;
-	}
-
-	fseek(fp, 0L, SEEK_END);
-	len = ftell(fp);
-	fseek(fp, 0L, SEEK_SET);
-	if (UNLIKELY(len == -1)) {
-		fclose(fp);
-		return NULL;
+	buffer = BLI_file_read_as_mem(filepath_abs, 0, &buffer_len);
+	if (buffer == NULL) {
+		return false;
 	}
 
-	ta = BKE_libblock_alloc(bmain, ID_TXT, BLI_path_basename(str));
+	ta = BKE_libblock_alloc(bmain, ID_TXT, BLI_path_basename(filepath_abs));
 
 	BLI_listbase_clear(&ta->lines);
 	ta->curl = ta->sell = NULL;
@@ -445,22 +424,15 @@ Text *BKE_text_load_ex(Main *bmain, const char *file, const char *relpath, const
 
 	/* clear undo buffer */
 	init_undo_text(ta);
-	
-	buffer = MEM_mallocN(len, "text_buffer");
-	/* under windows fread can return less than len bytes because
-	 * of CR stripping */
-	len = fread(buffer, 1, len, fp);
-
-	fclose(fp);
 
-	if (BLI_stat(str, &st) != -1) {
+	if (BLI_stat(filepath_abs, &st) != -1) {
 		ta->mtime = st.st_mtime;
 	}
 	else {
 		ta->mtime = 0;
 	}
 	
-	text_from_buf(ta, buffer, len);
+	text_from_buf(ta, buffer, buffer_len);
 	
 	MEM_freeN(buffer);
 
diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h
index 53ebc81..b842c30 100644
--- a/source/blender/blenlib/BLI_fileops.h
+++ b/source/blender/blenlib/BLI_fileops.h
@@ -130,6 +130,7 @@ bool   BLI_file_older(const char *file1, const char *file2) ATTR_WARN_UNUSED_RES
 
 /* read ascii file as lines, empty list if reading fails */
 struct LinkNode *BLI_file_read_as_lines(const char *file) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+void  *BLI_file_read_as_mem(const char *filepath, size_t pad_bytes, size_t *r_size);
 void   BLI_file_free_lines(struct LinkNode *lines);
 
 /* this weirdo pops up in two places ... */
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index f7a8664..a107c84 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -287,6 +287,39 @@ bool BLI_is_file(const char *path)
 	return (mode && !S_ISDIR(mode));
 }
 
+void *BLI_file_read_as_mem(const char *filepath, size_t pad_bytes, size_t *r_size)
+{
+	FILE *fp = BLI_fopen(filepath, "r");
+	void *mem = NULL;
+
+	if (fp) {
+		fseek(fp, 0L, SEEK_END);
+		const long int filelen = ftell(fp);
+		if (filelen == -1) {
+			goto finally;
+		}
+		fseek(fp, 0L, SEEK_SET);
+
+		mem = MEM_mallocN(filelen + pad_bytes, __func__);
+		if (mem == NULL) {
+			goto finally;
+		}
+
+		if (fread(mem, 1, filelen, fp) != filelen) {
+			MEM_freeN(mem);
+			mem = NULL;
+			goto finally;
+		}
+
+		*r_size = filelen;
+	}
+
+finally:
+	fclose(fp);
+	return mem;
+}
+
+
 /**
  * Reads the contents of a text file and returns the lines in a linked list.
  */
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index 9fba646..542c7fe 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -345,50 +345,18 @@ static bool font_paste_utf8(bContext *C, const char *str, const size_t str_len)
 static int paste_from_file(bContext *C, ReportList *reports, const char *filename)
 {
 	Object *obedit = CTX_data_edit_object(C);
-	FILE *fp;
 	char *strp;
-	int filelen;
+	size_t filelen;
 	int retval;
 
-	fp = BLI_fopen(filename, "r");
-
-	if (!fp) {
+	strp = BLI_file_read_as_mem(filename, 1, &filelen);
+	if (strp == NULL) {
 		BKE_reportf(reports, RPT_ERROR, "Failed to open file '%s'", filename);
 		return OPERATOR_CANCELLED;
 	}
+	strp[filelen] = 0;
 
-	fseek(fp, 0L, SEEK_END);
-
-	errno = 0;
-	filelen = ftell(fp);
-	if (filelen == -1) {
-		goto fail;
-	}
-
-	if (filelen <= MAXTEXT) {
-		strp = MEM_mallocN(filelen + 4, "tempstr");
-
-		fseek(fp, 0L, SEEK_SET);
-
-		/* fread() instead of read(), because windows read() converts text
-		 * to DOS \r\n linebreaks, causing double linebreaks in the 3d text */
-		errno = 0;
-		filelen = fread(strp, 1, filelen, fp);
-		if (filelen == -1) {
-			MEM_freeN(strp);
-			goto fail;
-		}
-
-		strp[filelen] = 0;
-	}
-	else {
-		strp = NULL;
-	}
-
-	fclose(fp);
-
-
-	if (strp && font_paste_utf8(C, strp, filelen)) {
+	if (font_paste_utf8(C, strp, filelen)) {
 		text_update_edited(C, obedit, FO_EDIT);
 		retval = OPERATOR_FINISHED;
 
@@ -398,18 +366,9 @@ static int paste_from_file(bContext *C, ReportList *reports, const char *filenam
 		retval = OPERATOR_CANCELLED;
 	}
 
-	if (strp) {
-		MEM_freeN(strp);
-	}
+	MEM_freeN(strp);
 
 	return retval;
-
-
-	/* failed to seek or read */
-fail:
-	BKE_reportf(reports, RPT_ERROR, "Failed to read file '%s', %s", filename, strerror(errno));
-	fclose(fp);
-	return OPERATOR_CANCELLED;
 }
 
 static int paste_from_file_exec(bContext *C, wmOperator *op)




More information about the Bf-blender-cvs mailing list