From 8b42b7d269f3397b04e9e4c8f236c4b922de410b Mon Sep 17 00:00:00 2001 From: gabime Date: Tue, 2 Oct 2018 18:27:49 +0300 Subject: [PATCH] Fix support for wchar to utf8 under windows (fix issue #851 and #764) --- include/spdlog/details/logger_impl.h | 36 ++++++++++++++++++++++------ include/spdlog/logger.h | 9 ++----- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/include/spdlog/details/logger_impl.h b/include/spdlog/details/logger_impl.h index d790d919..339c01e5 100644 --- a/include/spdlog/details/logger_impl.h +++ b/include/spdlog/details/logger_impl.h @@ -175,6 +175,29 @@ inline void spdlog::logger::critical(const T &msg) } #ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT +static_assert(_WIN32, "SPDLOG_WCHAR_TO_UTF8_SUPPORT only supported on windows"); +inline void wbuf_to_utf8buf(const fmt::wmemory_buffer &wbuf, fmt::memory_buffer &target) +{ + int wbuf_size = static_cast(wbuf.size()); + if (wbuf_size == 0) + { + return; + } + + auto result_size = ::WideCharToMultiByte(CP_UTF8, 0, wbuf.data(), wbuf_size, NULL, 0, NULL, NULL); + + if (result_size > 0) + { + target.resize(result_size); + ::WideCharToMultiByte(CP_UTF8, 0, wbuf.data(), wbuf_size, &target.data()[0], result_size, NULL, NULL); + } + else + { + throw spdlog::spdlog_ex("Failed converting to utf8", errno); + } +} + + template inline void spdlog::logger::log(level::level_enum lvl, const wchar_t *fmt, const Args &... args) { @@ -183,15 +206,14 @@ inline void spdlog::logger::log(level::level_enum lvl, const wchar_t *fmt, const return; } - decltype(wstring_converter_)::byte_string utf8_string; - try { - { - std::lock_guard lock(wstring_converter_mutex_); - utf8_string = wstring_converter_.to_bytes(fmt); - } - log(lvl, utf8_string.c_str(), args...); + // format to wmemory_buffer and convert to utf8 + details::log_msg log_msg(&name_, lvl); + fmt::wmemory_buffer wbuf; + fmt::format_to(wbuf, fmt, args...); + wbuf_to_utf8buf(wbuf, log_msg.raw); + sink_it_(log_msg); } SPDLOG_CATCH_AND_HANDLE } diff --git a/include/spdlog/logger.h b/include/spdlog/logger.h index e8a238fb..b0398f26 100644 --- a/include/spdlog/logger.h +++ b/include/spdlog/logger.h @@ -25,6 +25,7 @@ #include #include #include +#include namespace spdlog { @@ -146,8 +147,7 @@ protected: // message/minute void default_err_handler_(const std::string &msg); - // increment the message count (only if - // defined(SPDLOG_ENABLE_MESSAGE_COUNTER)) + // increment the message count (only if defined(SPDLOG_ENABLE_MESSAGE_COUNTER)) void incr_msg_counter_(details::log_msg &msg); const std::string name_; @@ -157,11 +157,6 @@ protected: log_err_handler err_handler_; std::atomic last_err_time_; std::atomic msg_counter_; - -#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT - std::wstring_convert> wstring_converter_; - std::mutex wstring_converter_mutex_; -#endif }; } // namespace spdlog