1 /* $Id: mbchars.c,v 1.5 2004/04/04 17:59:23 gvg Exp $
7 /**********************************************************************
12 * TRUE if CodePage is installed in the system.
17 IsInstalledCP(UINT CodePage
)
24 /**********************************************************************
26 * MultiByteToWideChar@24
30 * CP_ACP ANSI code page
31 * CP_MACCP Macintosh code page
32 * CP_OEMCP OEM code page
33 * (UINT) Any installed code page
38 * MB_ERR_INVALID_CHARS
45 * Size of MultiByteStr, or -1 if MultiByteStr is
52 * Size (in WCHAR unit) of WideCharStr, or 0
53 * if the caller just wants to know how large
54 * WideCharStr should be for a successful
58 * 0 on error; otherwise the number of WCHAR written
59 * in the WideCharStr buffer.
62 * A raw converter for now. It assumes lpMultiByteStr is
63 * NEVER multi-byte (that is each input character is
64 * 8-bit ASCII) and is ALWAYS NULL terminated.
65 * FIXME-FIXME-FIXME-FIXME
74 LPCSTR lpMultiByteStr
,
79 int InStringLength
= 0;
85 * Check the parameters.
87 if (/* --- CODE PAGE --- */
88 ( (CP_ACP
!= CodePage
)
89 && (CP_MACCP
!= CodePage
)
90 && (CP_OEMCP
!= CodePage
)
91 && (FALSE
== IsInstalledCP(CodePage
)) )
93 || (dwFlags
& ~(MB_PRECOMPOSED
| MB_COMPOSITE
|
94 MB_ERR_INVALID_CHARS
| MB_USEGLYPHCHARS
))
95 /* --- INPUT BUFFER --- */
96 || (NULL
== lpMultiByteStr
) )
98 SetLastError (ERROR_INVALID_PARAMETER
);
102 * Compute the input buffer length.
104 //if (-1 == cchMultiByte)
105 if (cchMultiByte
< 0)
107 InStringLength
= lstrlenA(lpMultiByteStr
) + 1;
111 InStringLength
= cchMultiByte
;
114 * Does caller query for output
117 if (0 == cchWideChar
)
119 //SetLastError(ERROR_SUCCESS); /* according to wine tests this shouldn't be touched on success.
120 return InStringLength
;
123 * Is space provided for the translated
126 if (cchWideChar
< InStringLength
)
128 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
132 * Raw 8- to 16-bit conversion.
134 for (cchConverted
= 0,
135 r
= (PCHAR
)lpMultiByteStr
,
136 w
= (PWCHAR
)lpWideCharStr
;
138 cchConverted
< InStringLength
;
144 *w
= (WCHAR
)(unsigned char) *r
;
147 * Return how many characters we
148 * wrote in the output buffer.
150 //SetLastError(ERROR_SUCCESS); /* according to wine tests this shouldn't be touched on success.
155 /**********************************************************************
157 * WideCharToMultiByte@32
159 * Not yet implemented complete (without NLS so far)
163 * CP_ACP ANSI code page
164 * CP_MACCP Macintosh code page
165 * CP_OEMCP OEM code page
166 * CP_SYMBOL Symbol code page (42)
167 * CP_THREAD_ACP Current thread's ANSI code page
168 * CP_UTF7 Translate using UTF-7
169 * CP_UTF8 Translate using UTF-8
170 * (UINT) Any installed code page
173 * WC_NO_BEST_FIT_CHARS
174 * WC_COMPOSITECHECK Convert composite characters to precomposed characters.
175 * WC_DISCARDNS Discard nonspacing characters during conversion.
176 * WC_SEPCHARS Generate separate characters during conversion. This is the default conversion behavior.
177 * WC_DEFAULTCHAR Replace exceptions with the default character during conversion.
180 * Points to the wide-character string to be converted.
183 * Size (in WCHAR unit) of WideCharStr, or 0
184 * if the caller just wants to know how large
185 * WideCharStr should be for a successful
188 * Points to the buffer to receive the translated string.
190 * Specifies the size in bytes of the buffer pointed to by the
191 * lpMultiByteStr parameter. If this value is zero, the function
192 * returns the number of bytes required for the buffer.
194 * Points to the character used if a wide character cannot be
195 * represented in the specified code page. If this parameter is
196 * NULL, a system default value is used.
199 * Points to a flag that indicates whether a default character was used.
200 * This parameter may be NULL.
201 FIXME: allways set to FALSE.
206 * 0 on error; otherwise the number of bytes written
207 * in the lpMultiByteStr buffer. Or the number of
208 * bytes needed for the lpMultiByteStr buffer if cchMultiByte is zero.
211 * A raw converter for now. It just cuts off the upper 9 Bit.
212 * So the MBCS-string does not contain any LeadCharacters
213 * FIXME - FIXME - FIXME - FIXME
222 LPCWSTR lpWideCharStr
,
224 LPSTR lpMultiByteStr
,
226 LPCSTR lpDefaultChar
,
227 LPBOOL lpUsedDefaultChar
230 int wi
, di
; // wide counter, dbcs byte count
233 * Check the parameters.
235 if ( /* --- CODE PAGE --- */
236 ( (CP_ACP
!= CodePage
)
237 && (CP_MACCP
!= CodePage
)
238 && (CP_OEMCP
!= CodePage
)
239 && (CP_SYMBOL
!= CodePage
)
240 && (CP_THREAD_ACP
!= CodePage
)
241 && (CP_UTF7
!= CodePage
)
242 && (CP_UTF8
!= CodePage
)
243 && (FALSE
== IsInstalledCP (CodePage
))
246 || (dwFlags
& ~(/*WC_NO_BEST_FIT_CHARS
247 |*/ WC_COMPOSITECHECK
253 /* --- INPUT BUFFER --- */
254 || (NULL
== lpWideCharStr
)
257 SetLastError(ERROR_INVALID_PARAMETER
);
261 // for now, make no difference but only convert cut the characters to 7Bit
262 //if (cchWideChar == -1) // assume its a 0-terminated str
263 if (cchWideChar
< 0) // assume its a 0-terminated str
264 { // and determine its length
265 // for (cchWideChar=0; lpWideCharStr[cchWideChar]!=0; cchWideChar++)
267 for (cchWideChar
= 0; lpWideCharStr
[cchWideChar
] != 0; cchWideChar
++) {
269 cchWideChar
++; // length includes the null terminator
272 // user wants to determine needed space
273 if (cchMultiByte
== 0)
275 //SetLastError(ERROR_SUCCESS); /* according to wine tests this shouldn't be touched on success.
276 return cchWideChar
; // FIXME: determine correct.
278 // the lpWideCharStr is cchWideChar characters long.
279 for (wi
=0, di
=0; wi
<cchWideChar
&& di
<cchMultiByte
; ++wi
, ++di
)
281 // Flag and a not displayable char FIXME
282 /*if( (dwFlags&WC_NO_BEST_FIT_CHARS) && (lpWideCharStr[wi] >127) )
285 *lpUsedDefaultChar = TRUE;
289 // just cut off the upper 9 Bit, since vals>=128 mean LeadByte.
290 lpMultiByteStr
[di
] = lpWideCharStr
[wi
] & 0x007F;
292 // has MultiByte exceeded but Wide is still in the string?
293 if (wi
< cchWideChar
&& di
>= cchMultiByte
)
295 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
298 // else return # of bytes wirtten to MBCSbuffer (di)
299 //SetLastError(ERROR_SUCCESS); /* according to wine tests this shouldn't be touched on success.
300 // FIXME: move that elsewhere
301 if (lpUsedDefaultChar
!= NULL
) *lpUsedDefaultChar
= FALSE
;