xref: /reactos/win32ss/user/user32/windows/text.c (revision 1734f297)
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
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
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
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
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
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
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
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
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
138 CharNextW(LPCWSTR x)
139 {
140     if (*x) x++;
141     return (LPWSTR)x;
142 }
143 
144 /*
145  * @implemented
146  */
147 LPSTR
148 WINAPI
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
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
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
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
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
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  */
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
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
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
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
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
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
356 IsCharAlphaNumericW(WCHAR Ch)
357 {
358     return (GetC1Type(Ch) & (C1_ALPHA|C1_DIGIT)) != 0;
359 }
360 
361 /*
362  * @implemented
363  */
364 BOOL
365 WINAPI
366 IsCharAlphaW(WCHAR Ch)
367 {
368     return (GetC1Type(Ch) & C1_ALPHA) != 0;
369 }
370 
371 /*
372  * @implemented
373  */
374 BOOL
375 WINAPI
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
389 IsCharLowerW(WCHAR Ch)
390 {
391     return (GetC1Type(Ch) & C1_LOWER) != 0;
392 }
393 
394 /*
395  * @implemented
396  */
397 BOOL
398 WINAPI
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
412 IsCharUpperW(WCHAR Ch)
413 {
414     return (GetC1Type(Ch) & C1_UPPER) != 0;
415 }
416 
417 /*
418  * @implemented
419  */
420 BOOL
421 WINAPI
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  */
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
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  */
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