Skip to content

Commit

Permalink
#5231: Add new implementation for converting strings from and to cert…
Browse files Browse the repository at this point in the history
…ain encodings, replacing the previous wxutil::IConv implementation.
  • Loading branch information
codereader committed Jul 31, 2020
1 parent 4eec820 commit 26cc6de
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 8 deletions.
2 changes: 1 addition & 1 deletion libs/module/DynamicLibrary.cpp
Expand Up @@ -59,7 +59,7 @@ DynamicLibrary::FunctionPointer DynamicLibrary::findSymbol(const std::string& sy

std::string DynamicLibrary::getName() const
{
return string::to_utf8(_name);
return string::unicode_to_utf8(_name);
}

/**
Expand Down
64 changes: 63 additions & 1 deletion libs/string/encoding.h
Expand Up @@ -7,9 +7,71 @@
namespace string
{

inline std::string to_utf8(const std::wstring& wstring)
inline std::string unicode_to_utf8(const std::wstring& wstring)
{
return std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().to_bytes(wstring);
}

inline std::wstring utf8_to_unicode(const std::string& utf8)
{
return std::wstring_convert< std::codecvt_utf8<wchar_t> >().from_bytes(utf8);
}

inline std::wstring mb_to_unicode(const std::string& str)
{
std::wstring ret;
std::mbstate_t state = {};
const char* src = str.data();

size_t len = std::mbsrtowcs(nullptr, &src, 0, &state);

if (len != static_cast<size_t>(-1))
{
std::vector<wchar_t> buff(len + 1);

len = std::mbsrtowcs(buff.data(), &src, len, &state);

if (len != static_cast<size_t>(-1))
{
ret.assign(buff.data(), len);
}
}

return ret;
}

inline std::string unicode_to_mb(const std::wstring& wstr)
{
std::string ret;
std::mbstate_t state = {};

const wchar_t* src = wstr.data();

size_t len = std::wcsrtombs(nullptr, &src, 0, &state);

if (len != static_cast<size_t>(-1))
{
std::vector<char> buff(len + 1);

len = std::wcsrtombs(buff.data(), &src, len, &state);

if (len != static_cast<size_t>(-1))
{
ret.assign(buff.data(), len);
}
}

return ret;
}

inline std::string utf8_to_mb(const std::string& input)
{
return unicode_to_mb(utf8_to_unicode(input));
}

inline std::string mb_to_utf8(const std::string& input)
{
return unicode_to_utf8(mb_to_unicode(input));
}

}
11 changes: 11 additions & 0 deletions libs/wxutil/IConv.h
@@ -1,7 +1,10 @@
#pragma once

#include <string>
#if 0
#include <wx/string.h>
#endif
#include "string/encoding.h"

#include <cassert>

Expand All @@ -25,8 +28,12 @@ class IConv
*/
static std::string localeToUTF8(const std::string& input)
{
#if 1
return string::mb_to_utf8(input);
#else
wxString inp(input);
return inp.ToUTF8().data();
#endif
}

/**
Expand All @@ -35,7 +42,11 @@ class IConv
*/
static std::string localeFromUTF8(const std::string& input)
{
#if 1
return string::utf8_to_mb(input);
#else
return wxString::FromUTF8(input.c_str()).ToStdString();
#endif
}
};

Expand Down
2 changes: 1 addition & 1 deletion radiant/ui/prefdialog/GameSetupPageTdm.cpp
Expand Up @@ -230,7 +230,7 @@ void GameSetupPageTdm::validateSettings()
}
catch (const std::system_error& ex)
{
rWarning() << "[vfs] Skipping file " << string::to_utf8(path.filename().wstring()) <<
rWarning() << "[vfs] Skipping file " << string::unicode_to_utf8(path.filename().wstring()) <<
" - possibly unsupported characters in filename? " <<
"(Exception: " << ex.what() << ")" << std::endl;
}
Expand Down
2 changes: 1 addition & 1 deletion radiantcore/vfs/DirectoryArchive.cpp
Expand Up @@ -92,7 +92,7 @@ void DirectoryArchive::traverse(Visitor& visitor, const std::string& root)
}
catch (const std::system_error& ex)
{
rWarning() << "[vfs] Skipping file " << string::to_utf8(candidate.filename().wstring()) <<
rWarning() << "[vfs] Skipping file " << string::unicode_to_utf8(candidate.filename().wstring()) <<
" - possibly unsupported characters in filename? " <<
"(Exception: " << ex.what() << ")" << std::endl;
}
Expand Down
2 changes: 1 addition & 1 deletion radiantcore/vfs/Doom3FileSystem.cpp
Expand Up @@ -269,7 +269,7 @@ void Doom3FileSystem::initDirectory(const std::string& inputPath)
}
catch (std::system_error& ex)
{
rWarning() << "[vfs] Skipping file " << string::to_utf8(file.filename().wstring()) <<
rWarning() << "[vfs] Skipping file " << string::unicode_to_utf8(file.filename().wstring()) <<
" - possibly unsupported characters in filename? " <<
"(Exception: " << ex.what() << ")" << std::endl;
}
Expand Down
6 changes: 3 additions & 3 deletions radiantcore/xmlregistry/XMLRegistry.cpp
Expand Up @@ -9,7 +9,7 @@

#include "version.h"
#include "string/string.h"
#include "wxutil/IConv.h"
#include "string/encoding.h"
#include "module/StaticModule.h"

namespace registry
Expand Down Expand Up @@ -191,7 +191,7 @@ std::string XMLRegistry::get(const std::string& key)
if (!nodeList.empty())
{
// Convert the UTF-8 string back to locale and return
return wxutil::IConv::localeFromUTF8(nodeList[0].getAttributeValue("value"));
return string::utf8_to_mb(nodeList[0].getAttributeValue("value"));
}

return std::string();
Expand All @@ -203,7 +203,7 @@ void XMLRegistry::set(const std::string& key, const std::string& value)

// Create or set the value in the user tree, the default tree stays untouched
// Convert the string to UTF-8 before storing it into the RegistryTree
_userTree.set(key, wxutil::IConv::localeToUTF8(value));
_userTree.set(key, string::mb_to_utf8(value));

_changesSinceLastSave++;

Expand Down

0 comments on commit 26cc6de

Please sign in to comment.