1 /*
2 * PROJECT: ReactOS user32.dll
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Text processing functions
5 * COPYRIGHT: Copyright 2001-2004 Casper S. Hornstrup <chorns@users.sourceforge.net>
6 */
7
8 #include <user32.h>
9
10 static WORD
GetC1Type(WCHAR Ch)11 GetC1Type(WCHAR Ch)
12 {
13 WORD CharType;
14
15 if (! GetStringTypeW(CT_CTYPE1, &Ch, 1, &CharType))
16 {
17 return 0;
18 }
19
20 return CharType;
21 }
22
23 /*
24 * @implemented
25 */
26 LPSTR
27 WINAPI
CharLowerA(LPSTR str)28 CharLowerA(LPSTR str)
29 {
30 if (!HIWORD(str))
31 {
32 char ch = LOWORD(str);
33 CharLowerBuffA( &ch, 1 );
34 return (LPSTR)(UINT_PTR)(BYTE)ch;
35 }
36
37 _SEH2_TRY
38 {
39 CharLowerBuffA( str, strlen(str) );
40 }
41 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
42 {
43 SetLastError( ERROR_INVALID_PARAMETER );
44 _SEH2_YIELD(return NULL);
45 }
46 _SEH2_END;
47
48 return str;
49 }
50
51 /*
52 * @implemented
53 */
54 DWORD
55 WINAPI
CharLowerBuffA(LPSTR str,DWORD len)56 CharLowerBuffA(LPSTR str, DWORD len)
57 {
58 DWORD lenW;
59 WCHAR *strW;
60 if (!str) return 0; /* YES */
61
62 lenW = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0);
63 strW = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR));
64 if (strW) {
65 MultiByteToWideChar(CP_ACP, 0, str, len, strW, lenW);
66 CharLowerBuffW(strW, lenW);
67 len = WideCharToMultiByte(CP_ACP, 0, strW, lenW, str, len, NULL, NULL);
68 HeapFree(GetProcessHeap(), 0, strW);
69 return len;
70 }
71 return 0;
72 }
73
74 /*
75 * @implemented
76 */
77 DWORD
78 WINAPI
CharLowerBuffW(LPWSTR str,DWORD len)79 CharLowerBuffW(LPWSTR str, DWORD len)
80 {
81 DWORD ret = len;
82 if (!str) return 0; /* YES */
83 for (; len; len--, str++) *str = towlower(*str);
84 return ret;
85 }
86
87 /*
88 * @implemented
89 */
90 LPWSTR
91 WINAPI
CharLowerW(LPWSTR x)92 CharLowerW(LPWSTR x)
93 {
94 if (HIWORD(x)) return strlwrW(x);
95 else return (LPWSTR)((UINT_PTR)tolowerW(LOWORD(x)));
96 }
97
98 /*
99 * @implemented
100 */
101 LPWSTR
102 WINAPI
CharPrevW(LPCWSTR start,LPCWSTR x)103 CharPrevW(LPCWSTR start, LPCWSTR x)
104 {
105 if (x > start) return (LPWSTR)(x - 1);
106 else return (LPWSTR)x;
107 }
108
109 /*
110 * @implemented
111 */
112 LPSTR
113 WINAPI
CharNextA(LPCSTR ptr)114 CharNextA(LPCSTR ptr)
115 {
116 if (!*ptr) return (LPSTR)ptr;
117 if (IsDBCSLeadByte(ptr[0]) && ptr[1]) return (LPSTR)(ptr + 2);
118 return (LPSTR)(ptr + 1);
119 }
120
121 /*
122 * @implemented
123 */
124 LPSTR
125 WINAPI
CharNextExA(WORD codepage,LPCSTR ptr,DWORD flags)126 CharNextExA(WORD codepage, LPCSTR ptr, DWORD flags)
127 {
128 if (!*ptr) return (LPSTR)ptr;
129 if (IsDBCSLeadByteEx(codepage, ptr[0]) && ptr[1]) return (LPSTR)(ptr + 2);
130 return (LPSTR)(ptr + 1);
131 }
132
133 /*
134 * @implemented
135 */
136 LPWSTR
137 WINAPI
CharNextW(LPCWSTR x)138 CharNextW(LPCWSTR x)
139 {
140 if (*x) x++;
141 return (LPWSTR)x;
142 }
143
144 /*
145 * @implemented
146 */
147 LPSTR
148 WINAPI
CharPrevA(LPCSTR start,LPCSTR ptr)149 CharPrevA(LPCSTR start, LPCSTR ptr)
150 {
151 if (ptr > start)
152 {
153 --ptr;
154 if (gpsi->dwSRVIFlags & SRVINFO_DBCSENABLED)
155 {
156 LPCSTR ch;
157 BOOL dbl = FALSE;
158
159 for (ch = ptr - 1; ch >= start; --ch)
160 {
161 if (!IsDBCSLeadByte(*ch))
162 break;
163
164 dbl = !dbl;
165 }
166 if (dbl) --ptr;
167 }
168 }
169 return (LPSTR)ptr;
170 }
171
172 /*
173 * @implemented
174 */
175 LPSTR
176 WINAPI
CharPrevExA(WORD codepage,LPCSTR start,LPCSTR ptr,DWORD flags)177 CharPrevExA(WORD codepage, LPCSTR start, LPCSTR ptr, DWORD flags)
178 {
179 if (ptr > start)
180 {
181 LPCSTR ch;
182 BOOL dbl = FALSE;
183
184 --ptr;
185 for (ch = ptr - 1; ch >= start; --ch)
186 {
187 if (!IsDBCSLeadByteEx(codepage, *ch))
188 break;
189
190 dbl = !dbl;
191 }
192 if (dbl) --ptr;
193 }
194 return (LPSTR)ptr;
195 }
196
197 /*
198 * @implemented
199 */
200 BOOL
201 WINAPI
CharToOemA(LPCSTR s,LPSTR d)202 CharToOemA(LPCSTR s, LPSTR d)
203 {
204 if (!s || !d) return FALSE;
205 return CharToOemBuffA(s, d, strlen(s) + 1);
206 }
207
208 /*
209 * @implemented
210 */
211 BOOL
212 WINAPI
CharToOemBuffA(LPCSTR s,LPSTR d,DWORD len)213 CharToOemBuffA(LPCSTR s, LPSTR d, DWORD len)
214 {
215 WCHAR* bufW;
216
217 if ( !s || !d ) return FALSE;
218
219 bufW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
220 if (bufW) {
221 MultiByteToWideChar(CP_ACP, 0, s, len, bufW, len);
222 WideCharToMultiByte(CP_OEMCP, 0, bufW, len, d, len, NULL, NULL);
223 HeapFree(GetProcessHeap(), 0, bufW);
224 }
225 return TRUE;
226 }
227
228 /*
229 * @implemented
230 */
231 BOOL
232 WINAPI
CharToOemBuffW(LPCWSTR s,LPSTR d,DWORD len)233 CharToOemBuffW(LPCWSTR s, LPSTR d, DWORD len)
234 {
235 if (!s || !d)
236 return FALSE;
237 WideCharToMultiByte(CP_OEMCP, 0, s, len, d, len, NULL, NULL);
238 return TRUE;
239 }
240
241 /*
242 * @implemented
243 */
244 BOOL
245 WINAPI
CharToOemW(LPCWSTR s,LPSTR d)246 CharToOemW(LPCWSTR s, LPSTR d)
247 {
248 if ( !s || !d ) return FALSE;
249 return CharToOemBuffW(s, d, wcslen(s) + 1);
250 }
251
252 /*
253 * @implemented
254 */
CharUpperA(LPSTR str)255 LPSTR WINAPI CharUpperA(LPSTR str)
256 {
257 if (!HIWORD(str))
258 {
259 char ch = LOWORD(str);
260 CharUpperBuffA( &ch, 1 );
261 return (LPSTR)(UINT_PTR)(BYTE)ch;
262 }
263
264 _SEH2_TRY
265 {
266 CharUpperBuffA( str, strlen(str) );
267 }
268 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
269 {
270 SetLastError( ERROR_INVALID_PARAMETER );
271 _SEH2_YIELD(return NULL);
272 }
273 _SEH2_END;
274
275 return str;
276 }
277
278 /*
279 * @implemented
280 */
281 DWORD
282 WINAPI
CharUpperBuffA(LPSTR str,DWORD len)283 CharUpperBuffA(LPSTR str, DWORD len)
284 {
285 DWORD lenW;
286 WCHAR* strW;
287 if (!str) return 0; /* YES */
288
289 lenW = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0);
290 strW = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR));
291 if (strW) {
292 MultiByteToWideChar(CP_ACP, 0, str, len, strW, lenW);
293 CharUpperBuffW(strW, lenW);
294 len = WideCharToMultiByte(CP_ACP, 0, strW, lenW, str, len, NULL, NULL);
295 HeapFree(GetProcessHeap(), 0, strW);
296 return len;
297 }
298 return 0;
299 }
300
301 /*
302 * @implemented
303 */
304 DWORD
305 WINAPI
CharUpperBuffW(LPWSTR str,DWORD len)306 CharUpperBuffW(LPWSTR str, DWORD len)
307 {
308 DWORD ret = len;
309 if (!str) return 0; /* YES */
310 for (; len; len--, str++) *str = towupper(*str);
311 return ret;
312 }
313
314 /*
315 * @implemented
316 */
317 LPWSTR
318 WINAPI
CharUpperW(LPWSTR x)319 CharUpperW(LPWSTR x)
320 {
321 if (HIWORD(x)) return struprW(x);
322 else return (LPWSTR)((UINT_PTR)toupperW(LOWORD(x)));
323 }
324
325 /*
326 * @implemented
327 */
328 BOOL
329 WINAPI
IsCharAlphaA(CHAR Ch)330 IsCharAlphaA(CHAR Ch)
331 {
332 WCHAR WCh;
333
334 MultiByteToWideChar(CP_ACP, 0, &Ch, 1, &WCh, 1);
335 return IsCharAlphaW(WCh);
336 }
337
338 /*
339 * @implemented
340 */
341 BOOL
342 WINAPI
IsCharAlphaNumericA(CHAR Ch)343 IsCharAlphaNumericA(CHAR Ch)
344 {
345 WCHAR WCh;
346
347 MultiByteToWideChar(CP_ACP, 0, &Ch, 1, &WCh, 1);
348 return IsCharAlphaNumericW(WCh);
349 }
350
351 /*
352 * @implemented
353 */
354 BOOL
355 WINAPI
IsCharAlphaNumericW(WCHAR Ch)356 IsCharAlphaNumericW(WCHAR Ch)
357 {
358 return (GetC1Type(Ch) & (C1_ALPHA|C1_DIGIT)) != 0;
359 }
360
361 /*
362 * @implemented
363 */
364 BOOL
365 WINAPI
IsCharAlphaW(WCHAR Ch)366 IsCharAlphaW(WCHAR Ch)
367 {
368 return (GetC1Type(Ch) & C1_ALPHA) != 0;
369 }
370
371 /*
372 * @implemented
373 */
374 BOOL
375 WINAPI
IsCharLowerA(CHAR Ch)376 IsCharLowerA(CHAR Ch)
377 {
378 WCHAR WCh;
379
380 MultiByteToWideChar(CP_ACP, 0, &Ch, 1, &WCh, 1);
381 return IsCharLowerW(WCh);
382 }
383
384 /*
385 * @implemented
386 */
387 BOOL
388 WINAPI
IsCharLowerW(WCHAR Ch)389 IsCharLowerW(WCHAR Ch)
390 {
391 return (GetC1Type(Ch) & C1_LOWER) != 0;
392 }
393
394 /*
395 * @implemented
396 */
397 BOOL
398 WINAPI
IsCharUpperA(CHAR Ch)399 IsCharUpperA(CHAR Ch)
400 {
401 WCHAR WCh;
402
403 MultiByteToWideChar(CP_ACP, 0, &Ch, 1, &WCh, 1);
404 return IsCharUpperW(WCh);
405 }
406
407 /*
408 * @implemented
409 */
410 BOOL
411 WINAPI
IsCharUpperW(WCHAR Ch)412 IsCharUpperW(WCHAR Ch)
413 {
414 return (GetC1Type(Ch) & C1_UPPER) != 0;
415 }
416
417 /*
418 * @implemented
419 */
420 BOOL
421 WINAPI
OemToCharA(LPCSTR s,LPSTR d)422 OemToCharA(LPCSTR s, LPSTR d)
423 {
424 if ( !s || !d ) return FALSE;
425 return OemToCharBuffA(s, d, strlen(s) + 1);
426 }
427
428 /*
429 * @implemented
430 */
OemToCharBuffA(LPCSTR s,LPSTR d,DWORD len)431 BOOL WINAPI OemToCharBuffA(LPCSTR s, LPSTR d, DWORD len)
432 {
433 WCHAR* bufW;
434
435 if ( !s || !d ) return FALSE;
436
437 bufW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
438 if (bufW) {
439 MultiByteToWideChar(CP_OEMCP, 0, s, len, bufW, len);
440 WideCharToMultiByte(CP_ACP, 0, bufW, len, d, len, NULL, NULL);
441 HeapFree(GetProcessHeap(), 0, bufW);
442 }
443 return TRUE;
444 }
445
446 /*
447 * @implemented
448 */
449 BOOL
450 WINAPI
OemToCharBuffW(LPCSTR s,LPWSTR d,DWORD len)451 OemToCharBuffW(LPCSTR s, LPWSTR d, DWORD len)
452 {
453 if ( !s || !d ) return FALSE;
454 MultiByteToWideChar(CP_OEMCP, 0, s, len, d, len);
455 return TRUE;
456 }
457
458 /*
459 * @implemented
460 */
OemToCharW(LPCSTR s,LPWSTR d)461 BOOL WINAPI OemToCharW(LPCSTR s, LPWSTR d)
462 {
463 if ( !s || !d ) return FALSE;
464 return OemToCharBuffW(s, d, strlen(s) + 1);
465 }
466
467 /* EOF */
468