Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenc_wlocale_win32.c
Go to the documentation of this file.
00001 /* 00002 * Copyright (c) 2007 2008 00003 * Francois Dumont 00004 * 00005 * This material is provided "as is", with absolutely no warranty expressed 00006 * or implied. Any use is at your own risk. 00007 * 00008 * Permission to use or copy this software for any purpose is hereby granted 00009 * without fee, provided the above notices are retained on all copies. 00010 * Permission to modify the code and to distribute modified code is granted, 00011 * provided the above notices are retained, and a notice that the code was 00012 * modified is included with the above copyright notice. 00013 * 00014 */ 00015 00016 #if defined (_STLP_USE_SAFE_STRING_FUNCTIONS) 00017 # define _STLP_WCSNCPY(D, DS, S, C) wcsncpy_s(D, DS, S, C) 00018 #else 00019 # define _STLP_WCSNCPY(D, DS, S, C) wcsncpy(D, S, C) 00020 #endif 00021 00022 static const wchar_t* __wtrue_name = L"true"; 00023 static const wchar_t* __wfalse_name = L"false"; 00024 00025 typedef struct _Locale_codecvt { 00026 _Locale_lcid_t lc; 00027 UINT cp; 00028 unsigned char cleads[256 / CHAR_BIT]; 00029 unsigned char max_char_size; 00030 DWORD mbtowc_flags; 00031 DWORD wctomb_flags; 00032 } _Locale_codecvt_t; 00033 00034 /* Ctype */ 00035 _Locale_mask_t _WLocale_ctype(_Locale_ctype_t* ltype, wint_t c, 00036 _Locale_mask_t which_bits) { 00037 wchar_t buf[2]; 00038 WORD out[2]; 00039 buf[0] = c; buf[1] = 0; 00040 GetStringTypeW(CT_CTYPE1, buf, -1, out); 00041 _STLP_MARK_PARAMETER_AS_UNUSED(ltype) 00042 return (_Locale_mask_t)(MapCtypeMask(out[0]) & which_bits); 00043 } 00044 00045 wint_t _WLocale_tolower(_Locale_ctype_t* ltype, wint_t c) { 00046 wchar_t in_c = c; 00047 wchar_t res; 00048 00049 LCMapStringW(ltype->lc.id, LCMAP_LOWERCASE, &in_c, 1, &res, 1); 00050 return res; 00051 } 00052 00053 wint_t _WLocale_toupper(_Locale_ctype_t* ltype, wint_t c) { 00054 wchar_t in_c = c; 00055 wchar_t res; 00056 00057 LCMapStringW(ltype->lc.id, LCMAP_UPPERCASE, &in_c, 1, &res, 1); 00058 return res; 00059 } 00060 00061 _Locale_codecvt_t* _Locale_codecvt_create(const char * name, _Locale_lcid_t* lc_hint, int *__err_code) { 00062 char cp_name[MAX_CP_LEN + 1]; 00063 unsigned char *ptr; 00064 CPINFO CPInfo; 00065 int i; 00066 00067 _Locale_codecvt_t *lcodecvt = (_Locale_codecvt_t*)malloc(sizeof(_Locale_codecvt_t)); 00068 00069 if (!lcodecvt) { *__err_code = _STLP_LOC_NO_MEMORY; return lcodecvt; } 00070 memset(lcodecvt, 0, sizeof(_Locale_codecvt_t)); 00071 00072 if (__GetLCIDFromName(name, &lcodecvt->lc.id, cp_name, lc_hint) == -1) 00073 { free(lcodecvt); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; } 00074 00075 lcodecvt->cp = atoi(cp_name); 00076 if (!GetCPInfo(lcodecvt->cp, &CPInfo)) { free(lcodecvt); return NULL; } 00077 00078 if (lcodecvt->cp != CP_UTF7 && lcodecvt->cp != CP_UTF8) { 00079 lcodecvt->mbtowc_flags = MB_PRECOMPOSED; 00080 lcodecvt->wctomb_flags = WC_COMPOSITECHECK | WC_SEPCHARS; 00081 } 00082 lcodecvt->max_char_size = CPInfo.MaxCharSize; 00083 00084 if (CPInfo.MaxCharSize > 1) { 00085 for (ptr = (unsigned char*)CPInfo.LeadByte; *ptr && *(ptr + 1); ptr += 2) 00086 for (i = *ptr; i <= *(ptr + 1); ++i) lcodecvt->cleads[i / CHAR_BIT] |= (0x01 << i % CHAR_BIT); 00087 } 00088 00089 return lcodecvt; 00090 } 00091 00092 char const* _Locale_codecvt_name(const _Locale_codecvt_t* lcodecvt, char* buf) { 00093 char cp_buf[MAX_CP_LEN + 1]; 00094 my_ltoa(lcodecvt->cp, cp_buf); 00095 return __GetLocaleName(lcodecvt->lc.id, cp_buf, buf); 00096 } 00097 00098 void _Locale_codecvt_destroy(_Locale_codecvt_t* lcodecvt) { 00099 if (!lcodecvt) return; 00100 00101 free(lcodecvt); 00102 } 00103 00104 int _WLocale_mb_cur_max (_Locale_codecvt_t * lcodecvt) 00105 { return lcodecvt->max_char_size; } 00106 00107 int _WLocale_mb_cur_min (_Locale_codecvt_t *lcodecvt) { 00108 _STLP_MARK_PARAMETER_AS_UNUSED(lcodecvt) 00109 return 1; 00110 } 00111 00112 int _WLocale_is_stateless (_Locale_codecvt_t * lcodecvt) 00113 { return (lcodecvt->max_char_size == 1) ? 1 : 0; } 00114 00115 static int __isleadbyte(int i, unsigned char *ctable) { 00116 unsigned char c = (unsigned char)i; 00117 return (ctable[c / CHAR_BIT] & (0x01 << c % CHAR_BIT)); 00118 } 00119 00120 static int __mbtowc(_Locale_codecvt_t *l, wchar_t *dst, const char *from, unsigned int count) { 00121 int result; 00122 00123 if (l->cp == CP_UTF7 || l->cp == CP_UTF8) { 00124 result = MultiByteToWideChar(l->cp, l->mbtowc_flags, from, count, dst, 1); 00125 if (result == 0) { 00126 switch (GetLastError()) { 00127 case ERROR_NO_UNICODE_TRANSLATION: 00128 return -2; 00129 default: 00130 return -1; 00131 } 00132 } 00133 } 00134 else { 00135 if (count == 1 && __isleadbyte(*from, l->cleads)) return (size_t)-2; 00136 result = MultiByteToWideChar(l->cp, l->mbtowc_flags, from, count, dst, 1); 00137 if (result == 0) return -1; 00138 } 00139 00140 return result; 00141 } 00142 00143 size_t _WLocale_mbtowc(_Locale_codecvt_t *lcodecvt, wchar_t *to, 00144 const char *from, size_t n, mbstate_t *shift_state) { 00145 int result; 00146 _STLP_MARK_PARAMETER_AS_UNUSED(shift_state) 00147 if (lcodecvt->max_char_size == 1) { /* Single byte encoding. */ 00148 result = MultiByteToWideChar(lcodecvt->cp, lcodecvt->mbtowc_flags, from, 1, to, 1); 00149 if (result == 0) return (size_t)-1; 00150 return result; 00151 } 00152 else { /* Multi byte encoding. */ 00153 int retval; 00154 unsigned int count = 1; 00155 while (n--) { 00156 retval = __mbtowc(lcodecvt, to, from, count); 00157 if (retval == -2) 00158 { if (++count > ((unsigned int)lcodecvt->max_char_size)) return (size_t)-1; } 00159 else if (retval == -1) 00160 { return (size_t)-1; } 00161 else 00162 { return count; } 00163 } 00164 return (size_t)-2; 00165 } 00166 } 00167 00168 size_t _WLocale_wctomb(_Locale_codecvt_t *lcodecvt, char *to, size_t n, 00169 const wchar_t c, mbstate_t *shift_state) { 00170 int size = WideCharToMultiByte(lcodecvt->cp, lcodecvt->wctomb_flags, &c, 1, NULL, 0, NULL, NULL); 00171 00172 if (!size) return (size_t)-1; 00173 if ((size_t)size > n) return (size_t)-2; 00174 00175 if (n > INT_MAX) 00176 /* Limiting the output buf size to INT_MAX seems like reasonable to transform a single wchar_t. */ 00177 n = INT_MAX; 00178 00179 WideCharToMultiByte(lcodecvt->cp, lcodecvt->wctomb_flags, &c, 1, to, (int)n, NULL, NULL); 00180 00181 _STLP_MARK_PARAMETER_AS_UNUSED(shift_state) 00182 return (size_t)size; 00183 } 00184 00185 size_t _WLocale_unshift(_Locale_codecvt_t *lcodecvt, mbstate_t *st, 00186 char *buf, size_t n, char **next) { 00187 /* _WLocale_wctomb do not even touch to st, there is nothing to unshift in this localization implementation. */ 00188 _STLP_MARK_PARAMETER_AS_UNUSED(lcodecvt) 00189 _STLP_MARK_PARAMETER_AS_UNUSED(st) 00190 _STLP_MARK_PARAMETER_AS_UNUSED(&n) 00191 *next = buf; 00192 return 0; 00193 } 00194 00195 /* Collate */ 00196 /* This function takes care of the potential size_t DWORD different size. */ 00197 static int _WLocale_strcmp_aux(_Locale_collate_t* lcol, 00198 const wchar_t* s1, size_t n1, 00199 const wchar_t* s2, size_t n2) { 00200 int result = CSTR_EQUAL; 00201 while (n1 > 0 || n2 > 0) { 00202 DWORD size1 = trim_size_t_to_DWORD(n1); 00203 DWORD size2 = trim_size_t_to_DWORD(n2); 00204 result = CompareStringW(lcol->lc.id, 0, s1, size1, s2, size2); 00205 if (result != CSTR_EQUAL) 00206 break; 00207 n1 -= size1; 00208 n2 -= size2; 00209 } 00210 return result; 00211 } 00212 00213 int _WLocale_strcmp(_Locale_collate_t* lcol, 00214 const wchar_t* s1, size_t n1, 00215 const wchar_t* s2, size_t n2) { 00216 int result; 00217 result = _WLocale_strcmp_aux(lcol, s1, n1, s2, n2); 00218 return (result == CSTR_EQUAL) ? 0 : (result == CSTR_LESS_THAN) ? -1 : 1; 00219 } 00220 00221 size_t _WLocale_strxfrm(_Locale_collate_t* lcol, 00222 wchar_t* dst, size_t dst_size, 00223 const wchar_t* src, size_t src_size) { 00224 int result, i; 00225 00226 /* see _Locale_strxfrm: */ 00227 if (src_size > INT_MAX) { 00228 if (dst != 0) { 00229 _STLP_WCSNCPY(dst, dst_size, src, src_size); 00230 } 00231 return src_size; 00232 } 00233 if (dst_size > INT_MAX) { 00234 dst_size = INT_MAX; 00235 } 00236 result = LCMapStringW(lcol->lc.id, LCMAP_SORTKEY, src, (int)src_size, dst, (int)dst_size); 00237 if (result != 0 && dst != 0) { 00238 for (i = result - 1; i >= 0; --i) { 00239 dst[i] = ((unsigned char*)dst)[i]; 00240 } 00241 } 00242 return result != 0 ? result - 1 : 0; 00243 } 00244 00245 /* Numeric */ 00246 wchar_t _WLocale_decimal_point(_Locale_numeric_t* lnum) { 00247 wchar_t buf[4]; 00248 GetLocaleInfoW(lnum->lc.id, LOCALE_SDECIMAL, buf, 4); 00249 return buf[0]; 00250 } 00251 00252 wchar_t _WLocale_thousands_sep(_Locale_numeric_t* lnum) { 00253 wchar_t buf[4]; 00254 GetLocaleInfoW(lnum->lc.id, LOCALE_STHOUSAND, buf, 4); 00255 return buf[0]; 00256 } 00257 00258 const wchar_t * _WLocale_true(_Locale_numeric_t* lnum, wchar_t* buf, size_t bufSize) { 00259 _STLP_MARK_PARAMETER_AS_UNUSED(lnum) 00260 _STLP_MARK_PARAMETER_AS_UNUSED(buf) 00261 _STLP_MARK_PARAMETER_AS_UNUSED(&bufSize) 00262 return __wtrue_name; 00263 } 00264 00265 const wchar_t * _WLocale_false(_Locale_numeric_t* lnum, wchar_t* buf, size_t bufSize) { 00266 _STLP_MARK_PARAMETER_AS_UNUSED(lnum) 00267 _STLP_MARK_PARAMETER_AS_UNUSED(buf) 00268 _STLP_MARK_PARAMETER_AS_UNUSED(&bufSize) 00269 return __wfalse_name; 00270 } 00271 00272 /* Monetary */ 00273 const wchar_t* _WLocale_int_curr_symbol(_Locale_monetary_t * lmon, wchar_t* buf, size_t bufSize) 00274 { GetLocaleInfoW(lmon->lc.id, LOCALE_SINTLSYMBOL, buf, (int)bufSize); return buf; } 00275 00276 const wchar_t* _WLocale_currency_symbol(_Locale_monetary_t * lmon, wchar_t* buf, size_t bufSize) 00277 { GetLocaleInfoW(lmon->lc.id, LOCALE_SCURRENCY, buf, (int)bufSize); return buf; } 00278 00279 wchar_t _WLocale_mon_decimal_point(_Locale_monetary_t * lmon) 00280 { return lmon->decimal_point[0]; } 00281 00282 wchar_t _WLocale_mon_thousands_sep(_Locale_monetary_t * lmon) 00283 { return lmon->thousands_sep[0]; } 00284 00285 const wchar_t* _WLocale_positive_sign(_Locale_monetary_t * lmon, wchar_t* buf, size_t bufSize) 00286 { GetLocaleInfoW(lmon->lc.id, LOCALE_SPOSITIVESIGN, buf, (int)bufSize); return buf; } 00287 00288 const wchar_t* _WLocale_negative_sign(_Locale_monetary_t * lmon, wchar_t* buf, size_t bufSize) 00289 { GetLocaleInfoW(lmon->lc.id, LOCALE_SNEGATIVESIGN, buf, (int)bufSize); return buf; } 00290 00291 /* Time */ 00292 const wchar_t * _WLocale_full_monthname(_Locale_time_t * ltime, int month, 00293 wchar_t* buf, size_t bufSize) 00294 { GetLocaleInfoW(ltime->lc.id, LOCALE_SMONTHNAME1 + month, buf, (int)bufSize); return buf; } 00295 00296 const wchar_t * _WLocale_abbrev_monthname(_Locale_time_t * ltime, int month, 00297 wchar_t* buf, size_t bufSize) 00298 { GetLocaleInfoW(ltime->lc.id, LOCALE_SABBREVMONTHNAME1 + month, buf, (int)bufSize); return buf; } 00299 00300 const wchar_t * _WLocale_full_dayofweek(_Locale_time_t * ltime, int day, 00301 wchar_t* buf, size_t bufSize) 00302 { GetLocaleInfoW(ltime->lc.id, LOCALE_SDAYNAME1 + day, buf, (int)bufSize); return buf; } 00303 00304 const wchar_t * _WLocale_abbrev_dayofweek(_Locale_time_t * ltime, int day, 00305 wchar_t* buf, size_t bufSize) 00306 { GetLocaleInfoW(ltime->lc.id, LOCALE_SABBREVDAYNAME1 + day, buf, (int)bufSize); return buf; } 00307 00308 const wchar_t* _WLocale_am_str(_Locale_time_t* ltime, 00309 wchar_t* buf, size_t bufSize) 00310 { GetLocaleInfoW(ltime->lc.id, LOCALE_S1159, buf, (int)bufSize); return buf; } 00311 00312 const wchar_t* _WLocale_pm_str(_Locale_time_t* ltime, 00313 wchar_t* buf, size_t bufSize) 00314 { GetLocaleInfoW(ltime->lc.id, LOCALE_S2359, buf, (int)bufSize); return buf; } Generated on Mon May 28 2012 04:34:57 for ReactOS by
1.7.6.1
|