ReactOS 0.4.16-dev-340-g0540c21
c_wlocale_win32.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2007 2008
3 * Francois Dumont
4 *
5 * This material is provided "as is", with absolutely no warranty expressed
6 * or implied. Any use is at your own risk.
7 *
8 * Permission to use or copy this software for any purpose is hereby granted
9 * without fee, provided the above notices are retained on all copies.
10 * Permission to modify the code and to distribute modified code is granted,
11 * provided the above notices are retained, and a notice that the code was
12 * modified is included with the above copyright notice.
13 *
14 */
15
16#if defined (_STLP_USE_SAFE_STRING_FUNCTIONS)
17# define _STLP_WCSNCPY(D, DS, S, C) wcsncpy_s(D, DS, S, C)
18#else
19# define _STLP_WCSNCPY(D, DS, S, C) wcsncpy(D, S, C)
20#endif
21
22static const wchar_t* __wtrue_name = L"true";
23static const wchar_t* __wfalse_name = L"false";
24
25typedef struct _Locale_codecvt {
28 unsigned char cleads[256 / CHAR_BIT];
29 unsigned char max_char_size;
33
34/* Ctype */
36 _Locale_mask_t which_bits) {
37 wchar_t buf[2];
38 WORD out[2];
39 buf[0] = c; buf[1] = 0;
42 return (_Locale_mask_t)(MapCtypeMask(out[0]) & which_bits);
43}
44
46 wchar_t in_c = c;
47 wchar_t res;
48
49 LCMapStringW(ltype->lc.id, LCMAP_LOWERCASE, &in_c, 1, &res, 1);
50 return res;
51}
52
54 wchar_t in_c = c;
55 wchar_t res;
56
57 LCMapStringW(ltype->lc.id, LCMAP_UPPERCASE, &in_c, 1, &res, 1);
58 return res;
59}
60
61_Locale_codecvt_t* _Locale_codecvt_create(const char * name, _Locale_lcid_t* lc_hint, int *__err_code) {
62 char cp_name[MAX_CP_LEN + 1];
63 unsigned char *ptr;
64 CPINFO CPInfo;
65 int i;
66
68
69 if (!lcodecvt) { *__err_code = _STLP_LOC_NO_MEMORY; return lcodecvt; }
70 memset(lcodecvt, 0, sizeof(_Locale_codecvt_t));
71
72 if (__GetLCIDFromName(name, &lcodecvt->lc.id, cp_name, lc_hint) == -1)
73 { free(lcodecvt); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; }
74
75 lcodecvt->cp = atoi(cp_name);
76 if (!GetCPInfo(lcodecvt->cp, &CPInfo)) { free(lcodecvt); return NULL; }
77
78 if (lcodecvt->cp != CP_UTF7 && lcodecvt->cp != CP_UTF8) {
79 lcodecvt->mbtowc_flags = MB_PRECOMPOSED;
81 }
82 lcodecvt->max_char_size = CPInfo.MaxCharSize;
83
84 if (CPInfo.MaxCharSize > 1) {
85 for (ptr = (unsigned char*)CPInfo.LeadByte; *ptr && *(ptr + 1); ptr += 2)
86 for (i = *ptr; i <= *(ptr + 1); ++i) lcodecvt->cleads[i / CHAR_BIT] |= (0x01 << i % CHAR_BIT);
87 }
88
89 return lcodecvt;
90}
91
92char const* _Locale_codecvt_name(const _Locale_codecvt_t* lcodecvt, char* buf) {
93 char cp_buf[MAX_CP_LEN + 1];
94 my_ltoa(lcodecvt->cp, cp_buf);
95 return __GetLocaleName(lcodecvt->lc.id, cp_buf, buf);
96}
97
99 if (!lcodecvt) return;
100
101 free(lcodecvt);
102}
103
105{ return lcodecvt->max_char_size; }
106
109 return 1;
110}
111
113{ return (lcodecvt->max_char_size == 1) ? 1 : 0; }
114
115static int __isleadbyte(int i, unsigned char *ctable) {
116 unsigned char c = (unsigned char)i;
117 return (ctable[c / CHAR_BIT] & (0x01 << c % CHAR_BIT));
118}
119
120static int __mbtowc(_Locale_codecvt_t *l, wchar_t *dst, const char *from, unsigned int count) {
121 int result;
122
123 if (l->cp == CP_UTF7 || l->cp == CP_UTF8) {
124 result = MultiByteToWideChar(l->cp, l->mbtowc_flags, from, count, dst, 1);
125 if (result == 0) {
126 switch (GetLastError()) {
128 return -2;
129 default:
130 return -1;
131 }
132 }
133 }
134 else {
135 if (count == 1 && __isleadbyte(*from, l->cleads)) return (size_t)-2;
136 result = MultiByteToWideChar(l->cp, l->mbtowc_flags, from, count, dst, 1);
137 if (result == 0) return -1;
138 }
139
140 return result;
141}
142
143size_t _WLocale_mbtowc(_Locale_codecvt_t *lcodecvt, wchar_t *to,
144 const char *from, size_t n, mbstate_t *shift_state) {
145 int result;
147 if (lcodecvt->max_char_size == 1) { /* Single byte encoding. */
148 result = MultiByteToWideChar(lcodecvt->cp, lcodecvt->mbtowc_flags, from, 1, to, 1);
149 if (result == 0) return (size_t)-1;
150 return result;
151 }
152 else { /* Multi byte encoding. */
153 int retval;
154 unsigned int count = 1;
155 while (n--) {
156 retval = __mbtowc(lcodecvt, to, from, count);
157 if (retval == -2)
158 { if (++count > ((unsigned int)lcodecvt->max_char_size)) return (size_t)-1; }
159 else if (retval == -1)
160 { return (size_t)-1; }
161 else
162 { return count; }
163 }
164 return (size_t)-2;
165 }
166}
167
168size_t _WLocale_wctomb(_Locale_codecvt_t *lcodecvt, char *to, size_t n,
169 const wchar_t c, mbstate_t *shift_state) {
170 int size = WideCharToMultiByte(lcodecvt->cp, lcodecvt->wctomb_flags, &c, 1, NULL, 0, NULL, NULL);
171
172 if (!size) return (size_t)-1;
173 if ((size_t)size > n) return (size_t)-2;
174
175 if (n > INT_MAX)
176 /* Limiting the output buf size to INT_MAX seems like reasonable to transform a single wchar_t. */
177 n = INT_MAX;
178
179 WideCharToMultiByte(lcodecvt->cp, lcodecvt->wctomb_flags, &c, 1, to, (int)n, NULL, NULL);
180
182 return (size_t)size;
183}
184
186 char *buf, size_t n, char **next) {
187 /* _WLocale_wctomb do not even touch to st, there is nothing to unshift in this localization implementation. */
191 *next = buf;
192 return 0;
193}
194
195/* Collate */
196/* This function takes care of the potential size_t DWORD different size. */
198 const wchar_t* s1, size_t n1,
199 const wchar_t* s2, size_t n2) {
200 int result = CSTR_EQUAL;
201 while (n1 > 0 || n2 > 0) {
204 result = CompareStringW(lcol->lc.id, 0, s1, size1, s2, size2);
205 if (result != CSTR_EQUAL)
206 break;
207 n1 -= size1;
208 n2 -= size2;
209 }
210 return result;
211}
212
214 const wchar_t* s1, size_t n1,
215 const wchar_t* s2, size_t n2) {
216 int result;
217 result = _WLocale_strcmp_aux(lcol, s1, n1, s2, n2);
218 return (result == CSTR_EQUAL) ? 0 : (result == CSTR_LESS_THAN) ? -1 : 1;
219}
220
222 wchar_t* dst, size_t dst_size,
223 const wchar_t* src, size_t src_size) {
224 int result, i;
225
226 /* see _Locale_strxfrm: */
227 if (src_size > INT_MAX) {
228 if (dst != 0) {
229 _STLP_WCSNCPY(dst, dst_size, src, src_size);
230 }
231 return src_size;
232 }
233 if (dst_size > INT_MAX) {
234 dst_size = INT_MAX;
235 }
236 result = LCMapStringW(lcol->lc.id, LCMAP_SORTKEY, src, (int)src_size, dst, (int)dst_size);
237 if (result != 0 && dst != 0) {
238 for (i = result - 1; i >= 0; --i) {
239 dst[i] = ((unsigned char*)dst)[i];
240 }
241 }
242 return result != 0 ? result - 1 : 0;
243}
244
245/* Numeric */
247 wchar_t buf[4];
249 return buf[0];
250}
251
253 wchar_t buf[4];
255 return buf[0];
256}
257
258const wchar_t * _WLocale_true(_Locale_numeric_t* lnum, wchar_t* buf, size_t bufSize) {
262 return __wtrue_name;
263}
264
265const wchar_t * _WLocale_false(_Locale_numeric_t* lnum, wchar_t* buf, size_t bufSize) {
269 return __wfalse_name;
270}
271
272/* Monetary */
273const wchar_t* _WLocale_int_curr_symbol(_Locale_monetary_t * lmon, wchar_t* buf, size_t bufSize)
274{ GetLocaleInfoW(lmon->lc.id, LOCALE_SINTLSYMBOL, buf, (int)bufSize); return buf; }
275
276const wchar_t* _WLocale_currency_symbol(_Locale_monetary_t * lmon, wchar_t* buf, size_t bufSize)
277{ GetLocaleInfoW(lmon->lc.id, LOCALE_SCURRENCY, buf, (int)bufSize); return buf; }
278
280{ return lmon->decimal_point[0]; }
281
283{ return lmon->thousands_sep[0]; }
284
285const wchar_t* _WLocale_positive_sign(_Locale_monetary_t * lmon, wchar_t* buf, size_t bufSize)
286{ GetLocaleInfoW(lmon->lc.id, LOCALE_SPOSITIVESIGN, buf, (int)bufSize); return buf; }
287
288const wchar_t* _WLocale_negative_sign(_Locale_monetary_t * lmon, wchar_t* buf, size_t bufSize)
289{ GetLocaleInfoW(lmon->lc.id, LOCALE_SNEGATIVESIGN, buf, (int)bufSize); return buf; }
290
291/* Time */
292const wchar_t * _WLocale_full_monthname(_Locale_time_t * ltime, int month,
293 wchar_t* buf, size_t bufSize)
294{ GetLocaleInfoW(ltime->lc.id, LOCALE_SMONTHNAME1 + month, buf, (int)bufSize); return buf; }
295
296const wchar_t * _WLocale_abbrev_monthname(_Locale_time_t * ltime, int month,
297 wchar_t* buf, size_t bufSize)
298{ GetLocaleInfoW(ltime->lc.id, LOCALE_SABBREVMONTHNAME1 + month, buf, (int)bufSize); return buf; }
299
300const wchar_t * _WLocale_full_dayofweek(_Locale_time_t * ltime, int day,
301 wchar_t* buf, size_t bufSize)
302{ GetLocaleInfoW(ltime->lc.id, LOCALE_SDAYNAME1 + day, buf, (int)bufSize); return buf; }
303
304const wchar_t * _WLocale_abbrev_dayofweek(_Locale_time_t * ltime, int day,
305 wchar_t* buf, size_t bufSize)
306{ GetLocaleInfoW(ltime->lc.id, LOCALE_SABBREVDAYNAME1 + day, buf, (int)bufSize); return buf; }
307
308const wchar_t* _WLocale_am_str(_Locale_time_t* ltime,
309 wchar_t* buf, size_t bufSize)
310{ GetLocaleInfoW(ltime->lc.id, LOCALE_S1159, buf, (int)bufSize); return buf; }
311
312const wchar_t* _WLocale_pm_str(_Locale_time_t* ltime,
313 wchar_t* buf, size_t bufSize)
314{ GetLocaleInfoW(ltime->lc.id, LOCALE_S2359, buf, (int)bufSize); return buf; }
int wint_t
Definition: _apple.h:38
#define _STLP_MARK_PARAMETER_AS_UNUSED(X)
Definition: _dm.h:68
r l[0]
Definition: byte_order.h:168
static _Locale_mask_t ctable[256]
static void my_ltoa(long __x, char *buf)
unsigned short MapCtypeMask(unsigned short mask)
static DWORD trim_size_t_to_DWORD(size_t n)
#define MAX_CP_LEN
static int __GetLCIDFromName(const char *lname, LCID *lcid, char *cp, _Locale_lcid_t *hint)
static char const * __GetLocaleName(LCID lcid, const char *cp, char *buf)
struct _Locale_codecvt _Locale_codecvt_t
static int __mbtowc(_Locale_codecvt_t *l, wchar_t *dst, const char *from, unsigned int count)
wchar_t _WLocale_decimal_point(_Locale_numeric_t *lnum)
const wchar_t * _WLocale_negative_sign(_Locale_monetary_t *lmon, wchar_t *buf, size_t bufSize)
static int __isleadbyte(int i, unsigned char *ctable)
#define _STLP_WCSNCPY(D, DS, S, C)
size_t _WLocale_mbtowc(_Locale_codecvt_t *lcodecvt, wchar_t *to, const char *from, size_t n, mbstate_t *shift_state)
const wchar_t * _WLocale_positive_sign(_Locale_monetary_t *lmon, wchar_t *buf, size_t bufSize)
int _WLocale_mb_cur_min(_Locale_codecvt_t *lcodecvt)
void _Locale_codecvt_destroy(_Locale_codecvt_t *lcodecvt)
const wchar_t * _WLocale_full_dayofweek(_Locale_time_t *ltime, int day, wchar_t *buf, size_t bufSize)
_Locale_mask_t _WLocale_ctype(_Locale_ctype_t *ltype, wint_t c, _Locale_mask_t which_bits)
wint_t _WLocale_tolower(_Locale_ctype_t *ltype, wint_t c)
wchar_t _WLocale_thousands_sep(_Locale_numeric_t *lnum)
const wchar_t * _WLocale_am_str(_Locale_time_t *ltime, wchar_t *buf, size_t bufSize)
static const wchar_t * __wtrue_name
const wchar_t * _WLocale_false(_Locale_numeric_t *lnum, wchar_t *buf, size_t bufSize)
wchar_t _WLocale_mon_thousands_sep(_Locale_monetary_t *lmon)
const wchar_t * _WLocale_true(_Locale_numeric_t *lnum, wchar_t *buf, size_t bufSize)
wint_t _WLocale_toupper(_Locale_ctype_t *ltype, wint_t c)
static int _WLocale_strcmp_aux(_Locale_collate_t *lcol, const wchar_t *s1, size_t n1, const wchar_t *s2, size_t n2)
const wchar_t * _WLocale_currency_symbol(_Locale_monetary_t *lmon, wchar_t *buf, size_t bufSize)
size_t _WLocale_wctomb(_Locale_codecvt_t *lcodecvt, char *to, size_t n, const wchar_t c, mbstate_t *shift_state)
size_t _WLocale_unshift(_Locale_codecvt_t *lcodecvt, mbstate_t *st, char *buf, size_t n, char **next)
int _WLocale_mb_cur_max(_Locale_codecvt_t *lcodecvt)
_Locale_codecvt_t * _Locale_codecvt_create(const char *name, _Locale_lcid_t *lc_hint, int *__err_code)
wchar_t _WLocale_mon_decimal_point(_Locale_monetary_t *lmon)
const wchar_t * _WLocale_full_monthname(_Locale_time_t *ltime, int month, wchar_t *buf, size_t bufSize)
const wchar_t * _WLocale_abbrev_dayofweek(_Locale_time_t *ltime, int day, wchar_t *buf, size_t bufSize)
int _WLocale_strcmp(_Locale_collate_t *lcol, const wchar_t *s1, size_t n1, const wchar_t *s2, size_t n2)
const wchar_t * _WLocale_int_curr_symbol(_Locale_monetary_t *lmon, wchar_t *buf, size_t bufSize)
size_t _WLocale_strxfrm(_Locale_collate_t *lcol, wchar_t *dst, size_t dst_size, const wchar_t *src, size_t src_size)
const wchar_t * _WLocale_abbrev_monthname(_Locale_time_t *ltime, int month, wchar_t *buf, size_t bufSize)
int _WLocale_is_stateless(_Locale_codecvt_t *lcodecvt)
const wchar_t * _WLocale_pm_str(_Locale_time_t *ltime, wchar_t *buf, size_t bufSize)
static const wchar_t * __wfalse_name
char const * _Locale_codecvt_name(const _Locale_codecvt_t *lcodecvt, char *buf)
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
static DOUBLE day(DOUBLE time)
Definition: date.c:117
INT WINAPI CompareStringW(LCID lcid, DWORD flags, LPCWSTR str1, INT len1, LPCWSTR str2, INT len2)
Definition: locale.c:4014
BOOL WINAPI GetCPInfo(UINT codepage, LPCPINFO cpinfo)
Definition: locale.c:2144
BOOL WINAPI GetStringTypeW(DWORD type, LPCWSTR src, INT count, LPWORD chartype)
Definition: locale.c:3095
INT WINAPI LCMapStringW(LCID lcid, DWORD flags, LPCWSTR src, INT srclen, LPWSTR dst, INT dstlen)
Definition: locale.c:3805
INT WINAPI GetLocaleInfoW(LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len)
Definition: locale.c:1666
unsigned char
Definition: typeof.h:29
static const WCHAR month[12][4]
Definition: session.c:2150
#define CHAR_BIT
Definition: urlcache.c:62
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLdouble n
Definition: glext.h:7729
GLuint res
Definition: glext.h:9613
GLenum src
Definition: glext.h:6340
const GLubyte * c
Definition: glext.h:8905
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLenum dst
Definition: glext.h:6340
GLuint GLsizei bufSize
Definition: glext.h:6040
GLuint64EXT * result
Definition: glext.h:11304
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define WC_COMPOSITECHECK
Definition: unicode.h:43
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
#define INT_MAX
Definition: intsafe.h:150
#define c
Definition: ke_i.h:80
unsigned short int _Locale_mask_t
Definition: c_locale.h:63
#define _STLP_LOC_NO_MEMORY
Definition: c_locale.h:103
#define _STLP_LOC_UNKNOWN_NAME
Definition: c_locale.h:101
struct S1 s1
struct S2 s2
static PVOID ptr
Definition: dispmode.c:27
unsigned int UINT
Definition: ndis.h:50
#define L(x)
Definition: ntvdm.h:50
static unsigned __int64 next
Definition: rand_nt.c:6
static FILE * out
Definition: regtests2xml.c:44
int n2
Definition: dwarfget.c:147
int n1
Definition: dwarfget.c:147
#define CP_UTF8
Definition: nls.h:20
#define memset(x, y, z)
Definition: compat.h:39
CardRegion * from
Definition: spigame.cpp:19
unsigned char cleads[256/CHAR_BIT]
unsigned char max_char_size
_Locale_lcid_t lc
_Locale_lcid_t lc
_Locale_lcid_t lc
_Locale_lcid_t lc
_Locale_lcid_t lc
_Locale_lcid_t lc
BYTE LeadByte[MAX_LEADBYTES]
Definition: winnls.h:585
UINT MaxCharSize
Definition: winnls.h:583
Definition: name.c:39
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define ERROR_NO_UNICODE_TRANSLATION
Definition: winerror.h:649
#define LOCALE_SDECIMAL
Definition: winnls.h:44
#define CT_CTYPE1
Definition: winnls.h:239
#define LOCALE_SDAYNAME1
Definition: winnls.h:79
#define LCMAP_UPPERCASE
Definition: winnls.h:187
#define LOCALE_S1159
Definition: winnls.h:73
#define WC_SEPCHARS
Definition: winnls.h:221
#define CSTR_EQUAL
Definition: winnls.h:458
#define CP_UTF7
Definition: winnls.h:237
#define LOCALE_SPOSITIVESIGN
Definition: winnls.h:119
#define LCMAP_SORTKEY
Definition: winnls.h:188
#define LCMAP_LOWERCASE
Definition: winnls.h:186
#define MB_PRECOMPOSED
Definition: winnls.h:283
#define LOCALE_SMONTHNAME1
Definition: winnls.h:93
#define LOCALE_SABBREVMONTHNAME1
Definition: winnls.h:106
#define LOCALE_STHOUSAND
Definition: winnls.h:45
#define LOCALE_SABBREVDAYNAME1
Definition: winnls.h:86
#define LOCALE_SNEGATIVESIGN
Definition: winnls.h:120
#define CSTR_LESS_THAN
Definition: winnls.h:457
#define LOCALE_S2359
Definition: winnls.h:74
#define LOCALE_SINTLSYMBOL
Definition: winnls.h:52
#define LOCALE_SCURRENCY
Definition: winnls.h:51