- Fix Get[System/Window]Directory[AW] for Buffer == NULL case.
[reactos.git] / reactos / lib / kernel32 / misc / mbchars.c
1 /* $Id: mbchars.c,v 1.5 2004/04/04 17:59:23 gvg 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 * @implemented
68 */
69 INT
70 STDCALL
71 MultiByteToWideChar(
72 UINT CodePage,
73 DWORD dwFlags,
74 LPCSTR lpMultiByteStr,
75 int cchMultiByte,
76 LPWSTR lpWideCharStr,
77 int cchWideChar)
78 {
79 int InStringLength = 0;
80 PCHAR r;
81 PWCHAR w;
82 int cchConverted;
83
84 /*
85 * Check the parameters.
86 */
87 if (/* --- CODE PAGE --- */
88 ( (CP_ACP != CodePage)
89 && (CP_MACCP != CodePage)
90 && (CP_OEMCP != CodePage)
91 && (FALSE == IsInstalledCP(CodePage)) )
92 /* --- FLAGS --- */
93 || (dwFlags & ~(MB_PRECOMPOSED | MB_COMPOSITE |
94 MB_ERR_INVALID_CHARS | MB_USEGLYPHCHARS))
95 /* --- INPUT BUFFER --- */
96 || (NULL == lpMultiByteStr) )
97 {
98 SetLastError (ERROR_INVALID_PARAMETER);
99 return 0;
100 }
101 /*
102 * Compute the input buffer length.
103 */
104 //if (-1 == cchMultiByte)
105 if (cchMultiByte < 0)
106 {
107 InStringLength = lstrlenA(lpMultiByteStr) + 1;
108 }
109 else
110 {
111 InStringLength = cchMultiByte;
112 }
113 /*
114 * Does caller query for output
115 * buffer size?
116 */
117 if (0 == cchWideChar)
118 {
119 //SetLastError(ERROR_SUCCESS); /* according to wine tests this shouldn't be touched on success.
120 return InStringLength;
121 }
122 /*
123 * Is space provided for the translated
124 * string enough?
125 */
126 if (cchWideChar < InStringLength)
127 {
128 SetLastError(ERROR_INSUFFICIENT_BUFFER);
129 return 0;
130 }
131 /*
132 * Raw 8- to 16-bit conversion.
133 */
134 for (cchConverted = 0,
135 r = (PCHAR)lpMultiByteStr,
136 w = (PWCHAR)lpWideCharStr;
137
138 cchConverted < InStringLength;
139
140 r++,
141 w++,
142 cchConverted++)
143 {
144 *w = (WCHAR)(unsigned char) *r;
145 }
146 /*
147 * Return how many characters we
148 * wrote in the output buffer.
149 */
150 //SetLastError(ERROR_SUCCESS); /* according to wine tests this shouldn't be touched on success.
151 return cchConverted;
152 }
153
154
155 /**********************************************************************
156 * NAME EXPORTED
157 * WideCharToMultiByte@32
158 *
159 * Not yet implemented complete (without NLS so far)
160 *
161 * ARGUMENTS
162 * CodePage
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
171 *
172 * dwFlags
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.
178 *
179 * lpWideCharStr
180 * Points to the wide-character string to be converted.
181 *
182 * cchWideChar
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
186 * conversion.
187 * lpMultiByteStr
188 * Points to the buffer to receive the translated string.
189 * cchMultiByte
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.
193 * lpDefaultChar
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.
197 FIXME: ignored
198 * lpUsedDefaultChar
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.
202 *
203 *
204 *
205 * RETURN VALUE
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.
209 *
210 * NOTE
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
214 *
215 * @implemented
216 */
217 int
218 STDCALL
219 WideCharToMultiByte(
220 UINT CodePage,
221 DWORD dwFlags,
222 LPCWSTR lpWideCharStr,
223 int cchWideChar,
224 LPSTR lpMultiByteStr,
225 int cchMultiByte,
226 LPCSTR lpDefaultChar,
227 LPBOOL lpUsedDefaultChar
228 )
229 {
230 int wi, di; // wide counter, dbcs byte count
231
232 /*
233 * Check the parameters.
234 */
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))
244 )
245 /* --- FLAGS --- */
246 || (dwFlags & ~(/*WC_NO_BEST_FIT_CHARS
247 |*/ WC_COMPOSITECHECK
248 | WC_DISCARDNS
249 | WC_SEPCHARS
250 | WC_DEFAULTCHAR
251 )
252 )
253 /* --- INPUT BUFFER --- */
254 || (NULL == lpWideCharStr)
255 )
256 {
257 SetLastError(ERROR_INVALID_PARAMETER);
258 return 0;
259 }
260
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++)
266 // cchWideChar++;
267 for (cchWideChar = 0; lpWideCharStr[cchWideChar] != 0; cchWideChar++) {
268 }
269 cchWideChar++; // length includes the null terminator
270 }
271
272 // user wants to determine needed space
273 if (cchMultiByte == 0)
274 {
275 //SetLastError(ERROR_SUCCESS); /* according to wine tests this shouldn't be touched on success.
276 return cchWideChar; // FIXME: determine correct.
277 }
278 // the lpWideCharStr is cchWideChar characters long.
279 for (wi=0, di=0; wi<cchWideChar && di<cchMultiByte; ++wi, ++di)
280 {
281 // Flag and a not displayable char FIXME
282 /*if( (dwFlags&WC_NO_BEST_FIT_CHARS) && (lpWideCharStr[wi] >127) )
283 {
284 lpMultiByteStr[di]=
285 *lpUsedDefaultChar = TRUE;
286
287 }*/
288 // FIXME
289 // just cut off the upper 9 Bit, since vals>=128 mean LeadByte.
290 lpMultiByteStr[di] = lpWideCharStr[wi] & 0x007F;
291 }
292 // has MultiByte exceeded but Wide is still in the string?
293 if (wi < cchWideChar && di >= cchMultiByte)
294 {
295 SetLastError(ERROR_INSUFFICIENT_BUFFER);
296 return 0;
297 }
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;
302 return di;
303 }
304
305 /* EOF */