177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner/* 277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * Copyright (c) 2007 2008 377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * Francois Dumont 477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * 577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * This material is provided "as is", with absolutely no warranty expressed 677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * or implied. Any use is at your own risk. 777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * 877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * Permission to use or copy this software for any purpose is hereby granted 977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * without fee, provided the above notices are retained on all copies. 1077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * Permission to modify the code and to distribute modified code is granted, 1177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * provided the above notices are retained, and a notice that the code was 1277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * modified is included with the above copyright notice. 1377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * 1477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner */ 1577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 1677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#if defined (_STLP_USE_SAFE_STRING_FUNCTIONS) 1777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner# define _STLP_WCSNCPY(D, DS, S, C) wcsncpy_s(D, DS, S, C) 1877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#else 1977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner# define _STLP_WCSNCPY(D, DS, S, C) wcsncpy(D, S, C) 2077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#endif 2177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 2277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerstatic const wchar_t* __wtrue_name = L"true"; 2377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerstatic const wchar_t* __wfalse_name = L"false"; 2477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 2577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnertypedef struct _Locale_codecvt { 2677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _Locale_lcid_t lc; 2777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner UINT cp; 2877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner unsigned char cleads[256 / CHAR_BIT]; 2977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner unsigned char max_char_size; 3077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner DWORD mbtowc_flags; 3177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner DWORD wctomb_flags; 3277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} _Locale_codecvt_t; 3377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 3477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner/* Ctype */ 3577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner_Locale_mask_t _WLocale_ctype(_Locale_ctype_t* ltype, wint_t c, 3677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _Locale_mask_t which_bits) { 3777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner wchar_t buf[2]; 3877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner WORD out[2]; 3977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner buf[0] = c; buf[1] = 0; 4077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner GetStringTypeW(CT_CTYPE1, buf, -1, out); 4177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _STLP_MARK_PARAMETER_AS_UNUSED(ltype) 4277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return (_Locale_mask_t)(MapCtypeMask(out[0]) & which_bits); 4377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 4477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 4577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerwint_t _WLocale_tolower(_Locale_ctype_t* ltype, wint_t c) { 4677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner wchar_t in_c = c; 4777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner wchar_t res; 4877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 4977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner LCMapStringW(ltype->lc.id, LCMAP_LOWERCASE, &in_c, 1, &res, 1); 5077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return res; 5177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 5277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 5377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerwint_t _WLocale_toupper(_Locale_ctype_t* ltype, wint_t c) { 5477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner wchar_t in_c = c; 5577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner wchar_t res; 5677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 5777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner LCMapStringW(ltype->lc.id, LCMAP_UPPERCASE, &in_c, 1, &res, 1); 5877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return res; 5977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 6077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 6177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner_Locale_codecvt_t* _Locale_codecvt_create(const char * name, _Locale_lcid_t* lc_hint, int *__err_code) { 6277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner char cp_name[MAX_CP_LEN + 1]; 6377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner unsigned char *ptr; 6477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner CPINFO CPInfo; 6577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner int i; 6677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 6777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _Locale_codecvt_t *lcodecvt = (_Locale_codecvt_t*)malloc(sizeof(_Locale_codecvt_t)); 6877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 6977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (!lcodecvt) { *__err_code = _STLP_LOC_NO_MEMORY; return lcodecvt; } 7077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner memset(lcodecvt, 0, sizeof(_Locale_codecvt_t)); 7177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 7277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (__GetLCIDFromName(name, &lcodecvt->lc.id, cp_name, lc_hint) == -1) 7377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner { free(lcodecvt); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; } 7477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 7577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner lcodecvt->cp = atoi(cp_name); 7677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (!GetCPInfo(lcodecvt->cp, &CPInfo)) { free(lcodecvt); return NULL; } 7777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 7877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (lcodecvt->cp != CP_UTF7 && lcodecvt->cp != CP_UTF8) { 7977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner lcodecvt->mbtowc_flags = MB_PRECOMPOSED; 8077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner lcodecvt->wctomb_flags = WC_COMPOSITECHECK | WC_SEPCHARS; 8177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 8277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner lcodecvt->max_char_size = CPInfo.MaxCharSize; 8377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 8477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (CPInfo.MaxCharSize > 1) { 8577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner for (ptr = (unsigned char*)CPInfo.LeadByte; *ptr && *(ptr + 1); ptr += 2) 8677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner for (i = *ptr; i <= *(ptr + 1); ++i) lcodecvt->cleads[i / CHAR_BIT] |= (0x01 << i % CHAR_BIT); 8777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 8877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 8977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return lcodecvt; 9077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 9177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 9277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerchar const* _Locale_codecvt_name(const _Locale_codecvt_t* lcodecvt, char* buf) { 9377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner char cp_buf[MAX_CP_LEN + 1]; 9477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner my_ltoa(lcodecvt->cp, cp_buf); 9577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return __GetLocaleName(lcodecvt->lc.id, cp_buf, buf); 9677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 9777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 9877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnervoid _Locale_codecvt_destroy(_Locale_codecvt_t* lcodecvt) { 9977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (!lcodecvt) return; 10077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 10177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner free(lcodecvt); 10277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 10377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 10477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerint _WLocale_mb_cur_max (_Locale_codecvt_t * lcodecvt) 10577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner{ return lcodecvt->max_char_size; } 10677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 10777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerint _WLocale_mb_cur_min (_Locale_codecvt_t *lcodecvt) { 10877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _STLP_MARK_PARAMETER_AS_UNUSED(lcodecvt) 10977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return 1; 11077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 11177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 11277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerint _WLocale_is_stateless (_Locale_codecvt_t * lcodecvt) 11377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner{ return (lcodecvt->max_char_size == 1) ? 1 : 0; } 11477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 11577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerstatic int __isleadbyte(int i, unsigned char *ctable) { 11677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner unsigned char c = (unsigned char)i; 11777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return (ctable[c / CHAR_BIT] & (0x01 << c % CHAR_BIT)); 11877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 11977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 12077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerstatic int __mbtowc(_Locale_codecvt_t *l, wchar_t *dst, const char *from, unsigned int count) { 12177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner int result; 12277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 12377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (l->cp == CP_UTF7 || l->cp == CP_UTF8) { 12477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner result = MultiByteToWideChar(l->cp, l->mbtowc_flags, from, count, dst, 1); 12577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (result == 0) { 12677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner switch (GetLastError()) { 12777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner case ERROR_NO_UNICODE_TRANSLATION: 12877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return -2; 12977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner default: 13077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return -1; 13177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 13277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 13377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 13477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner else { 13577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (count == 1 && __isleadbyte(*from, l->cleads)) return (size_t)-2; 13677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner result = MultiByteToWideChar(l->cp, l->mbtowc_flags, from, count, dst, 1); 13777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (result == 0) return -1; 13877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 13977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 14077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return result; 14177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 14277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 14377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnersize_t _WLocale_mbtowc(_Locale_codecvt_t *lcodecvt, wchar_t *to, 14477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner const char *from, size_t n, mbstate_t *shift_state) { 14577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner int result; 14677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _STLP_MARK_PARAMETER_AS_UNUSED(shift_state) 14777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (lcodecvt->max_char_size == 1) { /* Single byte encoding. */ 14877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner result = MultiByteToWideChar(lcodecvt->cp, lcodecvt->mbtowc_flags, from, 1, to, 1); 14977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (result == 0) return (size_t)-1; 15077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return result; 15177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 15277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner else { /* Multi byte encoding. */ 15377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner int retval; 15477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner unsigned int count = 1; 15577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner while (n--) { 15677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner retval = __mbtowc(lcodecvt, to, from, count); 15777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (retval == -2) 15877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner { if (++count > ((unsigned int)lcodecvt->max_char_size)) return (size_t)-1; } 15977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner else if (retval == -1) 16077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner { return (size_t)-1; } 16177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner else 16277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner { return count; } 16377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 16477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return (size_t)-2; 16577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 16677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 16777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 16877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnersize_t _WLocale_wctomb(_Locale_codecvt_t *lcodecvt, char *to, size_t n, 16977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner const wchar_t c, mbstate_t *shift_state) { 17077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner int size = WideCharToMultiByte(lcodecvt->cp, lcodecvt->wctomb_flags, &c, 1, NULL, 0, NULL, NULL); 17177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 17277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (!size) return (size_t)-1; 17377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if ((size_t)size > n) return (size_t)-2; 17477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 17577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (n > INT_MAX) 17677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner /* Limiting the output buf size to INT_MAX seems like reasonable to transform a single wchar_t. */ 17777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner n = INT_MAX; 17877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 17977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner WideCharToMultiByte(lcodecvt->cp, lcodecvt->wctomb_flags, &c, 1, to, (int)n, NULL, NULL); 18077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 18177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _STLP_MARK_PARAMETER_AS_UNUSED(shift_state) 18277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return (size_t)size; 18377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 18477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 18577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnersize_t _WLocale_unshift(_Locale_codecvt_t *lcodecvt, mbstate_t *st, 18677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner char *buf, size_t n, char **next) { 18777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner /* _WLocale_wctomb do not even touch to st, there is nothing to unshift in this localization implementation. */ 18877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _STLP_MARK_PARAMETER_AS_UNUSED(lcodecvt) 18977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _STLP_MARK_PARAMETER_AS_UNUSED(st) 19077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _STLP_MARK_PARAMETER_AS_UNUSED(&n) 19177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner *next = buf; 19277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return 0; 19377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 19477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 19577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner/* Collate */ 19677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner/* This function takes care of the potential size_t DWORD different size. */ 19777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerstatic int _WLocale_strcmp_aux(_Locale_collate_t* lcol, 19877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner const wchar_t* s1, size_t n1, 19977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner const wchar_t* s2, size_t n2) { 20077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner int result = CSTR_EQUAL; 20177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner while (n1 > 0 || n2 > 0) { 20277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner DWORD size1 = trim_size_t_to_DWORD(n1); 20377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner DWORD size2 = trim_size_t_to_DWORD(n2); 20477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner result = CompareStringW(lcol->lc.id, 0, s1, size1, s2, size2); 20577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (result != CSTR_EQUAL) 20677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner break; 20777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner n1 -= size1; 20877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner n2 -= size2; 20977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 21077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return result; 21177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 21277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 21377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerint _WLocale_strcmp(_Locale_collate_t* lcol, 21477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner const wchar_t* s1, size_t n1, 21577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner const wchar_t* s2, size_t n2) { 21677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner int result; 21777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner result = _WLocale_strcmp_aux(lcol, s1, n1, s2, n2); 21877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return (result == CSTR_EQUAL) ? 0 : (result == CSTR_LESS_THAN) ? -1 : 1; 21977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 22077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 22177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnersize_t _WLocale_strxfrm(_Locale_collate_t* lcol, 22277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner wchar_t* dst, size_t dst_size, 22377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner const wchar_t* src, size_t src_size) { 22477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner int result, i; 22577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 22677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner /* see _Locale_strxfrm: */ 22777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (src_size > INT_MAX) { 22877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (dst != 0) { 22977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _STLP_WCSNCPY(dst, dst_size, src, src_size); 23077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 23177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return src_size; 23277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 23377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (dst_size > INT_MAX) { 23477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner dst_size = INT_MAX; 23577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 23677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner result = LCMapStringW(lcol->lc.id, LCMAP_SORTKEY, src, (int)src_size, dst, (int)dst_size); 23777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (result != 0 && dst != 0) { 23877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner for (i = result - 1; i >= 0; --i) { 23977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner dst[i] = ((unsigned char*)dst)[i]; 24077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 24177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 24277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return result != 0 ? result - 1 : 0; 24377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 24477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 24577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner/* Numeric */ 24677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerwchar_t _WLocale_decimal_point(_Locale_numeric_t* lnum) { 24777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner wchar_t buf[4]; 24877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner GetLocaleInfoW(lnum->lc.id, LOCALE_SDECIMAL, buf, 4); 24977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return buf[0]; 25077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 25177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 25277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerwchar_t _WLocale_thousands_sep(_Locale_numeric_t* lnum) { 25377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner wchar_t buf[4]; 25477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner GetLocaleInfoW(lnum->lc.id, LOCALE_STHOUSAND, buf, 4); 25577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return buf[0]; 25677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 25777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 25877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerconst wchar_t * _WLocale_true(_Locale_numeric_t* lnum, wchar_t* buf, size_t bufSize) { 25977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _STLP_MARK_PARAMETER_AS_UNUSED(lnum) 26077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _STLP_MARK_PARAMETER_AS_UNUSED(buf) 26177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _STLP_MARK_PARAMETER_AS_UNUSED(&bufSize) 26277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return __wtrue_name; 26377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 26477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 26577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerconst wchar_t * _WLocale_false(_Locale_numeric_t* lnum, wchar_t* buf, size_t bufSize) { 26677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _STLP_MARK_PARAMETER_AS_UNUSED(lnum) 26777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _STLP_MARK_PARAMETER_AS_UNUSED(buf) 26877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _STLP_MARK_PARAMETER_AS_UNUSED(&bufSize) 26977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return __wfalse_name; 27077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 27177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 27277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner/* Monetary */ 27377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerconst wchar_t* _WLocale_int_curr_symbol(_Locale_monetary_t * lmon, wchar_t* buf, size_t bufSize) 27477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner{ GetLocaleInfoW(lmon->lc.id, LOCALE_SINTLSYMBOL, buf, (int)bufSize); return buf; } 27577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 27677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerconst wchar_t* _WLocale_currency_symbol(_Locale_monetary_t * lmon, wchar_t* buf, size_t bufSize) 27777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner{ GetLocaleInfoW(lmon->lc.id, LOCALE_SCURRENCY, buf, (int)bufSize); return buf; } 27877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 27977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerwchar_t _WLocale_mon_decimal_point(_Locale_monetary_t * lmon) 28077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner{ return lmon->decimal_point[0]; } 28177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 28277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerwchar_t _WLocale_mon_thousands_sep(_Locale_monetary_t * lmon) 28377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner{ return lmon->thousands_sep[0]; } 28477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 28577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerconst wchar_t* _WLocale_positive_sign(_Locale_monetary_t * lmon, wchar_t* buf, size_t bufSize) 28677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner{ GetLocaleInfoW(lmon->lc.id, LOCALE_SPOSITIVESIGN, buf, (int)bufSize); return buf; } 28777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 28877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerconst wchar_t* _WLocale_negative_sign(_Locale_monetary_t * lmon, wchar_t* buf, size_t bufSize) 28977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner{ GetLocaleInfoW(lmon->lc.id, LOCALE_SNEGATIVESIGN, buf, (int)bufSize); return buf; } 29077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 29177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner/* Time */ 29277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerconst wchar_t * _WLocale_full_monthname(_Locale_time_t * ltime, int month, 29377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner wchar_t* buf, size_t bufSize) 29477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner{ GetLocaleInfoW(ltime->lc.id, LOCALE_SMONTHNAME1 + month, buf, (int)bufSize); return buf; } 29577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 29677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerconst wchar_t * _WLocale_abbrev_monthname(_Locale_time_t * ltime, int month, 29777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner wchar_t* buf, size_t bufSize) 29877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner{ GetLocaleInfoW(ltime->lc.id, LOCALE_SABBREVMONTHNAME1 + month, buf, (int)bufSize); return buf; } 29977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 30077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerconst wchar_t * _WLocale_full_dayofweek(_Locale_time_t * ltime, int day, 30177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner wchar_t* buf, size_t bufSize) 30277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner{ GetLocaleInfoW(ltime->lc.id, LOCALE_SDAYNAME1 + day, buf, (int)bufSize); return buf; } 30377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 30477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerconst wchar_t * _WLocale_abbrev_dayofweek(_Locale_time_t * ltime, int day, 30577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner wchar_t* buf, size_t bufSize) 30677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner{ GetLocaleInfoW(ltime->lc.id, LOCALE_SABBREVDAYNAME1 + day, buf, (int)bufSize); return buf; } 30777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 30877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerconst wchar_t* _WLocale_am_str(_Locale_time_t* ltime, 30977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner wchar_t* buf, size_t bufSize) 31077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner{ GetLocaleInfoW(ltime->lc.id, LOCALE_S1159, buf, (int)bufSize); return buf; } 31177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 31277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerconst wchar_t* _WLocale_pm_str(_Locale_time_t* ltime, 31377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner wchar_t* buf, size_t bufSize) 31477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner{ GetLocaleInfoW(ltime->lc.id, LOCALE_S2359, buf, (int)bufSize); return buf; } 315