2 * msvcrt.dll mbcs functions
4 * Copyright 1999 Alexandre Julliard
5 * Copyright 2000 Jon Griffths
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 * Not currently binary compatible with win32. MSVCRT_mbctype must be
23 * populated correctly and the ismb* functions should reference it.
30 /* It seems that the data about valid trail bytes is not available from kernel32
31 * so we have to store is here. The format is the same as for lead bytes in CPINFO */
32 struct cp_extra_info_t
35 BYTE TrailBytes
[MAX_LEADBYTES
];
38 static struct cp_extra_info_t g_cpextrainfo
[] =
40 {932, {0x40, 0x7e, 0x80, 0xfc, 0, 0}},
41 {936, {0x40, 0xfe, 0, 0}},
42 {949, {0x41, 0xfe, 0, 0}},
43 {950, {0x40, 0x7e, 0xa1, 0xfe, 0, 0}},
44 {1361, {0x31, 0x7e, 0x81, 0xfe, 0, 0}},
45 {20932, {1, 255, 0, 0}}, /* seems to give different results on different systems */
46 {0, {1, 255, 0, 0}} /* match all with FIXME */
49 /*********************************************************************
50 * INTERNAL: _setmbcp_l
52 int _setmbcp_l(int cp
, LCID lcid
, MSVCRT_pthreadmbcinfo mbcinfo
)
54 const char format
[] = ".%d";
67 mbcinfo
= get_mbcinfo();
78 newcp
= get_locinfo()->lc_codepage
;
81 /* fall through (C locale) */
83 newcp
= 20127; /* ASCII */
91 sprintf(bufA
, format
, newcp
);
92 mbcinfo
->mblcid
= MSVCRT_locale_to_LCID(bufA
, NULL
);
94 mbcinfo
->mblcid
= lcid
;
97 if(mbcinfo
->mblcid
== -1)
99 WARN("Can't assign LCID to codepage (%d)\n", mbcinfo
->mblcid
);
103 if (!GetCPInfo(newcp
, &cpi
))
105 WARN("Codepage %d not found\n", newcp
);
110 /* setup the _mbctype */
111 memset(mbcinfo
->mbctype
, 0, sizeof(unsigned char[257]));
112 memset(mbcinfo
->mbcasemap
, 0, sizeof(unsigned char[256]));
114 bytes
= cpi
.LeadByte
;
115 while (bytes
[0] || bytes
[1])
117 for (i
= bytes
[0]; i
<= bytes
[1]; i
++)
118 mbcinfo
->mbctype
[i
+ 1] |= _M1
;
122 if (cpi
.MaxCharSize
> 1)
124 /* trail bytes not available through kernel32 but stored in a structure in msvcrt */
125 struct cp_extra_info_t
*cpextra
= g_cpextrainfo
;
127 mbcinfo
->ismbcodepage
= 1;
130 if (cpextra
->cp
== 0 || cpextra
->cp
== newcp
)
132 if (cpextra
->cp
== 0)
133 FIXME("trail bytes data not available for DBCS codepage %d - assuming all bytes\n", newcp
);
135 bytes
= cpextra
->TrailBytes
;
136 while (bytes
[0] || bytes
[1])
138 for (i
= bytes
[0]; i
<= bytes
[1]; i
++)
139 mbcinfo
->mbctype
[i
+ 1] |= _M2
;
148 mbcinfo
->ismbcodepage
= 0;
150 /* we can't use GetStringTypeA directly because we don't have a locale - only a code page
153 for (i
= 0; i
< 256; i
++)
154 if (!(mbcinfo
->mbctype
[i
+ 1] & _M1
))
155 bufA
[charcount
++] = i
;
157 ret
= MultiByteToWideChar(newcp
, 0, bufA
, charcount
, bufW
, charcount
);
158 if (ret
!= charcount
)
159 ERR("MultiByteToWideChar of chars failed for cp %d, ret=%d (exp %d), error=%d\n", newcp
, ret
, charcount
, GetLastError());
161 GetStringTypeW(CT_CTYPE1
, bufW
, charcount
, chartypes
);
164 for (i
= 0; i
< 256; i
++)
165 if (!(mbcinfo
->mbctype
[i
+ 1] & _M1
))
167 if (chartypes
[charcount
] & C1_UPPER
)
169 mbcinfo
->mbctype
[i
+ 1] |= _SBUP
;
170 bufW
[charcount
] = tolowerW(bufW
[charcount
]);
172 else if (chartypes
[charcount
] & C1_LOWER
)
174 mbcinfo
->mbctype
[i
+ 1] |= _SBLOW
;
175 bufW
[charcount
] = toupperW(bufW
[charcount
]);
180 ret
= WideCharToMultiByte(newcp
, 0, bufW
, charcount
, bufA
, charcount
, NULL
, NULL
);
181 if (ret
!= charcount
)
182 ERR("WideCharToMultiByte failed for cp %d, ret=%d (exp %d), error=%d\n", newcp
, ret
, charcount
, GetLastError());
185 for (i
= 0; i
< 256; i
++)
187 if(!(mbcinfo
->mbctype
[i
+ 1] & _M1
))
189 if(mbcinfo
->mbctype
[i
] & (C1_UPPER
|C1_LOWER
))
190 mbcinfo
->mbcasemap
[i
] = bufA
[charcount
];
195 if (newcp
== 932) /* CP932 only - set _MP and _MS */
197 /* On Windows it's possible to calculate the _MP and _MS from CT_CTYPE1
198 * and CT_CTYPE3. But as of Wine 0.9.43 we return wrong values what makes
199 * it hard. As this is set only for codepage 932 we hardcode it what gives
200 * also faster execution.
202 for (i
= 161; i
<= 165; i
++)
203 mbcinfo
->mbctype
[i
+ 1] |= _MP
;
204 for (i
= 166; i
<= 223; i
++)
205 mbcinfo
->mbctype
[i
+ 1] |= _MS
;
208 mbcinfo
->mbcodepage
= newcp
;
209 if(MSVCRT_locale
&& mbcinfo
== MSVCRT_locale
->mbcinfo
)
210 memcpy(_mbctype
, MSVCRT_locale
->mbcinfo
->mbctype
, sizeof(_mbctype
));
215 /*********************************************************************
216 * _setmbcp (MSVCRT.@)
218 int CDECL
_setmbcp(int cp
)
220 return _setmbcp_l(cp
, -1, NULL
);