aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorstoffu <stoffu@protonmail.ch>2018-06-25 09:44:07 +0900
committerstoffu <stoffu@protonmail.ch>2018-06-28 09:40:26 +0900
commit1d176473e90d0e75588ac97f32feb354f4b5da37 (patch)
tree5ec0b9cb18c651f7c703b48da9cc6bcf94eefa1f
parentMerge pull request #3907 (diff)
downloadmonero-1d176473e90d0e75588ac97f32feb354f4b5da37.tar.xz
epee.string_tools: add conversion between UTF-8 and UTF-16
Diffstat (limited to '')
-rw-r--r--contrib/epee/include/file_io_utils.h25
-rw-r--r--contrib/epee/include/string_tools.h35
-rw-r--r--src/common/util.cpp31
3 files changed, 64 insertions, 27 deletions
diff --git a/contrib/epee/include/file_io_utils.h b/contrib/epee/include/file_io_utils.h
index 4434f7383..25f8c648b 100644
--- a/contrib/epee/include/file_io_utils.h
+++ b/contrib/epee/include/file_io_utils.h
@@ -33,6 +33,7 @@
#include <boost/filesystem/operations.hpp>
#ifdef WIN32
#include <windows.h>
+#include "string_tools.h"
#endif
// On Windows there is a problem with non-ASCII characters in path and file names
@@ -72,11 +73,9 @@ namespace file_io_utils
bool save_string_to_file(const std::string& path_to_file, const std::string& str)
{
#ifdef WIN32
- WCHAR wide_path[1000];
- int chars = MultiByteToWideChar(CP_UTF8, 0, path_to_file.c_str(), path_to_file.size() + 1, wide_path, 1000);
- if (chars == 0)
- return false;
- HANDLE file_handle = CreateFileW(wide_path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ std::wstring wide_path;
+ try { wide_path = string_tools::utf8_to_utf16(path_to_file); } catch (...) { return false; }
+ HANDLE file_handle = CreateFileW(wide_path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (file_handle == INVALID_HANDLE_VALUE)
return false;
DWORD bytes_written;
@@ -131,11 +130,9 @@ namespace file_io_utils
bool load_file_to_string(const std::string& path_to_file, std::string& target_str, size_t max_size = 1000000000)
{
#ifdef WIN32
- WCHAR wide_path[1000];
- int chars = MultiByteToWideChar(CP_UTF8, 0, path_to_file.c_str(), path_to_file.size() + 1, wide_path, 1000);
- if (chars == 0)
- return false;
- HANDLE file_handle = CreateFileW(wide_path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ std::wstring wide_path;
+ try { wide_path = string_tools::utf8_to_utf16(path_to_file); } catch (...) { return false; }
+ HANDLE file_handle = CreateFileW(wide_path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (file_handle == INVALID_HANDLE_VALUE)
return false;
DWORD file_size = GetFileSize(file_handle, NULL);
@@ -202,11 +199,9 @@ namespace file_io_utils
bool get_file_size(const std::string& path_to_file, uint64_t &size)
{
#ifdef WIN32
- WCHAR wide_path[1000];
- int chars = MultiByteToWideChar(CP_UTF8, 0, path_to_file.c_str(), path_to_file.size() + 1, wide_path, 1000);
- if (chars == 0)
- return false;
- HANDLE file_handle = CreateFileW(wide_path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ std::wstring wide_path;
+ try { wide_path = string_tools::utf8_to_utf16(path_to_file); } catch (...) { return false; }
+ HANDLE file_handle = CreateFileW(wide_path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (file_handle == INVALID_HANDLE_VALUE)
return false;
LARGE_INTEGER file_size;
diff --git a/contrib/epee/include/string_tools.h b/contrib/epee/include/string_tools.h
index 63705e401..8d8603076 100644
--- a/contrib/epee/include/string_tools.h
+++ b/contrib/epee/include/string_tools.h
@@ -381,6 +381,41 @@ POP_WARNINGS
res = str.substr(0, pos);
return res;
}
+ //----------------------------------------------------------------------------
+#ifdef _WIN32
+ inline std::wstring utf8_to_utf16(const std::string& str)
+ {
+ if (str.empty())
+ return {};
+ int wstr_size = MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), NULL, 0);
+ if (wstr_size == 0)
+ {
+ throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
+ }
+ std::wstring wstr(wstr_size, wchar_t{});
+ if (!MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), &wstr[0], wstr_size))
+ {
+ throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
+ }
+ return wstr;
+ }
+ inline std::string utf16_to_utf8(const std::wstring& wstr)
+ {
+ if (wstr.empty())
+ return {};
+ int str_size = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), NULL, 0, NULL, NULL);
+ if (str_size == 0)
+ {
+ throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
+ }
+ std::string str(str_size, char{});
+ if (!WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), &str[0], str_size, NULL, NULL))
+ {
+ throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
+ }
+ return str;
+ }
+#endif
}
}
#endif //_STRING_TOOLS_H_
diff --git a/src/common/util.cpp b/src/common/util.cpp
index 329352e94..97c61a174 100644
--- a/src/common/util.cpp
+++ b/src/common/util.cpp
@@ -451,10 +451,15 @@ std::string get_nix_version_display_string()
if (SHGetSpecialFolderPathW(NULL, psz_path, nfolder, iscreate))
{
- int size_needed = WideCharToMultiByte(CP_UTF8, 0, psz_path, wcslen(psz_path), NULL, 0, NULL, NULL);
- std::string folder_name(size_needed, 0);
- WideCharToMultiByte(CP_UTF8, 0, psz_path, wcslen(psz_path), &folder_name[0], size_needed, NULL, NULL);
- return folder_name;
+ try
+ {
+ return string_tools::utf16_to_utf8(psz_path);
+ }
+ catch (const std::exception &e)
+ {
+ MERROR("utf16_to_utf8 failed: " << e.what());
+ return "";
+ }
}
LOG_ERROR("SHGetSpecialFolderPathW() failed, could not obtain requested path.");
@@ -515,18 +520,20 @@ std::string get_nix_version_display_string()
int code;
#if defined(WIN32)
// Maximizing chances for success
- WCHAR wide_replacement_name[1000];
- MultiByteToWideChar(CP_UTF8, 0, replacement_name.c_str(), replacement_name.size() + 1, wide_replacement_name, 1000);
- WCHAR wide_replaced_name[1000];
- MultiByteToWideChar(CP_UTF8, 0, replaced_name.c_str(), replaced_name.size() + 1, wide_replaced_name, 1000);
-
- DWORD attributes = ::GetFileAttributesW(wide_replaced_name);
+ std::wstring wide_replacement_name;
+ try { wide_replacement_name = string_tools::utf8_to_utf16(replacement_name); }
+ catch (...) { return std::error_code(GetLastError(), std::system_category()); }
+ std::wstring wide_replaced_name;
+ try { wide_replaced_name = string_tools::utf8_to_utf16(replaced_name); }
+ catch (...) { return std::error_code(GetLastError(), std::system_category()); }
+
+ DWORD attributes = ::GetFileAttributesW(wide_replaced_name.c_str());
if (INVALID_FILE_ATTRIBUTES != attributes)
{
- ::SetFileAttributesW(wide_replaced_name, attributes & (~FILE_ATTRIBUTE_READONLY));
+ ::SetFileAttributesW(wide_replaced_name.c_str(), attributes & (~FILE_ATTRIBUTE_READONLY));
}
- bool ok = 0 != ::MoveFileExW(wide_replacement_name, wide_replaced_name, MOVEFILE_REPLACE_EXISTING);
+ bool ok = 0 != ::MoveFileExW(wide_replacement_name.c_str(), wide_replaced_name.c_str(), MOVEFILE_REPLACE_EXISTING);
code = ok ? 0 : static_cast<int>(::GetLastError());
#else
bool ok = 0 == std::rename(replacement_name.c_str(), replaced_name.c_str());