// Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // Convert wide character to multibyte character, with locale. #include #include <__msvc_xlocinfo_types.hpp> #include #include // for MB_LEN_MAX #include #include #include #include _EXTERN_C_UNLESS_PURE _CRTIMP2_PURE _Cvtvec __CLRCALL_PURE_OR_CDECL _Getcvt() noexcept { // get conversion info for current locale _Cvtvec _Cvt = {0}; _Cvt._Page = ___lc_codepage_func(); _Cvt._Mbcurmax = ___mb_cur_max_func(); _Cvt._Isclocale = ___lc_locale_name_func()[LC_CTYPE] == nullptr; if (!_Cvt._Isclocale) { const unsigned short* const _Ctype_table = __pctype_func(); for (int _Idx = 0; _Idx < 256; ++_Idx) { if (_Ctype_table[_Idx] & _LEADBYTE) { _Cvt._Isleadbyte[_Idx >> 3] |= 1 << (_Idx & 7); } } } return _Cvt; } // int _Wcrtomb() - Convert wide character to multibyte character. // // Purpose: // Convert a wide character into the equivalent multi-byte character, // according to the specified LC_CTYPE category, or the current locale. // [ANSI]. // // Entry: // char* s = pointer to multibyte character // wchar_t wchar = source wide character // mbstate_t* pst = pointer to state (not used) // const _Cvtvec* ploc = pointer to locale info // // Exit: // Returns: // -1 (if error) or number of bytes comprising converted mbc // // Exceptions: // None. _CRTIMP2_PURE _Success_(return != -1) int __CLRCALL_PURE_OR_CDECL _Wcrtomb(_Out_ char* s, wchar_t wchar, mbstate_t* pst, const _Cvtvec* ploc) noexcept { _CRT_UNUSED(pst); if (ploc->_Isclocale) { if (wchar > 255) { // validate high byte errno = EILSEQ; return -1; } *s = static_cast(wchar); return sizeof(char); } else { BOOL defused = 0; _Cvtvec cvtvec; if (ploc == nullptr) { cvtvec = _Getcvt(); ploc = &cvtvec; } const int size = WideCharToMultiByte(ploc->_Page, 0, &wchar, 1, s, ploc->_Mbcurmax, nullptr, &defused); if (size == 0 || defused) { errno = EILSEQ; return -1; } return size; } } #ifdef MRTDLL _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _Wcrtomb( char* s, unsigned short wchar, mbstate_t* pst, const _Cvtvec* ploc) noexcept { return _Wcrtomb(s, static_cast(wchar), pst, ploc); } #endif // defined(MRTDLL) // TRANSITION, ABI: __Wcrtomb_lk() is preserved for binary compatibility _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL __Wcrtomb_lk( char* s, wchar_t wchar, mbstate_t* pst, const _Cvtvec* ploc) noexcept { return _Wcrtomb(s, wchar, pst, ploc); } _END_EXTERN_C_UNLESS_PURE