Fixed "kernel32_test codepage" conformance test:
[reactos.git] / reactos / lib / kernel32 / misc / mbchars.c
1 /* $Id: mbchars.c,v 1.2 2002/12/12 04:53:23 robd Exp $
2 *
3 */
4 #include <windows.h>
5
6
7 /**********************************************************************
8 * NAME PRIVATE
9 * IsInstalledCP@4
10 *
11 * RETURN VALUE
12 * TRUE if CodePage is installed in the system.
13 */
14 static
15 BOOL
16 STDCALL
17 IsInstalledCP(UINT CodePage)
18 {
19 /* FIXME */
20 return TRUE;
21 }
22
23
24 /**********************************************************************
25 * NAME EXPORTED
26 * MultiByteToWideChar@24
27 *
28 * ARGUMENTS
29 * CodePage
30 * CP_ACP ANSI code page
31 * CP_MACCP Macintosh code page
32 * CP_OEMCP OEM code page
33 * (UINT) Any installed code page
34 *
35 * dwFlags
36 * MB_PRECOMPOSED
37 * MB_COMPOSITE
38 * MB_ERR_INVALID_CHARS
39 * MB_USEGLYPHCHARS
40 *
41 * lpMultiByteStr
42 * Input buffer;
43 *
44 * cchMultiByte
45 * Size of MultiByteStr, or -1 if MultiByteStr is
46 * NULL terminated;
47 *
48 * lpWideCharStr
49 * Output buffer;
50 *
51 * cchWideChar
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
55 * conversion.
56 *
57 * RETURN VALUE
58 * 0 on error; otherwise the number of WCHAR written
59 * in the WideCharStr buffer.
60 *
61 * NOTE
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
66 */
67 INT
68 STDCALL
69 MultiByteToWideChar(
70 UINT CodePage,
71 DWORD dwFlags,
72 LPCSTR lpMultiByteStr,
73 int cchMultiByte,
74 LPWSTR lpWideCharStr,
75 int cchWideChar)
76 {
77 int InStringLength = 0;
78 PCHAR r;
79 PWCHAR w;
80 int cchConverted;
81
82 /*
83 * Check the parameters.
84 */
85 if (/* --- CODE PAGE --- */
86 ( (CP_ACP != CodePage)
87 && (CP_MACCP != CodePage)
88 && (CP_OEMCP != CodePage)
89 && (FALSE == IsInstalledCP(CodePage)) )
90 /* --- FLAGS --- */
91 || (dwFlags & ~(MB_PRECOMPOSED | MB_COMPOSITE |
92 MB_ERR_INVALID_CHARS | MB_USEGLYPHCHARS))
93 /* --- INPUT BUFFER --- */
94 || (NULL == lpMultiByteStr) )
95 {
96 SetLastError (ERROR_INVALID_PARAMETER);
97 return 0;
98 }
99 /*
100 * Compute the input buffer length.
101 */
102 //if (-1 == cchMultiByte)
103 if (cchMultiByte < 0)
104 {
105 InStringLength = lstrlen(lpMultiByteStr) + 1;
106 }
107 else
108 {
109 InStringLength = cchMultiByte;
110 }
111 /*
112 * Does caller query for output
113 * buffer size?
114 */
115 if (0 == cchWideChar)
116 {
117 //SetLastError(ERROR_SUCCESS); /* according to wine tests this shouldn't be touched on success.
118 return InStringLength;
119 }
120 /*
121 * Is space provided for the translated
122 * string enough?
123 */
124 if (cchWideChar < InStringLength)
125 {
126 SetLastError(ERROR_INSUFFICIENT_BUFFER);
127 return 0;
128 }
129 /*
130 * Raw 8- to 16-bit conversion.
131 */
132 for (cchConverted = 0,
133 r = (PCHAR)lpMultiByteStr,
134 w = (PWCHAR)lpWideCharStr;
135
136 cchConverted < InStringLength;
137
138 r++,
139 w++,
140 cchConverted++)
141 {
142 *w = (WCHAR)*r;
143 }
144 /*
145 * Return how many characters we
146 * wrote in the output buffer.
147 */
148 //SetLastError(ERROR_SUCCESS); /* according to wine tests this shouldn't be touched on success.
149 return cchConverted;
150 }
151
152
153 /**********************************************************************
154 * NAME EXPORTED
155 * WideCharToMultiByte@32
156 *
157 * Not yet implemented complete (without NLS so far)
158 *
159 * ARGUMENTS
160 * CodePage
161 * CP_ACP ANSI code page
162 * CP_MACCP Macintosh code page
163 * CP_OEMCP OEM code page
164 * CP_SYMBOL Symbol code page (42)
165 * CP_THREAD_ACP Current thread's ANSI code page
166 * CP_UTF7 Translate using UTF-7
167 * CP_UTF8 Translate using UTF-8
168 * (UINT) Any installed code page
169 *
170 * dwFlags
171 * WC_NO_BEST_FIT_CHARS
172 * WC_COMPOSITECHECK Convert composite characters to precomposed characters.
173 * WC_DISCARDNS Discard nonspacing characters during conversion.
174 * WC_SEPCHARS Generate separate characters during conversion. This is the default conversion behavior.
175 * WC_DEFAULTCHAR Replace exceptions with the default character during conversion.
176 *
177 * lpWideCharStr
178 * Points to the wide-character string to be converted.
179 *
180 * cchWideChar
181 * Size (in WCHAR unit) of WideCharStr, or 0
182 * if the caller just wants to know how large
183 * WideCharStr should be for a successful
184 * conversion.
185 * lpMultiByteStr
186 * Points to the buffer to receive the translated string.
187 * cchMultiByte
188 * Specifies the size in bytes of the buffer pointed to by the
189 * lpMultiByteStr parameter. If this value is zero, the function
190 * returns the number of bytes required for the buffer.
191 * lpDefaultChar
192 * Points to the character used if a wide character cannot be
193 * represented in the specified code page. If this parameter is
194 * NULL, a system default value is used.
195 FIXME: ignored
196 * lpUsedDefaultChar
197 * Points to a flag that indicates whether a default character was used.
198 * This parameter may be NULL.
199 FIXME: allways set to FALSE.
200 *
201 *
202 *
203 * RETURN VALUE
204 * 0 on error; otherwise the number of bytes written
205 * in the lpMultiByteStr buffer. Or the number of
206 * bytes needed for the lpMultiByteStr buffer if cchMultiByte is zero.
207 *
208 * NOTE
209 * A raw converter for now. It just cuts off the upper 9 Bit.
210 * So the MBCS-string does not contain any LeadCharacters
211 * FIXME - FIXME - FIXME - FIXME
212 */
213
214 int
215 STDCALL
216 WideCharToMultiByte(
217 UINT CodePage,
218 DWORD dwFlags,
219 LPCWSTR lpWideCharStr,
220 int cchWideChar,
221 LPSTR lpMultiByteStr,
222 int cchMultiByte,
223 LPCSTR lpDefaultChar,
224 LPBOOL lpUsedDefaultChar
225 )
226 {
227 int wi, di; // wide counter, dbcs byte count
228
229 /*
230 * Check the parameters.
231 */
232 if ( /* --- CODE PAGE --- */
233 ( (CP_ACP != CodePage)
234 && (CP_MACCP != CodePage)
235 && (CP_OEMCP != CodePage)
236 && (CP_SYMBOL != CodePage)
237 && (CP_THREAD_ACP != CodePage)
238 && (CP_UTF7 != CodePage)
239 && (CP_UTF8 != CodePage)
240 && (FALSE == IsInstalledCP (CodePage))
241 )
242 /* --- FLAGS --- */
243 || (dwFlags & ~(/*WC_NO_BEST_FIT_CHARS
244 |*/ WC_COMPOSITECHECK
245 | WC_DISCARDNS
246 | WC_SEPCHARS
247 | WC_DEFAULTCHAR
248 )
249 )
250 /* --- INPUT BUFFER --- */
251 || (NULL == lpWideCharStr)
252 )
253 {
254 SetLastError(ERROR_INVALID_PARAMETER);
255 return 0;
256 }
257
258 // for now, make no difference but only convert cut the characters to 7Bit
259 //if (cchWideChar == -1) // assume its a 0-terminated str
260 if (cchWideChar < 0) // assume its a 0-terminated str
261 { // and determine its length
262 // for (cchWideChar=0; lpWideCharStr[cchWideChar]!=0; cchWideChar++)
263 // cchWideChar++;
264 for (cchWideChar = 0; lpWideCharStr[cchWideChar] != 0; cchWideChar++) {
265 }
266 cchWideChar++; // length includes the null terminator
267 }
268
269 // user wants to determine needed space
270 if (cchMultiByte == 0)
271 {
272 //SetLastError(ERROR_SUCCESS); /* according to wine tests this shouldn't be touched on success.
273 return cchWideChar; // FIXME: determine correct.
274 }
275 // the lpWideCharStr is cchWideChar characters long.
276 for (wi=0, di=0; wi<cchWideChar && di<cchMultiByte; ++wi, ++di)
277 {
278 // Flag and a not displayable char FIXME
279 /*if( (dwFlags&WC_NO_BEST_FIT_CHARS) && (lpWideCharStr[wi] >127) )
280 {
281 lpMultiByteStr[di]=
282 *lpUsedDefaultChar = TRUE;
283
284 }*/
285 // FIXME
286 // just cut off the upper 9 Bit, since vals>=128 mean LeadByte.
287 lpMultiByteStr[di] = lpWideCharStr[wi] & 0x007F;
288 }
289 // has MultiByte exceeded but Wide is still in the string?
290 if (wi < cchWideChar && di >= cchMultiByte)
291 {
292 SetLastError(ERROR_INSUFFICIENT_BUFFER);
293 return 0;
294 }
295 // else return # of bytes wirtten to MBCSbuffer (di)
296 //SetLastError(ERROR_SUCCESS); /* according to wine tests this shouldn't be touched on success.
297 // FIXME: move that elsewhere
298 if (lpUsedDefaultChar != NULL) *lpUsedDefaultChar = FALSE;
299 return di;
300 }
301
302 /* EOF */