1818#pragma once
1919
2020#include < cassert>
21- #include < codecvt>
2221#include < cstring>
23- #include < locale>
22+ #include < iterator>
23+ #include < string>
2424#include < vector>
2525#include " arrow/flight/sql/odbc/odbc_impl/exceptions.h"
26- #include " arrow/util/macros .h"
26+ #include " arrow/vendored/utfcpp/checked .h"
2727
2828#if defined(__APPLE__)
2929# include < atomic>
@@ -68,21 +68,23 @@ inline size_t wcsstrlen(const void* wcs_string) {
6868 }
6969}
7070
71- // GH-46576: suppress unicode warnings
72- ARROW_SUPPRESS_DEPRECATION_WARNING
7371template <typename CHAR_TYPE >
7472inline void Utf8ToWcs (const char * utf8_string, size_t length,
7573 std::vector<uint8_t >* result) {
76- thread_local std::wstring_convert<std::codecvt_utf8<CHAR_TYPE >, CHAR_TYPE > converter;
77- auto string = converter.from_bytes (utf8_string, utf8_string + length);
74+ std::basic_string<CHAR_TYPE > string;
75+ if constexpr (sizeof (CHAR_TYPE ) == sizeof (char16_t )) {
76+ ::utf8::utf8to16 (utf8_string, utf8_string + length, std::back_inserter(string));
77+ } else {
78+ static_assert (sizeof (CHAR_TYPE ) == sizeof (char32_t ));
79+ ::utf8::utf8to32 (utf8_string, utf8_string + length, std::back_inserter(string));
80+ }
7881
79- uint32_t length_in_bytes = static_cast <uint32_t >(string.size () * GetSqlWCharSize ( ));
82+ auto length_in_bytes = static_cast <uint32_t >(string.size () * sizeof ( CHAR_TYPE ));
8083 const uint8_t * data = (uint8_t *)string.data ();
8184
8285 result->reserve (length_in_bytes);
8386 result->assign (data, data + length_in_bytes);
8487}
85- ARROW_UNSUPPRESS_DEPRECATION_WARNING
8688
8789inline void Utf8ToWcs (const char * utf8_string, size_t length,
8890 std::vector<uint8_t >* result) {
@@ -102,22 +104,21 @@ inline void Utf8ToWcs(const char* utf8_string, std::vector<uint8_t>* result) {
102104 return Utf8ToWcs (utf8_string, strlen (utf8_string), result);
103105}
104106
105- // GH-46576: suppress unicode warnings
106- ARROW_SUPPRESS_DEPRECATION_WARNING
107107template <typename CHAR_TYPE >
108108inline void WcsToUtf8 (const void * wcs_string, size_t length_in_code_units,
109109 std::vector<uint8_t >* result) {
110- thread_local std::wstring_convert<std::codecvt_utf8<CHAR_TYPE >, CHAR_TYPE > converter;
111- auto byte_string = converter.to_bytes ((CHAR_TYPE *)wcs_string,
112- (CHAR_TYPE *)wcs_string + length_in_code_units);
113-
114- uint32_t length_in_bytes = static_cast <uint32_t >(byte_string.size ());
115- const uint8_t * data = (uint8_t *)byte_string.data ();
110+ const auto * begin = static_cast <const CHAR_TYPE *>(wcs_string);
111+
112+ std::string string;
113+ if constexpr (sizeof (CHAR_TYPE ) == sizeof (char16_t )) {
114+ ::utf8::utf16to8 (begin, begin + length_in_code_units, std::back_inserter(string));
115+ } else {
116+ static_assert (sizeof (CHAR_TYPE ) == sizeof (char32_t ));
117+ ::utf8::utf32to8 (begin, begin + length_in_code_units, std::back_inserter(string));
118+ }
116119
117- result->reserve (length_in_bytes);
118- result->assign (data, data + length_in_bytes);
120+ result->assign (string.begin (), string.end ());
119121}
120- ARROW_UNSUPPRESS_DEPRECATION_WARNING
121122
122123inline void WcsToUtf8 (const void * wcs_string, size_t length_in_code_units,
123124 std::vector<uint8_t >* result) {
0 commit comments