Improve Unicode file name handling in Win9x

This commit is contained in:
Tsuda Kageyu 2013-04-23 01:59:02 +09:00
parent dfb3962511
commit 986ee3c44a
3 changed files with 100 additions and 10 deletions

View File

@ -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;
}

View File

@ -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
////////////////////////////////////////////////////////////////////////////////

View File

@ -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;