In search of meaningful error messages and some housekeeping on the stubs file.
[reactos.git] / reactos / lib / kernel32 / misc / mbchars.c
1 /* $Id: mbchars.c,v 1.1 2002/12/06 13:14:14 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 {
104 InStringLength = lstrlen(lpMultiByteStr) + 1;
105 }
106 else
107 {
108 InStringLength = cchMultiByte;
109 }
110 /*
111 * Does caller query for output
112 * buffer size?
113 */
114 if (0 == cchWideChar)
115 {
116 SetLastError(ERROR_SUCCESS);
117 return InStringLength;
118 }
119 /*
120 * Is space provided for the translated
121 * string enough?
122 */
123 if (cchWideChar < InStringLength)
124 {
125 SetLastError(ERROR_INSUFFICIENT_BUFFER);
126 return 0;
127 }
128 /*
129 * Raw 8- to 16-bit conversion.
130 */
131 for (cchConverted = 0,
132 r = (PCHAR)lpMultiByteStr,
133 w = (PWCHAR)lpWideCharStr;
134
135 cchConverted < InStringLength;
136
137 r++,
138 w++,
139 cchConverted++)
140 {
141 *w = (WCHAR)*r;
142 }
143 /*
144 * Return how many characters we
145 * wrote in the output buffer.
146 */
147 SetLastError(ERROR_SUCCESS);
148 return cchConverted;
149 }
150
151
152 /**********************************************************************
153 * NAME EXPORTED
154 * WideCharToMultiByte@32
155 *
156 * Not yet implemented complete (without NLS so far)
157 *
158 * ARGUMENTS
159 * CodePage
160 * CP_ACP ANSI code page
161 * CP_MACCP Macintosh code page
162 * CP_OEMCP OEM code page
163 * CP_SYMBOL Symbol code page (42)
164 * CP_THREAD_ACP Current thread's ANSI code page
165 * CP_UTF7 Translate using UTF-7
166 * CP_UTF8 Translate using UTF-8
167 * (UINT) Any installed code page
168 *
169 * dwFlags
170 * WC_NO_BEST_FIT_CHARS
171 * WC_COMPOSITECHECK Convert composite characters to precomposed characters.
172 * WC_DISCARDNS Discard nonspacing characters during conversion.
173 * WC_SEPCHARS Generate separate characters during conversion. This is the default conversion behavior.
174 * WC_DEFAULTCHAR Replace exceptions with the default character during conversion.
175 *
176 * lpWideCharStr
177 * Points to the wide-character string to be converted.
178 *
179 * cchWideChar
180 * Size (in WCHAR unit) of WideCharStr, or 0
181 * if the caller just wants to know how large
182 * WideCharStr should be for a successful
183 * conversion.
184 * lpMultiByteStr
185 * Points to the buffer to receive the translated string.
186 * cchMultiByte
187 * Specifies the size in bytes of the buffer pointed to by the
188 * lpMultiByteStr parameter. If this value is zero, the function
189 * returns the number of bytes required for the buffer.
190 * lpDefaultChar
191 * Points to the character used if a wide character cannot be
192 * represented in the specified code page. If this parameter is
193 * NULL, a system default value is used.
194 FIXME: ignored
195 * lpUsedDefaultChar
196 * Points to a flag that indicates whether a default character was used.
197 * This parameter may be NULL.
198 FIXME: allways set to FALSE.
199 *
200 *
201 *
202 * RETURN VALUE
203 * 0 on error; otherwise the number of bytes written
204 * in the lpMultiByteStr buffer. Or the number of
205 * bytes needed for the lpMultiByteStr buffer if cchMultiByte is zero.
206 *
207 * NOTE
208 * A raw converter for now. It just cuts off the upper 9 Bit.
209 * So the MBCS-string does not contain any LeadCharacters
210 * FIXME - FIXME - FIXME - FIXME
211 */
212
213 int
214 STDCALL
215 WideCharToMultiByte(
216 UINT CodePage,
217 DWORD dwFlags,
218 LPCWSTR lpWideCharStr,
219 int cchWideChar,
220 LPSTR lpMultiByteStr,
221 int cchMultiByte,
222 LPCSTR lpDefaultChar,
223 LPBOOL lpUsedDefaultChar
224 )
225 {
226 int wi, di; // wide counter, dbcs byte count
227
228 /*
229 * Check the parameters.
230 */
231 if ( /* --- CODE PAGE --- */
232 ( (CP_ACP != CodePage)
233 && (CP_MACCP != CodePage)
234 && (CP_OEMCP != CodePage)
235 && (CP_SYMBOL != CodePage)
236 && (CP_THREAD_ACP != CodePage)
237 && (CP_UTF7 != CodePage)
238 && (CP_UTF8 != CodePage)
239 && (FALSE == IsInstalledCP (CodePage))
240 )
241 /* --- FLAGS --- */
242 || (dwFlags & ~(/*WC_NO_BEST_FIT_CHARS
243 |*/ WC_COMPOSITECHECK
244 | WC_DISCARDNS
245 | WC_SEPCHARS
246 | WC_DEFAULTCHAR
247 )
248 )
249 /* --- INPUT BUFFER --- */
250 || (NULL == lpWideCharStr)
251 )
252 {
253 SetLastError(ERROR_INVALID_PARAMETER);
254 return 0;
255 }
256
257 // for now, make no difference but only convert cut the characters to 7Bit
258 if (cchWideChar == -1) // assume its a 0-terminated str
259 { // and determine its length
260 for (cchWideChar=0; lpWideCharStr[cchWideChar]!=0; cchWideChar++)
261 cchWideChar++;
262 }
263
264 // user wants to determine needed space
265 if (cchMultiByte == 0)
266 {
267 SetLastError(ERROR_SUCCESS);
268 return cchWideChar; // FIXME: determine correct.
269 }
270 // the lpWideCharStr is cchWideChar characters long.
271 for (wi=0, di=0; wi<cchWideChar && di<cchMultiByte; ++wi, ++di)
272 {
273 // Flag and a not displayable char FIXME
274 /*if( (dwFlags&WC_NO_BEST_FIT_CHARS) && (lpWideCharStr[wi] >127) )
275 {
276 lpMultiByteStr[di]=
277 *lpUsedDefaultChar = TRUE;
278
279 }*/
280 // FIXME
281 // just cut off the upper 9 Bit, since vals>=128 mean LeadByte.
282 lpMultiByteStr[di] = lpWideCharStr[wi] & 0x007F;
283 }
284 // has MultiByte exceeded but Wide is still in the string?
285 if (wi < cchWideChar && di >= cchMultiByte)
286 {
287 SetLastError(ERROR_INSUFFICIENT_BUFFER);
288 return 0;
289 }
290 // else return # of bytes wirtten to MBCSbuffer (di)
291 SetLastError(ERROR_SUCCESS);
292 // FIXME: move that elsewhere
293 if (lpUsedDefaultChar != NULL) *lpUsedDefaultChar = FALSE;
294 return di;
295 }
296
297 /* EOF */