From 986ee3c44aff2ac68e7b8001a50abdf824cda5de Mon Sep 17 00:00:00 2001 From: Tsuda Kageyu Date: Tue, 23 Apr 2013 01:59:02 +0900 Subject: [PATCH] Improve Unicode file name handling in Win9x --- taglib/toolkit/tfilestream.cpp | 4 +- taglib/toolkit/tiostream.cpp | 91 ++++++++++++++++++++++++++++++++++ taglib/toolkit/tiostream.h | 15 +++--- 3 files changed, 100 insertions(+), 10 deletions(-) diff --git a/taglib/toolkit/tfilestream.cpp b/taglib/toolkit/tfilestream.cpp index cd9dd7dd..a8de32aa 100644 --- a/taglib/toolkit/tfilestream.cpp +++ b/taglib/toolkit/tfilestream.cpp @@ -58,9 +58,9 @@ namespace const DWORD access = readOnly ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE); if(!path.wstr().empty()) - return CreateFileW(path, access, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + return CreateFileW(path.wstr().c_str(), access, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); else if(!path.str().empty()) - return CreateFileA(path, access, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + return CreateFileA(path.str().c_str(), access, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); else return INVALID_FILE; } diff --git a/taglib/toolkit/tiostream.cpp b/taglib/toolkit/tiostream.cpp index e7b60dd7..2d4f66d8 100644 --- a/taglib/toolkit/tiostream.cpp +++ b/taglib/toolkit/tiostream.cpp @@ -27,6 +27,97 @@ using namespace TagLib; +#ifdef _WIN32 + +// MSVC 2008 or later can't produce the binary for Win9x. +#if !defined(_MSC_VER) || (_MSC_VER < 1500) + +namespace +{ + + // Determines whether or not the running system is WinNT. + // In other words, whether the system supports Unicode. + + bool isWinNT() + { + OSVERSIONINFOA ver = {}; + ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); + if(GetVersionExA(&ver)) { + return (ver.dwPlatformId == VER_PLATFORM_WIN32_NT); + } + else { + return false; + } + } + + const bool IsWinNT = isWinNT(); + + // Converts a UTF-16 string into a local encoding. + + std::string unicodeToAnsi(const std::wstring &wstr) + { + const int len = WideCharToMultiByte(CP_ACP, 0, &wstr[0], -1, NULL, 0, NULL, NULL); + if(len == 0) + return std::string(); + + std::string str(len, '\0'); + WideCharToMultiByte(CP_ACP, 0, &wstr[0], -1, &str[0], len, NULL, NULL); + + return str; + } +} + +// If WinNT, stores a Unicode string into m_wname directly. +// If Win9x, converts and stores it into m_name to avoid calling Unicode version functions. + +FileName::FileName(const wchar_t *name) + : m_wname(IsWinNT ? name : L"") + , m_name(IsWinNT ? "" : unicodeToAnsi(name)) +{ +} + +#else + +FileName::FileName(const wchar_t *name) + : m_wname(name) +{ +} + +#endif + +FileName::FileName(const char *name) + : m_name(name) +{ +} + +FileName::FileName(const FileName &name) + : m_wname(name.m_wname) + , m_name(name.m_name) +{ +} + +FileName::operator const wchar_t *() const +{ + return m_wname.c_str(); +} + +FileName::operator const char *() const +{ + return m_name.c_str(); +} + +const std::wstring &FileName::wstr() const +{ + return m_wname; +} + +const std::string &FileName::str() const +{ + return m_name; +} + +#endif + //////////////////////////////////////////////////////////////////////////////// // public members //////////////////////////////////////////////////////////////////////////////// diff --git a/taglib/toolkit/tiostream.h b/taglib/toolkit/tiostream.h index d3f78c28..2cb80977 100644 --- a/taglib/toolkit/tiostream.h +++ b/taglib/toolkit/tiostream.h @@ -36,17 +36,16 @@ namespace TagLib { class TAGLIB_EXPORT FileName { public: - FileName(const wchar_t *name) : m_wname(name) {} - FileName(const char *name) : m_name(name) {} + FileName(const wchar_t *name); + FileName(const char *name); - FileName(const FileName &name) - : m_wname(name.m_wname), m_name(name.m_name) {} + FileName(const FileName &name); - operator const wchar_t *() const { return m_wname.c_str(); } - operator const char *() const { return m_name.c_str(); } + operator const wchar_t *() const; + operator const char *() const; - const std::wstring &wstr() const { return m_wname; } - const std::string &str() const { return m_name; } + const std::wstring &wstr() const; + const std::string &str() const; private: const std::string m_name;