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