aboutsummaryrefslogtreecommitdiffstats
path: root/src/fs
diff options
context:
space:
mode:
Diffstat (limited to 'src/fs')
-rw-r--r--src/fs/AllocatedPath.cxx2
-rw-r--r--src/fs/Charset.cxx44
-rw-r--r--src/fs/NarrowPath.hxx20
-rw-r--r--src/fs/Traits.hxx4
4 files changed, 68 insertions, 2 deletions
diff --git a/src/fs/AllocatedPath.cxx b/src/fs/AllocatedPath.cxx
index 087cbf76a..8b03ed2f1 100644
--- a/src/fs/AllocatedPath.cxx
+++ b/src/fs/AllocatedPath.cxx
@@ -30,7 +30,7 @@ AllocatedPath::~AllocatedPath() {}
AllocatedPath
AllocatedPath::FromUTF8(const char *path_utf8)
{
-#ifdef HAVE_FS_CHARSET
+#if defined(HAVE_FS_CHARSET) || defined(WIN32)
return AllocatedPath(::PathFromUTF8(path_utf8));
#else
return FromFS(path_utf8);
diff --git a/src/fs/Charset.cxx b/src/fs/Charset.cxx
index bc6357297..b25615d42 100644
--- a/src/fs/Charset.cxx
+++ b/src/fs/Charset.cxx
@@ -25,6 +25,10 @@
#include "lib/icu/Converter.hxx"
#include "util/Error.hxx"
+#ifdef WIN32
+#include <windows.h>
+#endif
+
#include <algorithm>
#include <assert.h>
@@ -95,6 +99,24 @@ PathToUTF8(PathTraitsFS::const_pointer path_fs)
assert(path_fs != nullptr);
#endif
+#ifdef WIN32
+ int length = WideCharToMultiByte(CP_UTF8, 0, path_fs, -1, nullptr, 0,
+ nullptr, nullptr);
+ if (length <= 0)
+ return PathTraitsUTF8::string();
+
+ char *buffer = new char[length];
+ length = WideCharToMultiByte(CP_UTF8, 0, path_fs, -1, buffer, length,
+ nullptr, nullptr);
+ if (length <= 0) {
+ delete[] buffer;
+ return PathTraitsUTF8::string();
+ }
+
+ PathTraitsUTF8::string result(buffer);
+ delete[] buffer;
+ return FixSeparators(std::move(result));
+#else
#ifdef HAVE_FS_CHARSET
if (fs_converter == nullptr)
#endif
@@ -103,9 +125,10 @@ PathToUTF8(PathTraitsFS::const_pointer path_fs)
return FixSeparators(fs_converter->ToUTF8(path_fs));
#endif
+#endif
}
-#ifdef HAVE_FS_CHARSET
+#if defined(HAVE_FS_CHARSET) || defined(WIN32)
PathTraitsFS::string
PathFromUTF8(PathTraitsUTF8::const_pointer path_utf8)
@@ -115,10 +138,29 @@ PathFromUTF8(PathTraitsUTF8::const_pointer path_utf8)
assert(path_utf8 != nullptr);
#endif
+#ifdef WIN32
+ int length = MultiByteToWideChar(CP_UTF8, 0, path_utf8, -1,
+ nullptr, 0);
+ if (length <= 0)
+ return PathTraitsFS::string();
+
+ wchar_t *buffer = new wchar_t[length];
+ length = MultiByteToWideChar(CP_UTF8, 0, path_utf8, -1,
+ buffer, length);
+ if (length <= 0) {
+ delete[] buffer;
+ return PathTraitsFS::string();
+ }
+
+ PathTraitsFS::string result(buffer);
+ delete[] buffer;
+ return std::move(result);
+#else
if (fs_converter == nullptr)
return path_utf8;
return fs_converter->FromUTF8(path_utf8);
+#endif
}
#endif
diff --git a/src/fs/NarrowPath.hxx b/src/fs/NarrowPath.hxx
index 2088f9359..ad310cd5c 100644
--- a/src/fs/NarrowPath.hxx
+++ b/src/fs/NarrowPath.hxx
@@ -22,6 +22,11 @@
#include "check.h"
#include "Path.hxx"
+#include "util/Macros.hxx"
+
+#ifdef _UNICODE
+#include <windows.h>
+#endif
/**
* A path name that uses the regular (narrow) "char". This is used to
@@ -32,10 +37,25 @@ class NarrowPath {
typedef char value_type;
typedef const char *const_pointer;
+#ifdef _UNICODE
+ char value[PATH_MAX];
+#else
const_pointer value;
+#endif
public:
+#ifdef _UNICODE
+ explicit NarrowPath(Path _path) {
+ auto result = WideCharToMultiByte(CP_ACP, 0,
+ _path.c_str(), -1,
+ value, ARRAY_SIZE(value),
+ nullptr, nullptr);
+ if (result < 0)
+ value[0] = 0;
+ }
+#else
explicit NarrowPath(Path _path):value(_path.c_str()) {}
+#endif
operator const_pointer() const {
return value;
diff --git a/src/fs/Traits.hxx b/src/fs/Traits.hxx
index cdd9b531d..b92330f60 100644
--- a/src/fs/Traits.hxx
+++ b/src/fs/Traits.hxx
@@ -43,7 +43,11 @@
* This class describes the nature of a native filesystem path.
*/
struct PathTraitsFS {
+#ifdef WIN32
+ typedef std::wstring string;
+#else
typedef std::string string;
+#endif
typedef string::traits_type char_traits;
typedef char_traits::char_type value_type;
typedef value_type *pointer;