From d4808158ca5c1a5ff98b2c0c4d4a73840f293070 Mon Sep 17 00:00:00 2001 From: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com> Date: Sun, 6 Jan 2019 21:21:19 -0500 Subject: [PATCH] win32: handle multi-byte characters in path strings Change-Id: I30276479189012edfb4f334641c66596c59b0ba9 --- src/fileutils.cpp | 3 +++ src/manager.cpp | 9 ++++----- src/media/recordable.cpp | 3 +++ src/string_utils.cpp | 16 +++++++++++++--- src/string_utils.h | 3 +-- 5 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/fileutils.cpp b/src/fileutils.cpp index 437122ce0d..409bcab174 100644 --- a/src/fileutils.cpp +++ b/src/fileutils.cpp @@ -242,6 +242,9 @@ bool isDirectory(const std::string& path) bool isDirectoryWritable(const std::string &directory) { +#ifdef _WIN32 + return access(decodeMultibyteString(directory).c_str(), W_OK) == 0; +#endif return access(directory.c_str(), W_OK) == 0; } diff --git a/src/manager.cpp b/src/manager.cpp index f8c74650da..f07eaad4f5 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -98,7 +98,6 @@ using random_device = dht::crypto::random_device; #include <list> #include <random> - namespace ring { /** To store conference objects by conference ids */ @@ -290,13 +289,10 @@ struct Manager::ManagerPimpl void loadAccount(const YAML::Node &item, int &errorCount); - void sendTextMessageToConference(const Conference& conf, const std::map<std::string, std::string>& messages, const std::string& from) const noexcept; - - void bindCallToConference(Call& call, Conference& conf); template <class T> @@ -1128,7 +1124,6 @@ Manager::muteMediaCall(const std::string& callId, const std::string& mediaType, } } - //THREAD=Main bool Manager::transferCall(const std::string& callId, const std::string& to) @@ -2124,12 +2119,16 @@ Manager::playRingtone(const std::string& accountID) } std::string ringchoice = account->getRingtonePath(); +#ifndef _WIN32 if (ringchoice.find(DIR_SEPARATOR_STR) == std::string::npos) { // check inside global share directory static const char * const RINGDIR = "ringtones"; ringchoice = std::string(PROGSHAREDIR) + DIR_SEPARATOR_STR + RINGDIR + DIR_SEPARATOR_STR + ringchoice; } +#else + ringchoice = decodeMultibyteString(ringchoice); +#endif { std::lock_guard<std::mutex> lock(pimpl_->audioLayerMutex_); diff --git a/src/media/recordable.cpp b/src/media/recordable.cpp index 3941cd920a..cd29930472 100644 --- a/src/media/recordable.cpp +++ b/src/media/recordable.cpp @@ -60,6 +60,9 @@ Recordable::toggleRecording() auto startTime = *std::localtime(&t); std::stringstream ss; auto dir = Manager::instance().audioPreference.getRecordPath(); +#ifdef _WIN32 + dir = decodeMultibyteString(dir); +#endif if (dir.empty()) dir = fileutils::get_home_dir(); ss << dir; diff --git a/src/string_utils.cpp b/src/string_utils.cpp index c74b34f543..b11db5210b 100644 --- a/src/string_utils.cpp +++ b/src/string_utils.cpp @@ -35,18 +35,28 @@ namespace ring { #ifdef _WIN32 -std::wstring to_wstring(const std::string& s) +std::wstring +to_wstring(const std::string& s) { int slength = (int)s.length() + 1; - int len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, nullptr, 0); + int len = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), slength, nullptr, 0); if (not len) throw std::runtime_error("Can't convert string to wchar"); std::wstring r((size_t)len, 0); - if (!MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, &(*r.begin()), len)) + if (!MultiByteToWideChar(CP_UTF8, 0, s.c_str(), slength, &(*r.begin()), len)) throw std::runtime_error("Can't convert string to wchar"); return r; } +std::string +decodeMultibyteString(const std::string& s) +{ + if (not s.length()) + return {}; + auto wstr = to_wstring(s); + return std::string(wstr.begin(), wstr.end()); +} + #endif std::string diff --git a/src/string_utils.h b/src/string_utils.h index fded39125f..62ad643ae3 100644 --- a/src/string_utils.h +++ b/src/string_utils.h @@ -39,9 +39,8 @@ bool_to_str(bool b) noexcept std::string to_string(double value); #ifdef _WIN32 - std::wstring to_wstring(const std::string& s); - +std::string decodeMultibyteString(const std::string& s); #endif template <typename T> -- GitLab