fs/Traits: enable _UNICODE on Windows
Use wchar_t for everything on Windows. Solves a lot of filesystem charset problems.
This commit is contained in:
parent
1da0956331
commit
65ff72cdf8
|
@ -103,6 +103,7 @@ mingw32* | windows*)
|
|||
AM_CPPFLAGS="$AM_CPPFLAGS -DWIN32_LEAN_AND_MEAN"
|
||||
AM_CPPFLAGS="$AM_CPPFLAGS -DWINVER=0x0600 -D_WIN32_WINNT=0x0600"
|
||||
AM_CPPFLAGS="$AM_CPPFLAGS -DSTRICT"
|
||||
AM_CPPFLAGS="$AM_CPPFLAGS -DUNICODE -D_UNICODE"
|
||||
LIBS="$LIBS -lws2_32"
|
||||
host_is_windows=yes
|
||||
host_is_unix=no
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "fs/Traits.hxx"
|
||||
#include "fs/FileSystem.hxx"
|
||||
#include "fs/StandardDirectory.hxx"
|
||||
#include "util/Macros.hxx"
|
||||
#include "util/Error.hxx"
|
||||
#include "util/Domain.hxx"
|
||||
#include "util/OptionDef.hxx"
|
||||
|
@ -337,7 +338,19 @@ parse_cmdline(int argc, char **argv, struct options *options,
|
|||
|
||||
if (config_file != nullptr) {
|
||||
/* use specified configuration file */
|
||||
#ifdef _UNICODE
|
||||
wchar_t buffer[MAX_PATH];
|
||||
auto result = MultiByteToWideChar(CP_ACP, 0, config_file, -1,
|
||||
buffer, ARRAY_SIZE(buffer));
|
||||
if (result <= 0) {
|
||||
error.SetLastError("MultiByteToWideChar() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return ReadConfigFile(Path::FromFS(buffer), error);
|
||||
#else
|
||||
return ReadConfigFile(Path::FromFS(config_file), error);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* use default configuration file path */
|
||||
|
|
|
@ -268,7 +268,17 @@ LoadPlaylistFile(const char *utf8path, Error &error)
|
|||
if (*s == 0 || *s == PLAYLIST_COMMENT)
|
||||
continue;
|
||||
|
||||
#ifdef _UNICODE
|
||||
wchar_t buffer[MAX_PATH];
|
||||
auto result = MultiByteToWideChar(CP_ACP, 0, s, -1,
|
||||
buffer, ARRAY_SIZE(buffer));
|
||||
if (result <= 0)
|
||||
continue;
|
||||
|
||||
const Path path = Path::FromFS(buffer);
|
||||
#else
|
||||
const Path path = Path::FromFS(s);
|
||||
#endif
|
||||
|
||||
std::string uri_utf8;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "config.h"
|
||||
#include "SocketError.hxx"
|
||||
#include "util/Domain.hxx"
|
||||
#include "util/Macros.hxx"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
@ -29,13 +30,31 @@ const Domain socket_domain("socket");
|
|||
|
||||
SocketErrorMessage::SocketErrorMessage(socket_error_t code)
|
||||
{
|
||||
#ifdef _UNICODE
|
||||
wchar_t buffer[ARRAY_SIZE(msg)];
|
||||
#else
|
||||
auto *buffer = msg;
|
||||
#endif
|
||||
|
||||
DWORD nbytes = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS |
|
||||
FORMAT_MESSAGE_MAX_WIDTH_MASK,
|
||||
NULL, code, 0,
|
||||
(LPSTR)msg, sizeof(msg), NULL);
|
||||
if (nbytes == 0)
|
||||
nullptr, code, 0,
|
||||
buffer, ARRAY_SIZE(msg), nullptr);
|
||||
if (nbytes == 0) {
|
||||
strcpy(msg, "Unknown error");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef _UNICODE
|
||||
auto length = WideCharToMultiByte(CP_UTF8, 0, buffer, -1,
|
||||
msg, ARRAY_SIZE(msg),
|
||||
nullptr, nullptr);
|
||||
if (length <= 0) {
|
||||
strcpy(msg, "WideCharToMultiByte() error");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
|
|
Loading…
Reference in New Issue