Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236/****a_map.c - A version of LCMapString.** Copyright (c) Microsoft Corporation. All rights reserved.**Purpose:* Use either LCMapStringA or LCMapStringW depending on which is available********************************************************************************/#include <corecrt_internal.h>#include <locale.h>
/****int __cdecl __acrt_LCMapStringA - Get type information about an ANSI string.**Purpose:* Internal support function. Assumes info in ANSI string format. Tries* to use NLS API call LCMapStringA if available and uses LCMapStringW* if it must. If neither are available it fails and returns 0.**Entry:* LPCWSTR LocaleName - locale context for the comparison.* DWORD dwMapFlags - see NT\Chicago docs* PCCH cchSrc - wide char (word) count of input string* (including nullptr if any)* (-1 if nullptr terminated)* PCH lpDestStr - pointer to memory to store mapping* int cchDest - char (byte) count of buffer (including nullptr)* int code_page - for MB/WC conversion. If 0, use __lc_codepage* BOOL bError - TRUE if MB_ERR_INVALID_CHARS set on call to* MultiByteToWideChar when GetStringTypeW used.**Exit:* Success: number of chars written to lpDestStr (including nullptr)* Failure: 0**Exceptions:********************************************************************************/
static _Success_(return != 0) int __cdecl __acrt_LCMapStringA_stat( _In_opt_ _locale_t plocinfo, _In_ LPCWSTR LocaleName, _In_ DWORD dwMapFlags, _In_CRT_NLS_string_(cchSrc) PCCH lpSrcStr, _In_ int cchSrc, _Out_writes_opt_(cchDest) PCH lpDestStr, _In_ int cchDest, _In_ int code_page, _In_ BOOL bError ){ // LCMapString will map past the null terminator. We must find the null // terminator if it occurs in the string before cchSrc characters // and cap the number of characters to be considered. if (cchSrc > 0) { int cchSrcCnt = static_cast<int>(__strncnt(lpSrcStr, cchSrc));
// Include the null terminator if the source string is terminated within // the buffer. if (cchSrcCnt < cchSrc) { cchSrc = cchSrcCnt + 1; } else { cchSrc = cchSrcCnt; } }
int retval = 0; int inbuff_size; int outbuff_size;
/* * Convert string and return the requested information. Note that * we are converting to a wide string so there is not a * one-to-one correspondence between number of wide chars in the * input string and the number of *bytes* in the buffer. However, * there had *better be* a one-to-one correspondence between the * number of wide characters and the number of multibyte characters * or the resulting mapped string will be worthless to the user. */
/* * Use __lc_codepage for conversion if code_page not specified */
if (0 == code_page) code_page = plocinfo->locinfo->_public._locale_lc_codepage;
/* find out how big a buffer we need (includes nullptr if any) */ if ( 0 == (inbuff_size = __acrt_MultiByteToWideChar( code_page, bError ? MB_PRECOMPOSED | MB_ERR_INVALID_CHARS : MB_PRECOMPOSED, lpSrcStr, cchSrc, nullptr, 0 )) ) return 0;
/* allocate enough space for wide chars */ __crt_scoped_stack_ptr<wchar_t> const inwbuffer(_malloca_crt_t(wchar_t, inbuff_size)); if (!inwbuffer) return 0;
/* do the conversion */ if ( 0 == __acrt_MultiByteToWideChar( code_page, MB_PRECOMPOSED, lpSrcStr, cchSrc, inwbuffer.get(), inbuff_size) ) return retval;
/* get size required for string mapping */ if ( 0 == (retval = __acrt_LCMapStringEx( LocaleName, dwMapFlags, inwbuffer.get(), inbuff_size, nullptr, 0, nullptr, nullptr, 0)) ) return retval;
if (dwMapFlags & LCMAP_SORTKEY) { /* retval is size in BYTES */
if (0 != cchDest) {
if (retval > cchDest) return 0;
/* do string mapping */ // The buffer overflow warning here is due to an inadequate annotation // on __acrt_LCMapStringEx. When the map flags include LCMAP_SORTKEY, // the destination buffer is actually required to be an array of bytes, // despite the type of the buffer being a wchar_t*. __pragma(warning(suppress: __WARNING_BUFFER_OVERFLOW)) if ( 0 == (retval = __acrt_LCMapStringEx( LocaleName, dwMapFlags, inwbuffer.get(), inbuff_size, reinterpret_cast<PWCH>(lpDestStr), cchDest, nullptr, nullptr, 0)) ) return retval; } } else { /* retval is size in wide chars */
outbuff_size = retval;
/* allocate enough space for wide chars (includes nullptr if any) */ __crt_scoped_stack_ptr<wchar_t> const outwbuffer(_malloca_crt_t(wchar_t, outbuff_size)); if (!outwbuffer) return 0;
/* do string mapping */ if ( 0 == (retval = __acrt_LCMapStringEx( LocaleName, dwMapFlags, inwbuffer.get(), inbuff_size, outwbuffer.get(), outbuff_size, nullptr, nullptr, 0)) ) return retval;
if (0 == cchDest) { /* get size required */ if ( 0 == (retval = __acrt_WideCharToMultiByte( code_page, 0, outwbuffer.get(), outbuff_size, nullptr, 0, nullptr, nullptr )) ) return retval; } else { /* convert mapping */ if ( 0 == (retval = __acrt_WideCharToMultiByte( code_page, 0, outwbuffer.get(), outbuff_size, lpDestStr, cchDest, nullptr, nullptr )) ) return retval; } }
return retval;}
extern "C" int __cdecl __acrt_LCMapStringA( _locale_t const plocinfo, PCWSTR const LocaleName, DWORD const dwMapFlags, PCCH const lpSrcStr, int const cchSrc, PCH const lpDestStr, int const cchDest, int const code_page, BOOL const bError ){ _LocaleUpdate _loc_update(plocinfo);
return __acrt_LCMapStringA_stat( _loc_update.GetLocaleT(), LocaleName, dwMapFlags, lpSrcStr, cchSrc, lpDestStr, cchDest, code_page, bError );}