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