[PATCH] Files: fix a path encoding issue on Windows

Lubomir I. Ivanov neolit123 at gmail.com
Tue Dec 17 06:10:43 UTC 2013


From: "Lubomir I. Ivanov" <neolit123 at gmail.com>

The Qt frontend currently uses a C backend e.g. file.c,
but Windows does things it's own way and we cannot quite
relly on methods such as open() to work for paths with
special characters.

A solution for that is to always pass UTF-8 encoded filenames
(that may eventually reach file.c:readfile()) and then
if on Windows converted such to UTF-16 for use with
the Windows's specific function _wopen().

This possibly avoids re-writing file.c to use Qt/QFile.

Signed-off-by: Lubomir I. Ivanov <neolit123 at gmail.com>
---
this new version also fixes the file names for
MainWindow::importFiles()
---
 file.c               | 14 ++++++++++++++
 qt-ui/mainwindow.cpp |  4 ++--
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/file.c b/file.c
index 9fd44d9..91749df 100644
--- a/file.c
+++ b/file.c
@@ -15,6 +15,9 @@
 #ifndef O_BINARY
 #define O_BINARY 0
 #endif
+#ifdef WIN32
+#include <windows.h>
+#endif
 
 int readfile(const char *filename, struct memblock *mem)
 {
@@ -25,7 +28,18 @@ int readfile(const char *filename, struct memblock *mem)
 	mem->buffer = NULL;
 	mem->size = 0;
 
+/* filename should be UTF-8 encoded and then we can convert it to the 2 byte wchar_t on win32
+ * and use _wopen(). */
+#ifdef WIN32
+	wchar_t filename_w[MAX_PATH] = { 0 };
+	int sz = MultiByteToWideChar(CP_UTF8, 0, filename, -1, NULL, 0);
+	if (!sz)
+		return -1;
+	MultiByteToWideChar(CP_UTF8, 0, filename, -1, filename_w, sz);
+	fd = _wopen(filename_w, O_RDONLY | O_BINARY, 0);
+#else
 	fd = open(filename, O_RDONLY | O_BINARY, 0);
+#endif
 	if (fd < 0)
 		return fd;
 	ret = fstat(fd, &st);
diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp
index fbe3779..f236bd8 100644
--- a/qt-ui/mainwindow.cpp
+++ b/qt-ui/mainwindow.cpp
@@ -822,7 +822,7 @@ void MainWindow::importFiles(const QStringList fileNames)
 	QByteArray fileNamePtr;
 	char *error = NULL;
 	for (int i = 0; i < fileNames.size(); ++i) {
-		fileNamePtr = fileNames.at(i).toLocal8Bit();
+		fileNamePtr = fileNames.at(i).toUtf8();
 		parse_file(fileNamePtr.data(), &error);
 		if (error != NULL) {
 			showError(error);
@@ -843,7 +843,7 @@ void MainWindow::loadFiles(const QStringList fileNames)
 	QByteArray fileNamePtr;
 
 	for (int i = 0; i < fileNames.size(); ++i) {
-		fileNamePtr = fileNames.at(i).toLocal8Bit();
+		fileNamePtr = fileNames.at(i).toUtf8();
 		parse_file(fileNamePtr.data(), &error);
 		set_filename(fileNamePtr.data(), TRUE);
 		setTitle(MWTF_FILENAME);
-- 
1.7.11.msysgit.0



More information about the subsurface mailing list