From c83bb880d254ebab2dc29873f83cb3409df895db Mon Sep 17 00:00:00 2001 From: Pavel Artsishevsky Date: Wed, 11 Dec 2024 18:56:10 +0100 Subject: [PATCH] Use std::mbrlen() instead of std::mbsrtowcs() Signed-off-by: Pavel Artsishevsky --- include/slimlog/util/unicode.h | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/include/slimlog/util/unicode.h b/include/slimlog/util/unicode.h index 78f3984..5fc6734 100644 --- a/include/slimlog/util/unicode.h +++ b/include/slimlog/util/unicode.h @@ -143,31 +143,26 @@ constexpr auto count_codepoints(const Char* begin, std::size_t len) -> std::size std::uint8_t state = 0; std::size_t codepoints = 0; std::uint32_t codepoint = 0; - for (const auto* end = std::next(begin, len); begin != end; std::advance(begin, 1)) { - if (utf8_decode(state, codepoint, static_cast(*begin)) == 0) { - codepoints += (codepoint > std::numeric_limits::max()) ? 2 : 1; + for (const auto* const end = std::next(begin, len); begin != end; std::advance(begin, 1)) { + utf8_decode(state, codepoint, static_cast(*begin)); + if (state == 0) { + ++codepoints; + } else if (state == 1) { + throw std::runtime_error("utf8_decode(): conversion error"); } } - if (state != 0) { - throw std::runtime_error("Unicode::utf8_decode(): conversion error"); - } return codepoints; #endif } else { - std::mbstate_t state = std::mbstate_t(); -#if defined(_WIN32) and defined(__STDC_WANT_SECURE_LIB__) std::size_t codepoints = 0; - if (mbsrtowcs_s(&codepoints, nullptr, codepoints, &begin, 0, &state) != 0) { - throw std::runtime_error("mbsrtowcs_s(): conversion error"); - } - codepoints -= 1; -#else - // NOLINTNEXTLINE (concurrency-mt-unsafe) - const auto codepoints = std::mbsrtowcs(nullptr, &begin, 0, &state); - if (codepoints == static_cast(-1)) [[unlikely]] { - throw std::runtime_error("std::mbsrtowcs(): conversion error"); + std::mbstate_t mb = {}; + for (const auto* const end = std::next(begin, len); begin != end; ++codepoints) { + const auto next = std::mbrlen(begin, end - begin, &mb); // NOLINT(concurrency-mt-unsafe) + if (next == static_cast(-1)) { + throw std::runtime_error("std::mbrlen(): conversion error"); + } + std::advance(begin, next); } -#endif return codepoints; } }