diff --git a/UnitTests/pch.h b/UnitTests/pch.h index 3cbbefdb5..16b6a700a 100644 --- a/UnitTests/pch.h +++ b/UnitTests/pch.h @@ -1,4 +1,4 @@ -/* +/* SPDX-License-Identifier: MIT Copyright © 2023 Amebis */ diff --git a/UnitTests/unicode.cpp b/UnitTests/unicode.cpp index fcc0bc40a..45ee9283b 100644 --- a/UnitTests/unicode.cpp +++ b/UnitTests/unicode.cpp @@ -23,8 +23,8 @@ namespace UnitTests Assert::AreEqual( L"Th\u00ed\u0161 i\u22c5 a te\u0073\u0304t. 😀😅", stdex::str2wstr("Thíš i⋅ a tes̄t. 😀😅", stdex::charset_id::utf8).c_str()); - string src; - wstring dst; + std::string src; + std::wstring dst; for (size_t i = 0; i < 2000; i++) { src += "🐔Test🐮\r\n"; dst += L"🐔Test🐮\r\n"; @@ -46,8 +46,8 @@ namespace UnitTests Assert::AreEqual( "Th\xc3\xad\xc5\xa1 i\xe2\x8b\x85 a tes\xcc\x84t. \xf0\x9f\x98\x80\xf0\x9f\x98\x85", stdex::wstr2str(L"Thíš i⋅ a tes̄t. 😀😅", stdex::charset_id::utf8).c_str()); - wstring src; - string dst; + std::wstring src; + std::string dst; for (size_t i = 0; i < 2000; i++) { src += L"🐔Test🐮\r\n"; dst += "🐔Test🐮\r\n"; @@ -71,7 +71,7 @@ namespace UnitTests Assert::AreEqual( "Thíš i· a teşt.", win1250_to_utf8.convert("Th\xed\x9a i\xb7 a te\xbat.").c_str()); - string src, dst; + std::string src, dst; for (size_t i = 0; i < 1000; i++) { src += "V ko\x9eu\x9a\xe8ku zlobnega mizarja stopiclja fant in kli\xe8" "e 0123456789.\r\n"; dst += "V kožuščku zlobnega mizarja stopiclja fant in kliče 0123456789.\r\n"; diff --git a/include/stdex/mapping.hpp b/include/stdex/mapping.hpp index 816ac774e..b349fa8e9 100644 --- a/include/stdex/mapping.hpp +++ b/include/stdex/mapping.hpp @@ -1,6 +1,6 @@ /* - SPDX-License-Identifier: MIT - Copyright © 2023 Amebis + SPDX-License-Identifier: MIT + Copyright © 2023 Amebis */ #pragma once diff --git a/include/stdex/parser.hpp b/include/stdex/parser.hpp index 380efbd3f..92aaa8616 100644 --- a/include/stdex/parser.hpp +++ b/include/stdex/parser.hpp @@ -14,6 +14,7 @@ #include #include #include +#include #if defined(_WIN32) #ifndef _WINSOCKAPI_ #include diff --git a/include/stdex/unicode.hpp b/include/stdex/unicode.hpp index 31f2ec58e..2ecb42ed0 100644 --- a/include/stdex/unicode.hpp +++ b/include/stdex/unicode.hpp @@ -86,15 +86,16 @@ namespace stdex _Inout_ std::basic_string &dst, _In_reads_or_z_opt_(count_src) const T_from* src, _In_ size_t count_src) { - constexpr DWORD dwFlagsMBWC = MB_PRECOMPOSED; - constexpr DWORD dwFlagsWCMB = 0; - constexpr LPCCH lpDefaultChar = NULL; - assert(src || !count_src); count_src = stdex::strnlen(src, count_src); if (!count_src) _Unlikely_ return; + #ifdef _WIN32 + constexpr DWORD dwFlagsMBWC = MB_PRECOMPOSED; + constexpr DWORD dwFlagsWCMB = 0; + constexpr LPCCH lpDefaultChar = NULL; + _Analysis_assume_(src); if (m_from == m_to) _Unlikely_{ dst.append(reinterpret_cast(src), count_src); @@ -195,17 +196,21 @@ namespace stdex throw std::runtime_error("MultiByteToWideChar failed"); } #else + dst.reserve(dst.size() + count_src); T_to buf[1024 / sizeof(T_to)]; size_t src_size = stdex::mul(sizeof(T_from), count_src); - do { + for (;;) { T_to* output = &buf[0]; size_t output_size = sizeof(buf); errno = 0; - iconv(m_handle, (char**)&src, &src_size, (char**)&output, &output_size); - if (errno) - throw std::runtime_error("iconv failed"); + iconv(m_handle, const_cast(reinterpret_cast(&src)), &src_size, reinterpret_cast(&output), &output_size); dst.append(buf, reinterpret_cast(reinterpret_cast(buf) + sizeof(buf) - output_size)); - } while (src_size); + if (!errno) + break; + if (errno == E2BIG) + continue; + throw std::runtime_error("iconv failed"); + } #endif } @@ -353,10 +358,10 @@ namespace stdex "CP1250", // windows1250 "CP1251", // windows1251 "CP1252", // windows1252 - } + }; return charset == charset_id::system ? nl_langinfo(LC_CTYPE) : - encodings[static_cast>(charset))]; + encodings[static_cast>(charset)]; } protected: