1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | // ============================================================ |
5 | // |
6 | // FusionHelpers.cpp |
7 | // |
8 | // Implements various helper functions |
9 | // |
10 | // ============================================================ |
11 | |
12 | #include "fusionhelpers.hpp" |
13 | |
14 | #include "shlwapi.h" |
15 | |
16 | #define IS_UPPER_A_TO_Z(x) (((x) >= L'A') && ((x) <= L'Z')) |
17 | #define IS_LOWER_A_TO_Z(x) (((x) >= L'a') && ((x) <= L'z')) |
18 | #define IS_0_TO_9(x) (((x) >= L'0') && ((x) <= L'9')) |
19 | #define CAN_SIMPLE_UPCASE(x) (((x)&~0x7f) == 0) |
20 | #define SIMPLE_UPCASE(x) (IS_LOWER_A_TO_Z(x) ? ((x) - L'a' + L'A') : (x)) |
21 | #define CAN_SIMPLE_LOWERCASE(x) (((x)&~0x7f) == 0) |
22 | #define SIMPLE_LOWERCASE(x) (IS_UPPER_A_TO_Z(x) ? ((x) - L'A' + L'a') : (x)) |
23 | |
24 | // --------------------------------------------------------------------------- |
25 | // Private Helpers |
26 | // --------------------------------------------------------------------------- |
27 | namespace |
28 | { |
29 | WCHAR FusionMapChar(WCHAR wc) |
30 | { |
31 | WCHAR wTmp; |
32 | |
33 | #ifndef FEATURE_PAL |
34 | |
35 | #ifdef FEATURE_USE_LCID |
36 | int iRet = WszLCMapString(g_lcid, LCMAP_UPPERCASE, &wc, 1, &wTmp, 1); |
37 | #else |
38 | int iRet = LCMapStringEx(g_lcid, LCMAP_UPPERCASE, &wc, 1, &wTmp, 1, NULL, NULL, 0); |
39 | #endif |
40 | if (!iRet) { |
41 | _ASSERTE(!"LCMapString failed!" ); |
42 | iRet = GetLastError(); |
43 | wTmp = wc; |
44 | } |
45 | #else // !FEATURE_PAL |
46 | // For PAL, no locale specific processing is done |
47 | wTmp = toupper(wc); |
48 | #endif // !FEATURE_PAL |
49 | |
50 | return wTmp; |
51 | } |
52 | }; |
53 | |
54 | // --------------------------------------------------------------------------- |
55 | // FusionCompareStringN |
56 | // --------------------------------------------------------------------------- |
57 | // if nChar < 0, compare the whole string |
58 | int FusionCompareStringN(LPCWSTR pwz1, LPCWSTR pwz2, int nChar, BOOL bCaseSensitive) |
59 | { |
60 | int iRet = 0; |
61 | int nCount = 0; |
62 | WCHAR ch1; |
63 | WCHAR ch2; |
64 | _ASSERTE(pwz1 && pwz2); |
65 | |
66 | // same point always return equal. |
67 | if (pwz1 == pwz2) { |
68 | return 0; |
69 | } |
70 | |
71 | // Case sensitive comparison |
72 | if (bCaseSensitive) { |
73 | if (nChar >= 0) |
74 | return wcsncmp(pwz1, pwz2, nChar); |
75 | else |
76 | return wcscmp(pwz1, pwz2); |
77 | } |
78 | |
79 | for (;;) { |
80 | ch1 = *pwz1++; |
81 | ch2 = *pwz2++; |
82 | |
83 | if (ch1 == L'\0' || ch2 == L'\0') { |
84 | break; |
85 | } |
86 | |
87 | // We use OS mapping table |
88 | ch1 = (CAN_SIMPLE_UPCASE(ch1)) ? (SIMPLE_UPCASE(ch1)) : (FusionMapChar(ch1)); |
89 | ch2 = (CAN_SIMPLE_UPCASE(ch2)) ? (SIMPLE_UPCASE(ch2)) : (FusionMapChar(ch2)); |
90 | nCount++; |
91 | |
92 | if (ch1 != ch2 || (nChar >= 0 && nCount >= nChar)) { |
93 | break; |
94 | } |
95 | } |
96 | |
97 | if (ch1 > ch2) { |
98 | iRet = 1; |
99 | } |
100 | else if (ch1 < ch2) { |
101 | iRet = -1; |
102 | } |
103 | |
104 | return iRet; |
105 | } |
106 | |
107 | // --------------------------------------------------------------------------- |
108 | // FusionCompareStringI |
109 | // --------------------------------------------------------------------------- |
110 | int FusionCompareStringI(LPCWSTR pwz1, LPCWSTR pwz2) |
111 | { |
112 | return FusionCompareStringN(pwz1, pwz2, -1, FALSE); |
113 | } |
114 | |