xref: /reactos/win32ss/user/user32/windows/text.c (revision bcbfcd22)
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     while (*start && (start < ptr))
152     {
153         LPCSTR next = CharNextA(start);
154         if (next >= ptr) break;
155         start = next;
156     }
157     return (LPSTR)start;
158 }
159 
160 /*
161  * @implemented
162  */
163 LPSTR
164 WINAPI
165 CharPrevExA(WORD codepage, LPCSTR start, LPCSTR ptr, DWORD flags)
166 {
167     while (*start && (start < ptr))
168     {
169         LPCSTR next = CharNextExA(codepage, start, flags);
170         if (next >= ptr) break;
171         start = next;
172     }
173     return (LPSTR)start;
174 }
175 
176 /*
177  * @implemented
178  */
179 BOOL
180 WINAPI
181 CharToOemA(LPCSTR s, LPSTR d)
182 {
183     if (!s || !d) return FALSE;
184     return CharToOemBuffA(s, d, strlen(s) + 1);
185 }
186 
187 /*
188  * @implemented
189  */
190 BOOL
191 WINAPI
192 CharToOemBuffA(LPCSTR s, LPSTR d, DWORD len)
193 {
194     WCHAR* bufW;
195 
196     if ( !s || !d ) return FALSE;
197 
198     bufW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
199     if (bufW) {
200 	    MultiByteToWideChar(CP_ACP, 0, s, len, bufW, len);
201         WideCharToMultiByte(CP_OEMCP, 0, bufW, len, d, len, NULL, NULL);
202 	    HeapFree(GetProcessHeap(), 0, bufW);
203     }
204     return TRUE;
205 }
206 
207 /*
208  * @implemented
209  */
210 BOOL
211 WINAPI
212 CharToOemBuffW(LPCWSTR s, LPSTR d, DWORD len)
213 {
214     if (!s || !d)
215         return FALSE;
216     WideCharToMultiByte(CP_OEMCP, 0, s, len, d, len, NULL, NULL);
217     return TRUE;
218 }
219 
220 /*
221  * @implemented
222  */
223 BOOL
224 WINAPI
225 CharToOemW(LPCWSTR s, LPSTR d)
226 {
227     if ( !s || !d ) return FALSE;
228     return CharToOemBuffW(s, d, wcslen(s) + 1);
229 }
230 
231 /*
232  * @implemented
233  */
234 LPSTR WINAPI CharUpperA(LPSTR str)
235 {
236     if (!HIWORD(str))
237     {
238         char ch = LOWORD(str);
239         CharUpperBuffA( &ch, 1 );
240         return (LPSTR)(UINT_PTR)(BYTE)ch;
241     }
242 
243     _SEH2_TRY
244     {
245         CharUpperBuffA( str, strlen(str) );
246     }
247     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
248     {
249         SetLastError( ERROR_INVALID_PARAMETER );
250         _SEH2_YIELD(return NULL);
251     }
252     _SEH2_END;
253 
254     return str;
255 }
256 
257 /*
258  * @implemented
259  */
260 DWORD
261 WINAPI
262 CharUpperBuffA(LPSTR str, DWORD len)
263 {
264     DWORD lenW;
265     WCHAR* strW;
266     if (!str) return 0; /* YES */
267 
268     lenW = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0);
269     strW = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR));
270     if (strW) {
271         MultiByteToWideChar(CP_ACP, 0, str, len, strW, lenW);
272         CharUpperBuffW(strW, lenW);
273         len = WideCharToMultiByte(CP_ACP, 0, strW, lenW, str, len, NULL, NULL);
274         HeapFree(GetProcessHeap(), 0, strW);
275         return len;
276     }
277     return 0;
278 }
279 
280 /*
281  * @implemented
282  */
283 DWORD
284 WINAPI
285 CharUpperBuffW(LPWSTR str, DWORD len)
286 {
287     DWORD ret = len;
288     if (!str) return 0; /* YES */
289     for (; len; len--, str++) *str = towupper(*str);
290     return ret;
291 }
292 
293 /*
294  * @implemented
295  */
296 LPWSTR
297 WINAPI
298 CharUpperW(LPWSTR x)
299 {
300     if (HIWORD(x)) return struprW(x);
301     else return (LPWSTR)((UINT_PTR)toupperW(LOWORD(x)));
302 }
303 
304 /*
305  * @implemented
306  */
307 BOOL
308 WINAPI
309 IsCharAlphaA(CHAR Ch)
310 {
311     WCHAR WCh;
312 
313     MultiByteToWideChar(CP_ACP, 0, &Ch, 1, &WCh, 1);
314     return IsCharAlphaW(WCh);
315 }
316 
317 /*
318  * @implemented
319  */
320 BOOL
321 WINAPI
322 IsCharAlphaNumericA(CHAR Ch)
323 {
324     WCHAR WCh;
325 
326     MultiByteToWideChar(CP_ACP, 0, &Ch, 1, &WCh, 1);
327     return IsCharAlphaNumericW(WCh);
328 }
329 
330 /*
331  * @implemented
332  */
333 BOOL
334 WINAPI
335 IsCharAlphaNumericW(WCHAR Ch)
336 {
337     return (GetC1Type(Ch) & (C1_ALPHA|C1_DIGIT)) != 0;
338 }
339 
340 /*
341  * @implemented
342  */
343 BOOL
344 WINAPI
345 IsCharAlphaW(WCHAR Ch)
346 {
347     return (GetC1Type(Ch) & C1_ALPHA) != 0;
348 }
349 
350 /*
351  * @implemented
352  */
353 BOOL
354 WINAPI
355 IsCharLowerA(CHAR Ch)
356 {
357     WCHAR WCh;
358 
359     MultiByteToWideChar(CP_ACP, 0, &Ch, 1, &WCh, 1);
360     return IsCharLowerW(WCh);
361 }
362 
363 /*
364  * @implemented
365  */
366 BOOL
367 WINAPI
368 IsCharLowerW(WCHAR Ch)
369 {
370     return (GetC1Type(Ch) & C1_LOWER) != 0;
371 }
372 
373 /*
374  * @implemented
375  */
376 BOOL
377 WINAPI
378 IsCharUpperA(CHAR Ch)
379 {
380     WCHAR WCh;
381 
382     MultiByteToWideChar(CP_ACP, 0, &Ch, 1, &WCh, 1);
383     return IsCharUpperW(WCh);
384 }
385 
386 /*
387  * @implemented
388  */
389 BOOL
390 WINAPI
391 IsCharUpperW(WCHAR Ch)
392 {
393     return (GetC1Type(Ch) & C1_UPPER) != 0;
394 }
395 
396 /*
397  * @implemented
398  */
399 BOOL
400 WINAPI
401 OemToCharA(LPCSTR s, LPSTR d)
402 {
403     if ( !s || !d ) return FALSE;
404     return OemToCharBuffA(s, d, strlen(s) + 1);
405 }
406 
407 /*
408  * @implemented
409  */
410 BOOL WINAPI OemToCharBuffA(LPCSTR s, LPSTR d, DWORD len)
411 {
412     WCHAR* bufW;
413 
414     if ( !s || !d ) return FALSE;
415 
416     bufW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
417     if (bufW) {
418         MultiByteToWideChar(CP_OEMCP, 0, s, len, bufW, len);
419 	    WideCharToMultiByte(CP_ACP, 0, bufW, len, d, len, NULL, NULL);
420 	    HeapFree(GetProcessHeap(), 0, bufW);
421     }
422     return TRUE;
423 }
424 
425 /*
426  * @implemented
427  */
428 BOOL
429 WINAPI
430 OemToCharBuffW(LPCSTR s, LPWSTR d, DWORD len)
431 {
432     if ( !s || !d ) return FALSE;
433     MultiByteToWideChar(CP_OEMCP, 0, s, len, d, len);
434     return TRUE;
435 }
436 
437 /*
438  * @implemented
439  */
440 BOOL WINAPI OemToCharW(LPCSTR s, LPWSTR d)
441 {
442     if ( !s || !d ) return FALSE;
443     return OemToCharBuffW(s, d, strlen(s) + 1);
444 }
445 
446 /* EOF */
447