| Server IP : 209.209.40.120 / Your IP : 216.73.217.112 Web Server : Microsoft-IIS/10.0 System : Windows NT NEWWWW 10.0 build 17763 (Windows Server 2019) i586 User : NEWWWW$ ( 0) PHP Version : 8.3.30 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : C:/Program Files (x86)/Windows Kits/10/Source/10.0.19041.0/ucrt/mbstring/ |
Upload File : |
/***
*mbctype.c - MBCS table used by the functions that test for types of char
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
* table used to determine the type of char
*
*******************************************************************************/
#include <corecrt_internal.h>
#include <locale.h>
#include <corecrt_internal_mbstring.h>
#include <mbctype.h>
#include <winnls.h>
#ifndef CRTDLL
_CRT_LINKER_FORCE_INCLUDE(__acrt_multibyte_initializer);
#endif /* CRTDLL */
#define _CHINESE_SIMP_CP 936
#define _KOREAN_WANGSUNG_CP 949
#define _CHINESE_TRAD_CP 950
#define _KOREAN_JOHAB_CP 1361
#define NUM_CHARS 257 /* -1 through 255 */
#define NUM_CTYPES 4 /* table contains 4 types of info */
#define MAX_RANGES 8 /* max number of ranges needed given languages so far */
/* character type info in ranges (pair of low/high), zeros indicate end */
typedef struct
{
int code_page;
unsigned short mbulinfo[NUM_ULINFO];
unsigned char rgrange[NUM_CTYPES][MAX_RANGES];
} code_page_info;
extern "C"
{
__crt_multibyte_data __acrt_initial_multibyte_data =
{
0, /* refcount */
CP_ACP, /* mbcodepage: _MB_CP_ANSI */
0, /* ismbcodepage */
{ 0, 0, 0, 0, 0, 0 }, /* mbulinfo[6] */
{ /* mbctype[257] */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00 /* rest is zero */
},
{ /* mbcasemap[256] */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b,
0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00 /* rest is zero */
},
nullptr /* mblocalename */
};
#define _MBCTYPE_DEFAULT \
{ \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, \
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, \
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00 /* rest is zero */ \
}
/* MBCS ctype array */
static unsigned char _mbctypes[__crt_state_management::state_index_count][NUM_CHARS] =
{
_MBCTYPE_DEFAULT
#ifdef _CRT_GLOBAL_STATE_ISOLATION
,_MBCTYPE_DEFAULT
#endif
};
#define _MBCASEMAP_DEFAULT \
{ \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, \
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, \
0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, \
0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, \
0x58, 0x59, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00 /* rest is zero */ \
}
static unsigned char _mbcasemaps[__crt_state_management::state_index_count][256] =
{
_MBCASEMAP_DEFAULT
#ifdef _CRT_GLOBAL_STATE_ISOLATION
,_MBCASEMAP_DEFAULT
#endif
};
/* global pointer to the multi-byte case type (i.e. upper or lower or n/a) */
__crt_state_management::dual_state_global<unsigned char*> _mbctype;
/* global pointer to the multi-byte casemap */
__crt_state_management::dual_state_global<unsigned char*> _mbcasemap;
/* global pointer to the current per-thread mbc information structure. */
__crt_state_management::dual_state_global<__crt_multibyte_data*> __acrt_current_multibyte_data;
}
static int fSystemSet;
static char __rgctypeflag[NUM_CTYPES] = { _MS, _MP, _M1, _M2 };
static code_page_info __rgcode_page_info[] =
{
{
_KANJI_CP, /* Kanji (Japanese) Code Page */
{ 0x8260, 0x8279, /* Full-Width Latin Upper Range 1 */
0x8281 - 0x8260, /* Full-Width Latin Case Difference 1 */
0x0000, 0x0000, /* Full-Width Latin Upper Range 2 */
0x0000 /* Full-Width Latin Case Difference 2 */
},
{
{ 0xA6, 0xDF, 0, 0, 0, 0, 0, 0, }, /* Single Byte Ranges */
{ 0xA1, 0xA5, 0, 0, 0, 0, 0, 0, }, /* Punctuation Ranges */
{ 0x81, 0x9F, 0xE0, 0xFC, 0, 0, 0, 0, }, /* Lead Byte Ranges */
{ 0x40, 0x7E, 0x80, 0xFC, 0, 0, 0, 0, }, /* Trail Byte Ranges */
}
},
{
_CHINESE_SIMP_CP, /* Chinese Simplified (PRC) Code Page */
{ 0xA3C1, 0xA3DA, /* Full-Width Latin Upper Range 1 */
0xA3E1 - 0xA3C1, /* Full-Width Latin Case Difference 1 */
0x0000, 0x0000, /* Full-Width Latin Upper Range 2 */
0x0000 /* Full-Width Latin Case Difference 2 */
},
{
{ 0, 0, 0, 0, 0, 0, 0, 0, }, /* Single Byte Ranges */
{ 0, 0, 0, 0, 0, 0, 0, 0, }, /* Punctuation Ranges */
{ 0x81, 0xFE, 0, 0, 0, 0, 0, 0, }, /* Lead Byte Ranges */
{ 0x40, 0xFE, 0, 0, 0, 0, 0, 0, }, /* Trail Byte Ranges */
}
},
{
_KOREAN_WANGSUNG_CP, /* Wangsung (Korean) Code Page */
{ 0xA3C1, 0xA3DA, /* Full-Width Latin Upper Range 1 */
0xA3E1 - 0xA3C1, /* Full-Width Latin Case Difference 1 */
0x0000, 0x0000, /* Full-Width Latin Upper Range 2 */
0x0000 /* Full-Width Latin Case Difference 2 */
},
{
{ 0, 0, 0, 0, 0, 0, 0, 0, }, /* Single Byte Ranges */
{ 0, 0, 0, 0, 0, 0, 0, 0, }, /* Punctuation Ranges */
{ 0x81, 0xFE, 0, 0, 0, 0, 0, 0, }, /* Lead Byte Ranges */
{ 0x41, 0xFE, 0, 0, 0, 0, 0, 0, }, /* Trail Byte Ranges */
}
},
{
_CHINESE_TRAD_CP, /* Chinese Traditional (Taiwan) Code Page */
{ 0xA2CF, 0xA2E4, /* Full-Width Latin Upper Range 1 */
0xA2E9 - 0xA2CF, /* Full-Width Latin Case Difference 1 */
0xA2E5, 0xA2E8, /* Full-Width Latin Upper Range 2 */
0xA340 - 0XA2E5 /* Full-Width Latin Case Difference 2 */
},
{
{ 0, 0, 0, 0, 0, 0, 0, 0, }, /* Single Byte Ranges */
{ 0, 0, 0, 0, 0, 0, 0, 0, }, /* Punctuation Ranges */
{ 0x81, 0xFE, 0, 0, 0, 0, 0, 0, }, /* Lead Byte Ranges */
{ 0x40, 0x7E, 0xA1, 0xFE, 0, 0, 0, 0, }, /* Trail Byte Ranges */
}
},
{
_KOREAN_JOHAB_CP, /* Johab (Korean) Code Page */
{ 0xDA51, 0xDA5E, /* Full-Width Latin Upper Range 1 */
0xDA71 - 0xDA51, /* Full-Width Latin Case Difference 1 */
0xDA5F, 0xDA6A, /* Full-Width Latin Upper Range 2 */
0xDA91 - 0xDA5F /* Full-Width Latin Case Difference 2 */
},
{
{ 0, 0, 0, 0, 0, 0, 0, 0, }, /* Single Byte Ranges */
{ 0, 0, 0, 0, 0, 0, 0, 0, }, /* Punctuation Ranges */
{ 0x81, 0xD3, 0xD8, 0xDE, 0xE0, 0xF9, 0, 0, }, /* Lead Byte Ranges */
{ 0x31, 0x7E, 0x81, 0xFE, 0, 0, 0, 0, }, /* Trail Byte Ranges */
}
}
};
#define JAPANSE_DEFAULT_LOCALE_NAME_INDEX 0
#define CHINESE_SIMPLIFIED_LOCALE_NAME_INDEX 1
#define KOREAN_DEFAULT_LOCALE_NAME_INDEX 2
#define CHINESE_TRADITIONAL_LOCALE_NAME_INDEX 3
const wchar_t* const _mb_locale_names[] =
{
L"ja-JP", /* JAPANSE_DEFAULT_LOCALE_NAME_INDEX */
L"zh-CN", /* CHINESE_SIMPLIFIED_LOCALE_NAME_INDEX */
L"ko-KR", /* KOREAN_DEFAULT_LOCALE_NAME_INDEX */
L"zh-TW", /* CHINESE_TRADITIONAL_LOCALE_NAME_INDEX */
};
extern "C" unsigned char* __cdecl __p__mbctype()
{
return _mbctype.value();
}
extern "C" unsigned char* __cdecl __p__mbcasemap()
{
return _mbcasemap.value();
}
extern "C" int __cdecl _setmbcp_nolock(int, __crt_multibyte_data*);
static int getSystemCP (int);
/***
*setSBCS() - Set MB code page to SBCS.
*
*Purpose:
* Set MB code page to SBCS.
*Entry:
*
*Exit:
*
*Exceptions:
*
*******************************************************************************/
static void setSBCS (__crt_multibyte_data* ptmbci)
{
int i;
/* set for single-byte code page */
for (i = 0; i < NUM_CHARS; i++)
ptmbci->mbctype[i] = 0;
/* code page has changed, set global flag */
ptmbci->mbcodepage = 0;
/* clear flag to indicate single-byte code */
ptmbci->ismbcodepage = 0;
ptmbci->mblocalename = nullptr;
for (i = 0; i < NUM_ULINFO; i++)
ptmbci->mbulinfo[i] = 0;
for ( i = 0 ; i < 257 ; i++ )
ptmbci->mbctype[i] = __acrt_initial_multibyte_data.mbctype[i];
for ( i = 0 ; i < 256 ; i++ )
ptmbci->mbcasemap[i] = __acrt_initial_multibyte_data.mbcasemap[i];
}
/***
*__acrt_update_thread_multibyte_data() - refresh the thread's mbc info
*
*Purpose:
* Update the current thread's reference to the multibyte character
* information to match the current global mbc info. Decrement the
* reference on the old mbc information struct and if this count is now
* zero (so that no threads are using it), free it.
*
*Entry:
*
*Exit:
* _getptd()->ptmbcinfo == current_multibyte_data (which should always be __acrt_current_multibyte_data)
*
*Exceptions:
*
*******************************************************************************/
static __crt_multibyte_data* __cdecl update_thread_multibyte_data_internal(
__acrt_ptd* const ptd,
__crt_multibyte_data** const current_multibyte_data
) throw()
{
__crt_multibyte_data* ptmbci = nullptr;
if (__acrt_should_sync_with_global_locale(ptd) || ptd->_locale_info == nullptr)
{
__acrt_lock(__acrt_multibyte_cp_lock);
__try
{
ptmbci = ptd->_multibyte_info;
if (ptmbci != *current_multibyte_data)
{
/*
* Decrement the reference count in the old mbc info structure
* and free it, if necessary
*/
if (ptmbci != nullptr &&
InterlockedDecrement(&ptmbci->refcount) == 0 &&
ptmbci != &__acrt_initial_multibyte_data)
{
/*
* Free it
*/
_free_crt(ptmbci);
}
/*
* Point to the current mbc info structure and increment its
* reference count.
*/
ptmbci = ptd->_multibyte_info = *current_multibyte_data;
InterlockedIncrement(&ptmbci->refcount);
}
}
__finally
{
__acrt_unlock(__acrt_multibyte_cp_lock);
}
}
else
{
ptmbci = ptd->_multibyte_info;
}
if (!ptmbci)
{
abort();
}
return ptmbci;
}
extern "C" __crt_multibyte_data* __cdecl __acrt_update_thread_multibyte_data()
{
return update_thread_multibyte_data_internal(__acrt_getptd(), &__acrt_current_multibyte_data.value());
}
/***
*_setmbcp() - Set MBC data based on code page
*
*Purpose:
* Init MBC character type tables based on code page number. If
* given code page is supported, load that code page info into
* mbctype table. If not, query OS to find the information,
* otherwise set up table with single byte info.
*
* Multithread Notes: First, allocate an mbc information struct. Set the
* mbc info in the static vars and arrays as does the single-thread
* version. Then, copy this info into the new allocated struct and set
* the current mbc info pointer (__acrt_current_multibyte_data) to point to it.
*
*Entry:
* codepage - code page to initialize MBC table
* _MB_CP_OEM = use system OEM code page
* _MB_CP_ANSI = use system ANSI code page
* _MB_CP_SBCS = set to single byte 'code page'
*
*Exit:
* 0 = Success
* -1 = Error, code page not changed.
*
*Exceptions:
*
*******************************************************************************/
static int __cdecl setmbcp_internal(
int const requested_codepage,
bool const is_for_crt_initialization,
__acrt_ptd* const ptd,
__crt_multibyte_data** const current_multibyte_data
) throw()
{
update_thread_multibyte_data_internal(ptd, current_multibyte_data);
int const system_codepage = getSystemCP(requested_codepage);
// If it's not a new codepage, just return success:
if (system_codepage == ptd->_multibyte_info->mbcodepage)
{
return 0;
}
// Always allocate space so that we don't have to take a lock for any update:
__crt_unique_heap_ptr<__crt_multibyte_data> mb_data(_malloc_crt_t(__crt_multibyte_data, 1));
if (!mb_data)
{
return -1;
}
// Initialize the new multibyte data structure from the current multibyte
// data structure for this thread, resetting the reference count (since it
// is not actually referenced by anything yet).
*mb_data.get() = *ptd->_multibyte_info;
mb_data.get()->refcount = 0;
// Actually initialize the new multibyte data using the new codepage:
// CRT_REFACTOR TODO _setmbcp_nolock is a terrible name.
int const setmbcp_status = _setmbcp_nolock(system_codepage, mb_data.get());
if (setmbcp_status == -1)
{
errno = EINVAL;
return -1;
}
// At this point, we have a valid, new set of multibyte data to swap in. If
// this is not the initial codepage initialization during process startup,
// we need to toggle the locale-changed state:
if (!is_for_crt_initialization)
{
__acrt_set_locale_changed();
}
if (InterlockedDecrement(&ptd->_multibyte_info->refcount) == 0 &&
ptd->_multibyte_info != &__acrt_initial_multibyte_data)
{
_free_crt(ptd->_multibyte_info);
}
// Update the multibyte codepage for this thread:
mb_data.get()->refcount = 1;
ptd->_multibyte_info = mb_data.detach();
// If this thread has its own locale, do not update the global codepage:
if (!__acrt_should_sync_with_global_locale(ptd))
{
return setmbcp_status;
}
// Otherwise, update the global codepage:
__acrt_lock_and_call(__acrt_multibyte_cp_lock, [&]
{
memcpy_s(_mbctype.value(), sizeof(_mbctypes[0]), ptd->_multibyte_info->mbctype, sizeof(ptd->_multibyte_info->mbctype));
memcpy_s(_mbcasemap.value(), sizeof(_mbcasemaps[0]), ptd->_multibyte_info->mbcasemap, sizeof(ptd->_multibyte_info->mbcasemap));
if (InterlockedDecrement(&(*current_multibyte_data)->refcount) == 0 &&
(*current_multibyte_data) != &__acrt_initial_multibyte_data)
{
_free_crt(*current_multibyte_data);
}
*current_multibyte_data = ptd->_multibyte_info;
InterlockedIncrement(&ptd->_multibyte_info->refcount);
});
if (is_for_crt_initialization)
{
__acrt_initial_locale_pointers.mbcinfo = *current_multibyte_data;
}
return setmbcp_status;
}
/* Enclaves only support built-in CP_ACP */
#ifdef _UCRT_ENCLAVE_BUILD
static int getSystemCP(int)
{
return CP_ACP;
}
extern "C" int __cdecl _setmbcp_nolock(int, __crt_multibyte_data* ptmbci)
{
setSBCS(ptmbci);
return 0;
}
#else /* ^^^ _UCRT_ENCLAVE_BUILD ^^^ // vvv !_UCRT_ENCLAVE_BUILD vvv */
/***
*CPtoLocaleName() - Code page to locale name.
*
*Purpose:
* Some API calls want a locale name, so convert MB CP to appropriate locale name,
* and then API converts back to ANSI CP for that locale name.
*
*Entry:
* codepage - code page to convert
*Exit:
* returns appropriate locale name
* Returned locale names are stored in static structs, so they must not be deleted.
*
*Exceptions:
*
*******************************************************************************/
static const wchar_t* CPtoLocaleName (int codepage)
{
switch (codepage) {
case 932:
return _mb_locale_names[JAPANSE_DEFAULT_LOCALE_NAME_INDEX];
case 936:
return _mb_locale_names[CHINESE_SIMPLIFIED_LOCALE_NAME_INDEX];
case 949:
return _mb_locale_names[KOREAN_DEFAULT_LOCALE_NAME_INDEX];
case 950:
return _mb_locale_names[CHINESE_TRADITIONAL_LOCALE_NAME_INDEX];
}
return 0;
}
/***
*getSystemCP - Get system default CP if requested.
*
*Purpose:
* Get system default CP if requested.
*
*Entry:
* codepage - user requested code page/world script
*
* Docs specify:
* _MB_CP_SBCS 0 - Use a single byte codepage
* _MB_CP_OEM -2 - use the OEMCP
* _MB_CP_ANSI -3 - use the ACP
* _MB_CP_LOCALE -4 - use the codepage for a previous setlocale call
* Codepage # - use the specified codepage (UTF-7 is disallowed)
* - 54936 and other interesting stateful codepages aren't
* - explicitly disallowed but I can't imagine them working right.
*
*Exit:
* requested code page
*
*Exceptions:
*
*******************************************************************************/
static int getSystemCP(int codepage)
{
_locale_t plocinfo = nullptr;
_LocaleUpdate _loc_update(plocinfo);
fSystemSet = 0;
/* get system code page values if requested */
if (codepage == _MB_CP_OEM)
{
fSystemSet = 1;
return GetOEMCP();
}
else if (codepage == _MB_CP_ANSI)
{
fSystemSet = 1;
return GetACP();
}
else if (codepage == _MB_CP_LOCALE)
{
fSystemSet = 1;
return _loc_update.GetLocaleT()->locinfo->_public._locale_lc_codepage;
}
return codepage;
}
/***
*setSBUpLow() - Set single byte range upper/lower mappings
*
*Purpose:
* Set single byte mapping for tolower/toupper.
* Basically this is ASCII-mapping plus a few if you're a lucky
* SBCS codepage.
* DBCS + UTF ranges > 0x7f are basically ignored.
*
*Entry:
*
*Exit:
*
*Exceptions:
*
*******************************************************************************/
static void setSBUpLow (__crt_multibyte_data* ptmbci)
{
BYTE * pbPair;
UINT ich;
CPINFO cpInfo;
UCHAR sbVector[256];
UCHAR upVector[256];
UCHAR lowVector[256];
USHORT wVector[512];
// test if codepage exists
if (ptmbci->mbcodepage != CP_UTF8 && GetCPInfo(ptmbci->mbcodepage, &cpInfo) != 0)
{
// This code attempts to generate casing tables for characters 0-255
// For DBCS codepages that will be basically ASCII casing but won't help DBCS mapping.
// For SBCS codepages that will include the codepage-specific characters.
// Mappings do not appear to include Turkish-i variations.
// if so, create vector 0-255
for (ich = 0; ich < 256; ich++)
sbVector[ich] = (UCHAR) ich;
// set byte 0 and any leading byte value to non-alpha char ' '
sbVector[0] = (UCHAR)' ';
for (pbPair = &cpInfo.LeadByte[0]; *pbPair; pbPair += 2)
// make sure ich within a valid range
for (ich = *pbPair; ich <= *(pbPair + 1) && ich < 256; ich++)
sbVector[ich] = (UCHAR)' ';
// get char type for character vector
__acrt_GetStringTypeA(nullptr, CT_CTYPE1, (LPCSTR)sbVector, 256, wVector,
ptmbci->mbcodepage, FALSE);
// get lower case mappings for character vector
__acrt_LCMapStringA(nullptr, ptmbci->mblocalename, LCMAP_LOWERCASE, (LPCSTR)sbVector, 256,
(LPSTR)lowVector, 256, ptmbci->mbcodepage, FALSE);
// get upper case mappings for character vector
__acrt_LCMapStringA(nullptr, ptmbci->mblocalename, LCMAP_UPPERCASE, (LPCSTR)sbVector, 256,
(LPSTR)upVector, 256, ptmbci->mbcodepage, FALSE);
// set _SBUP, _SBLOW in ptmbci->mbctype if type is upper. lower
// set mapping array with lower or upper mapping value
for (ich = 0; ich < 256; ich++)
{
if (wVector[ich] & _UPPER)
{
// WARNING: +1 because the mbctype array starts with a -1 EOF character
ptmbci->mbctype[ich + 1] |= _SBUP;
ptmbci->mbcasemap[ich] = lowVector[ich];
}
else if (wVector[ich] & _LOWER)
{
// WARNING: +1 because the mbctype array starts with a -1 EOF character
ptmbci->mbctype[ich + 1] |= _SBLOW;
ptmbci->mbcasemap[ich] = upVector[ich];
}
else
ptmbci->mbcasemap[ich] = 0;
}
}
else
{
// Either no codepage or UTF-8 (which looks a lot like ASCII in the lower bits)
// Set 'A'-'Z' as upper, 'a'-'z' as lower (eg: ASCII casing)
for (ich = 0; ich < 256; ich++)
{
if (ich >= (UINT)'A' && ich <= (UINT)'Z')
{
// WARNING: +1 because the mbctype array starts with a -1 EOF character
ptmbci->mbctype[ich + 1] |= _SBUP;
ptmbci->mbcasemap[ich] = static_cast<unsigned char>(ich + ('a' - 'A'));
}
else if (ich >= (UINT)'a' && ich <= (UINT)'z')
{
// WARNING: +1 because the mbctype array starts with a -1 EOF character
ptmbci->mbctype[ich + 1] |= _SBLOW;
ptmbci->mbcasemap[ich] = static_cast<unsigned char>(ich - ('a' - 'A'));
}
else
ptmbci->mbcasemap[ich] = 0;
}
}
}
extern "C" int __cdecl _setmbcp(int const codepage)
{
return setmbcp_internal(codepage, false, __acrt_getptd(), &__acrt_current_multibyte_data.value());
}
extern "C" int __cdecl _setmbcp_nolock(int codepage, __crt_multibyte_data* ptmbci)
{
unsigned int icp;
unsigned int irg;
unsigned int ich;
unsigned char *rgptr;
CPINFO cpInfo;
codepage = getSystemCP(codepage);
/* user wants 'single-byte' MB code page */
if (codepage == _MB_CP_SBCS)
{
setSBCS(ptmbci);
return 0;
}
/* check for CRT code page info */
for (icp = 0;
icp < (sizeof(__rgcode_page_info) / sizeof(code_page_info));
icp++)
{
/* see if we have info for this code page */
if (__rgcode_page_info[icp].code_page == codepage)
{
/* clear the table */
for (ich = 0; ich < NUM_CHARS; ich++)
ptmbci->mbctype[ich] = 0;
/* for each type of info, load table */
for (irg = 0; irg < NUM_CTYPES; irg++)
{
/* go through all the ranges for each type of info */
for (rgptr = (unsigned char *)__rgcode_page_info[icp].rgrange[irg];
rgptr[0] && rgptr[1];
rgptr += 2)
{
/* set the type for every character in range */
for (ich = rgptr[0]; ich <= rgptr[1] && ich < 256; ich++)
ptmbci->mbctype[ich + 1] |= __rgctypeflag[irg];
}
}
/* code page has changed */
ptmbci->mbcodepage = codepage;
/* all the code pages we keep info for are truly multibyte */
ptmbci->ismbcodepage = 1;
ptmbci->mblocalename = CPtoLocaleName(ptmbci->mbcodepage);
for (irg = 0; irg < NUM_ULINFO; irg++)
{
ptmbci->mbulinfo[irg] = __rgcode_page_info[icp].mbulinfo[irg];
}
/* return success */
setSBUpLow(ptmbci);
return 0;
}
}
/* verify codepage validity */
// Unclear why UTF7 is excluded yet stateful and other complex encodings are not
if (codepage == 0 || codepage == CP_UTF7 || !IsValidCodePage((WORD)codepage))
{
/* return failure, code page not changed */
return -1;
}
// Special case for UTF-8
if (codepage == CP_UTF8)
{
ptmbci->mbcodepage = CP_UTF8;
ptmbci->mblocalename = nullptr;
// UTF-8 does not have lead or trail bytes in the terms
// the CRT thinks of it for DBCS codepages, so we'll
// clear the flags for all bytes.
// Note that this array is 257 bytes because there's a
// "-1" that is used someplaces for EOF. So this array
// is actually -1 based.
for (ich = 0; ich < NUM_ULINFO; ich++)
{
ptmbci->mbctype[ich] = 0;
}
// not really a multibyte code page, we'll have to test
// ptmbci->mbcodepage == CP_UTF8 when we use this structure.
ptmbci->ismbcodepage = 0;
// CJK encodings have some full-width mappings, but not here.
for (irg = 0; irg < NUM_ULINFO; irg++)
{
ptmbci->mbulinfo[irg] = 0;
}
setSBUpLow(ptmbci);
// return success
return 0;
}
/* code page not supported by CRT, try the OS */\
else if (GetCPInfo(codepage, &cpInfo) != 0)
{
BYTE *lbptr;
/* clear the table */
for (ich = 0; ich < NUM_CHARS; ich++)
{
ptmbci->mbctype[ich] = 0;
}
ptmbci->mbcodepage = codepage;
ptmbci->mblocalename = nullptr;
// Special case for DBCS where we know there may be a leadbyte/trailbyte pattern
if (cpInfo.MaxCharSize == 2)
{
/* LeadByte range always terminated by two 0's */
for (lbptr = cpInfo.LeadByte; *lbptr && *(lbptr + 1); lbptr += 2)
{
for (ich = *lbptr; ich <= *(lbptr + 1); ich++)
ptmbci->mbctype[ich + 1] |= _M1;
}
/* All chars > 1 must be considered valid trail bytes */
for (ich = 0x01; ich < 0xFF; ich++)
{
ptmbci->mbctype[ich + 1] |= _M2;
}
/* code page has changed */
ptmbci->mblocalename = CPtoLocaleName(ptmbci->mbcodepage);
/* really a multibyte code page */
ptmbci->ismbcodepage = 1;
}
else
{
/* single-byte code page */
ptmbci->ismbcodepage = 0;
}
for (irg = 0; irg < NUM_ULINFO; irg++)
{
ptmbci->mbulinfo[irg] = 0;
}
setSBUpLow(ptmbci);
/* return success */
return 0;
}
/* If system default call, don't fail - set to SBCS */
if (fSystemSet)
{
setSBCS(ptmbci);
return 0;
}
/* return failure, code page not changed */
return -1;
}
#endif /* _UCRT_ENCLAVE_BUILD */
/***
*_getmbcp() - Get the current MBC code page
*
*Purpose:
* Get code page value.
*Entry:
* none.
*Exit:
* return current MB codepage value.
*
*Exceptions:
*
*******************************************************************************/
extern "C" int __cdecl _getmbcp()
{
_locale_t plocinfo = nullptr;
_LocaleUpdate _loc_update(plocinfo);
if ( _loc_update.GetLocaleT()->mbcinfo->ismbcodepage )
return _loc_update.GetLocaleT()->mbcinfo->mbcodepage;
else
return 0;
}
/***
*_initmbctable() - Set MB ctype table to initial default value.
*
*Purpose:
* Initialization.
*Entry:
* none.
*Exit:
* Returns 0 to indicate no error.
*Exceptions:
*
*******************************************************************************/
extern "C" bool __cdecl __acrt_initialize_multibyte()
{
static bool initialized = false;
// Synchronization note: it is not possible for a data race to occur here.
// In the CRT DLLs, this function is called during CRT startup, befor any
// user code using the CRT may run. In the static CRT, this function is
// called by a CRT initializer (at the top of this file), so 'initialized'
// will be true before any user code can enter the CRT.
//
// CRT_REFACTOR TODO We should split this function into two parts: one that
// does the initialization (without any check), and one that does nothing,
// but can be used to cause this object to be linked in.
if (!initialized)
{
// initialize global pointer to the current per-thread mbc information structure
__acrt_current_multibyte_data.initialize(&__acrt_initial_multibyte_data);
// initialize mbc pointers
_mbcasemap.initialize_from_array(_mbcasemaps);
_mbctype .initialize_from_array(_mbctypes);
// initialize the multibyte globals
__acrt_ptd* const ptd_head = __acrt_getptd_head();
for (size_t i = 0; i != __crt_state_management::state_index_count; ++i)
{
setmbcp_internal(_MB_CP_ANSI, true, ptd_head + i, &__acrt_current_multibyte_data.dangerous_get_state_array()[i]);
}
initialized = 1;
}
return true;
}
/************************ Code Page info from NT/Win95 ********************
*** Code Page 932 ***
0x824f ;Fullwidth Digit Zero
0x8250 ;Fullwidth Digit One
0x8251 ;Fullwidth Digit Two
0x8252 ;Fullwidth Digit Three
0x8253 ;Fullwidth Digit Four
0x8254 ;Fullwidth Digit Five
0x8255 ;Fullwidth Digit Six
0x8256 ;Fullwidth Digit Seven
0x8257 ;Fullwidth Digit Eight
0x8258 ;Fullwidth Digit Nine
0x8281 0x8260 ;Fullwidth Small A -> Fullwidth Capital A
0x8282 0x8261 ;Fullwidth Small B -> Fullwidth Capital B
0x8283 0x8262 ;Fullwidth Small C -> Fullwidth Capital C
0x8284 0x8263 ;Fullwidth Small D -> Fullwidth Capital D
0x8285 0x8264 ;Fullwidth Small E -> Fullwidth Capital E
0x8286 0x8265 ;Fullwidth Small F -> Fullwidth Capital F
0x8287 0x8266 ;Fullwidth Small G -> Fullwidth Capital G
0x8288 0x8267 ;Fullwidth Small H -> Fullwidth Capital H
0x8289 0x8268 ;Fullwidth Small I -> Fullwidth Capital I
0x828a 0x8269 ;Fullwidth Small J -> Fullwidth Capital J
0x828b 0x826a ;Fullwidth Small K -> Fullwidth Capital K
0x828c 0x826b ;Fullwidth Small L -> Fullwidth Capital L
0x828d 0x826c ;Fullwidth Small M -> Fullwidth Capital M
0x828e 0x826d ;Fullwidth Small N -> Fullwidth Capital N
0x828f 0x826e ;Fullwidth Small O -> Fullwidth Capital O
0x8290 0x826f ;Fullwidth Small P -> Fullwidth Capital P
0x8291 0x8270 ;Fullwidth Small Q -> Fullwidth Capital Q
0x8292 0x8271 ;Fullwidth Small R -> Fullwidth Capital R
0x8293 0x8272 ;Fullwidth Small S -> Fullwidth Capital S
0x8294 0x8273 ;Fullwidth Small T -> Fullwidth Capital T
0x8295 0x8274 ;Fullwidth Small U -> Fullwidth Capital U
0x8296 0x8275 ;Fullwidth Small V -> Fullwidth Capital V
0x8297 0x8276 ;Fullwidth Small W -> Fullwidth Capital W
0x8298 0x8277 ;Fullwidth Small X -> Fullwidth Capital X
0x8299 0x8278 ;Fullwidth Small Y -> Fullwidth Capital Y
0x829a 0x8279 ;Fullwidth Small Z -> Fullwidth Capital Z
*** Code Page 936 ***
0xa3b0 ;Fullwidth Digit Zero
0xa3b1 ;Fullwidth Digit One
0xa3b2 ;Fullwidth Digit Two
0xa3b3 ;Fullwidth Digit Three
0xa3b4 ;Fullwidth Digit Four
0xa3b5 ;Fullwidth Digit Five
0xa3b6 ;Fullwidth Digit Six
0xa3b7 ;Fullwidth Digit Seven
0xa3b8 ;Fullwidth Digit Eight
0xa3b9 ;Fullwidth Digit Nine
0xa3e1 0xa3c1 ;Fullwidth Small A -> Fullwidth Capital A
0xa3e2 0xa3c2 ;Fullwidth Small B -> Fullwidth Capital B
0xa3e3 0xa3c3 ;Fullwidth Small C -> Fullwidth Capital C
0xa3e4 0xa3c4 ;Fullwidth Small D -> Fullwidth Capital D
0xa3e5 0xa3c5 ;Fullwidth Small E -> Fullwidth Capital E
0xa3e6 0xa3c6 ;Fullwidth Small F -> Fullwidth Capital F
0xa3e7 0xa3c7 ;Fullwidth Small G -> Fullwidth Capital G
0xa3e8 0xa3c8 ;Fullwidth Small H -> Fullwidth Capital H
0xa3e9 0xa3c9 ;Fullwidth Small I -> Fullwidth Capital I
0xa3ea 0xa3ca ;Fullwidth Small J -> Fullwidth Capital J
0xa3eb 0xa3cb ;Fullwidth Small K -> Fullwidth Capital K
0xa3ec 0xa3cc ;Fullwidth Small L -> Fullwidth Capital L
0xa3ed 0xa3cd ;Fullwidth Small M -> Fullwidth Capital M
0xa3ee 0xa3ce ;Fullwidth Small N -> Fullwidth Capital N
0xa3ef 0xa3cf ;Fullwidth Small O -> Fullwidth Capital O
0xa3f0 0xa3d0 ;Fullwidth Small P -> Fullwidth Capital P
0xa3f1 0xa3d1 ;Fullwidth Small Q -> Fullwidth Capital Q
0xa3f2 0xa3d2 ;Fullwidth Small R -> Fullwidth Capital R
0xa3f3 0xa3d3 ;Fullwidth Small S -> Fullwidth Capital S
0xa3f4 0xa3d4 ;Fullwidth Small T -> Fullwidth Capital T
0xa3f5 0xa3d5 ;Fullwidth Small U -> Fullwidth Capital U
0xa3f6 0xa3d6 ;Fullwidth Small V -> Fullwidth Capital V
0xa3f7 0xa3d7 ;Fullwidth Small W -> Fullwidth Capital W
0xa3f8 0xa3d8 ;Fullwidth Small X -> Fullwidth Capital X
0xa3f9 0xa3d9 ;Fullwidth Small Y -> Fullwidth Capital Y
0xa3fa 0xa3da ;Fullwidth Small Z -> Fullwidth Capital Z
*** Code Page 949 ***
0xa3b0 ;Fullwidth Digit Zero
0xa3b1 ;Fullwidth Digit One
0xa3b2 ;Fullwidth Digit Two
0xa3b3 ;Fullwidth Digit Three
0xa3b4 ;Fullwidth Digit Four
0xa3b5 ;Fullwidth Digit Five
0xa3b6 ;Fullwidth Digit Six
0xa3b7 ;Fullwidth Digit Seven
0xa3b8 ;Fullwidth Digit Eight
0xa3b9 ;Fullwidth Digit Nine
0xa3e1 0xa3c1 ;Fullwidth Small A -> Fullwidth Capital A
0xa3e2 0xa3c2 ;Fullwidth Small B -> Fullwidth Capital B
0xa3e3 0xa3c3 ;Fullwidth Small C -> Fullwidth Capital C
0xa3e4 0xa3c4 ;Fullwidth Small D -> Fullwidth Capital D
0xa3e5 0xa3c5 ;Fullwidth Small E -> Fullwidth Capital E
0xa3e6 0xa3c6 ;Fullwidth Small F -> Fullwidth Capital F
0xa3e7 0xa3c7 ;Fullwidth Small G -> Fullwidth Capital G
0xa3e8 0xa3c8 ;Fullwidth Small H -> Fullwidth Capital H
0xa3e9 0xa3c9 ;Fullwidth Small I -> Fullwidth Capital I
0xa3ea 0xa3ca ;Fullwidth Small J -> Fullwidth Capital J
0xa3eb 0xa3cb ;Fullwidth Small K -> Fullwidth Capital K
0xa3ec 0xa3cc ;Fullwidth Small L -> Fullwidth Capital L
0xa3ed 0xa3cd ;Fullwidth Small M -> Fullwidth Capital M
0xa3ee 0xa3ce ;Fullwidth Small N -> Fullwidth Capital N
0xa3ef 0xa3cf ;Fullwidth Small O -> Fullwidth Capital O
0xa3f0 0xa3d0 ;Fullwidth Small P -> Fullwidth Capital P
0xa3f1 0xa3d1 ;Fullwidth Small Q -> Fullwidth Capital Q
0xa3f2 0xa3d2 ;Fullwidth Small R -> Fullwidth Capital R
0xa3f3 0xa3d3 ;Fullwidth Small S -> Fullwidth Capital S
0xa3f4 0xa3d4 ;Fullwidth Small T -> Fullwidth Capital T
0xa3f5 0xa3d5 ;Fullwidth Small U -> Fullwidth Capital U
0xa3f6 0xa3d6 ;Fullwidth Small V -> Fullwidth Capital V
0xa3f7 0xa3d7 ;Fullwidth Small W -> Fullwidth Capital W
0xa3f8 0xa3d8 ;Fullwidth Small X -> Fullwidth Capital X
0xa3f9 0xa3d9 ;Fullwidth Small Y -> Fullwidth Capital Y
0xa3fa 0xa3da ;Fullwidth Small Z -> Fullwidth Capital Z
*** Code Page 950 ***
0xa2af ;Fullwidth Digit Zero
0xa2b0 ;Fullwidth Digit One
0xa2b1 ;Fullwidth Digit Two
0xa2b2 ;Fullwidth Digit Three
0xa2b3 ;Fullwidth Digit Four
0xa2b4 ;Fullwidth Digit Five
0xa2b5 ;Fullwidth Digit Six
0xa2b6 ;Fullwidth Digit Seven
0xa2b7 ;Fullwidth Digit Eight
0xa2b8 ;Fullwidth Digit Nine
0xa2e9 0xa2cf ;Fullwidth Small A -> Fullwidth Capital A
0xa2ea 0xa2d0 ;Fullwidth Small B -> Fullwidth Capital B
0xa2eb 0xa2d1 ;Fullwidth Small C -> Fullwidth Capital C
0xa2ec 0xa2d2 ;Fullwidth Small D -> Fullwidth Capital D
0xa2ed 0xa2d3 ;Fullwidth Small E -> Fullwidth Capital E
0xa2ee 0xa2d4 ;Fullwidth Small F -> Fullwidth Capital F
0xa2ef 0xa2d5 ;Fullwidth Small G -> Fullwidth Capital G
0xa2f0 0xa2d6 ;Fullwidth Small H -> Fullwidth Capital H
0xa2f1 0xa2d7 ;Fullwidth Small I -> Fullwidth Capital I
0xa2f2 0xa2d8 ;Fullwidth Small J -> Fullwidth Capital J
0xa2f3 0xa2d9 ;Fullwidth Small K -> Fullwidth Capital K
0xa2f4 0xa2da ;Fullwidth Small L -> Fullwidth Capital L
0xa2f5 0xa2db ;Fullwidth Small M -> Fullwidth Capital M
0xa2f6 0xa2dc ;Fullwidth Small N -> Fullwidth Capital N
0xa2f7 0xa2dd ;Fullwidth Small O -> Fullwidth Capital O
0xa2f8 0xa2de ;Fullwidth Small P -> Fullwidth Capital P
0xa2f9 0xa2df ;Fullwidth Small Q -> Fullwidth Capital Q
0xa2fa 0xa2e0 ;Fullwidth Small R -> Fullwidth Capital R
0xa2fb 0xa2e1 ;Fullwidth Small S -> Fullwidth Capital S
0xa2fc 0xa2e2 ;Fullwidth Small T -> Fullwidth Capital T
0xa2fd 0xa2e3 ;Fullwidth Small U -> Fullwidth Capital U
0xa2fe 0xa2e4 ;Fullwidth Small V -> Fullwidth Capital V
...Note break in sequence...
0xa340 0xa2e5 ;Fullwidth Small W -> Fullwidth Capital W
0xa341 0xa2e6 ;Fullwidth Small X -> Fullwidth Capital X
0xa342 0xa2e7 ;Fullwidth Small Y -> Fullwidth Capital Y
0xa343 0xa2e8 ;Fullwidth Small Z -> Fullwidth Capital Z
*** Code Page 1361 ***
Not yet available (05/17/94)
****************************************************************************/