Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 91f0f8b

Browse files
committed
Update IndexOfOrdinalIgnoreCase to use full code units
1 parent 80800eb commit 91f0f8b

File tree

3 files changed

+60
-68
lines changed

3 files changed

+60
-68
lines changed

src/corefx/System.Globalization.Native/collation.cpp

Lines changed: 57 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -129,78 +129,73 @@ extern "C" int32_t LastIndexOf(
129129
Static Function:
130130
AreEqualOrdinalIgnoreCase
131131
*/
132-
static bool AreEqualOrdinalIgnoreCase(UChar one, UChar two)
132+
static bool AreEqualOrdinalIgnoreCase(UChar32 one, UChar32 two)
133133
{
134-
// Return whether the two characters are identical or would be identical if they were upper-cased.
135-
136-
if (one == two)
137-
{
138-
return true;
139-
}
140-
141-
if (one == 0x0131 || two == 0x0131)
142-
{
143-
// On Windows with InvariantCulture, the LATIN SMALL LETTER DOTLESS I (U+0131)
144-
// capitalizes to itself, whereas with ICU it capitalizes to LATIN CAPITAL LETTER I (U+0049).
145-
// We special case it to match the Windows invariant behavior.
146-
return false;
147-
}
148-
149-
return u_toupper(one) == u_toupper(two);
134+
// Return whether the two characters are identical or would be identical if they were upper-cased.
135+
136+
if (one == two)
137+
{
138+
return true;
139+
}
140+
141+
if (one == 0x0131 || two == 0x0131)
142+
{
143+
// On Windows with InvariantCulture, the LATIN SMALL LETTER DOTLESS I (U+0131)
144+
// capitalizes to itself, whereas with ICU it capitalizes to LATIN CAPITAL LETTER I (U+0049).
145+
// We special case it to match the Windows invariant behavior.
146+
return false;
147+
}
148+
149+
return u_toupper(one) == u_toupper(two);
150150
}
151151

152152
/*
153153
Function:
154154
IndexOfOrdinalIgnoreCase
155155
*/
156156
extern "C" int32_t
157-
IndexOfOrdinalIgnoreCase(const UChar* lpTarget, int32_t cwTargetLength, const UChar* lpSource, int32_t cwSourceLength)
157+
IndexOfOrdinalIgnoreCase(
158+
const UChar* lpTarget, int32_t cwTargetLength,
159+
const UChar* lpSource, int32_t cwSourceLength,
160+
int32_t findLast)
158161
{
159-
int32_t endIndex = cwSourceLength - cwTargetLength;
160-
assert(endIndex >= 0);
161-
162-
for (int32_t i = 0; i <= endIndex; i++)
163-
{
164-
int32_t targetIdx = 0;
165-
for (int32_t srcIdx = i; targetIdx < cwTargetLength; srcIdx++, targetIdx++) {
166-
if (!AreEqualOrdinalIgnoreCase(lpSource[srcIdx], lpTarget[targetIdx])) {
167-
break;
168-
}
169-
}
170-
171-
if (targetIdx == cwTargetLength) {
172-
return i;
173-
}
174-
}
175-
176-
return -1;
177-
}
162+
int32_t result = -1;
178163

179-
/*
180-
Function:
181-
LastIndexOfOrdinalIgnoreCase
182-
*/
183-
extern "C" int32_t
184-
LastIndexOfOrdinalIgnoreCase(const UChar* lpTarget, int32_t cwTargetLength, const UChar* lpSource, int32_t cwSourceLength)
185-
{
186-
int32_t endIndex = cwSourceLength - cwTargetLength;
187-
assert(endIndex >= 0);
188-
189-
for (int32_t i = endIndex; i >= 0; i--)
190-
{
191-
int32_t targetIdx = 0;
192-
for (int32_t srcIdx = i; targetIdx < cwTargetLength; srcIdx++, targetIdx++) {
193-
if (!AreEqualOrdinalIgnoreCase(lpSource[srcIdx], lpTarget[targetIdx])) {
194-
break;
195-
}
196-
}
197-
198-
if (targetIdx == cwTargetLength) {
199-
return i;
200-
}
201-
}
202-
203-
return -1;
164+
int32_t endIndex = cwSourceLength - cwTargetLength;
165+
assert(endIndex >= 0);
166+
167+
int32_t i = 0;
168+
while (i <= endIndex)
169+
{
170+
int32_t srcIdx = i, trgIdx = 0;
171+
const UChar *src = lpSource, *trg = lpTarget;
172+
UChar32 srcCodepoint, trgCodepoint;
173+
174+
bool match = true;
175+
while (trgIdx < cwTargetLength)
176+
{
177+
U16_NEXT(src, srcIdx, cwSourceLength, srcCodepoint);
178+
U16_NEXT(trg, trgIdx, cwTargetLength, trgCodepoint);
179+
if (!AreEqualOrdinalIgnoreCase(srcCodepoint, trgCodepoint))
180+
{
181+
match = false;
182+
break;
183+
}
184+
}
185+
186+
if (match)
187+
{
188+
result = i;
189+
if (!findLast)
190+
{
191+
break;
192+
}
193+
}
194+
195+
U16_FWD_1(lpSource, i, cwSourceLength);
196+
}
197+
198+
return result;
204199
}
205200

206201
/*

src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Collation.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,7 @@ internal static partial class GlobalizationInterop
1919
internal unsafe static extern int LastIndexOf(byte[] localeName, string target, char* pSource, int cwSourceLength, CompareOptions options);
2020

2121
[DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode)]
22-
internal unsafe static extern int IndexOfOrdinalIgnoreCase(string target, int cwTargetLength, char* pSource, int cwSourceLength);
23-
24-
[DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode)]
25-
internal unsafe static extern int LastIndexOfOrdinalIgnoreCase(string target, int cwTargetLength, char* pSource, int cwSourceLength);
22+
internal unsafe static extern int IndexOfOrdinalIgnoreCase(string target, int cwTargetLength, char* pSource, int cwSourceLength, bool findLast);
2623

2724
[DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode)]
2825
[return: MarshalAs(UnmanagedType.Bool)]

src/mscorlib/corefx/System/Globalization/CompareInfo.Unix.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ internal static unsafe int IndexOfOrdinal(string source, string value, int start
3939
{
4040
fixed (char* pSource = source)
4141
{
42-
int index = Interop.GlobalizationInterop.IndexOfOrdinalIgnoreCase(value, value.Length, pSource + startIndex, count);
42+
int index = Interop.GlobalizationInterop.IndexOfOrdinalIgnoreCase(value, value.Length, pSource + startIndex, count, findLast: false);
4343
return index != -1 ?
4444
startIndex + index :
4545
-1;
@@ -88,7 +88,7 @@ internal static unsafe int LastIndexOfOrdinal(string source, string value, int s
8888
{
8989
fixed (char* pSource = source)
9090
{
91-
int lastIndex = Interop.GlobalizationInterop.LastIndexOfOrdinalIgnoreCase(value, value.Length, pSource + leftStartIndex, count);
91+
int lastIndex = Interop.GlobalizationInterop.IndexOfOrdinalIgnoreCase(value, value.Length, pSource + leftStartIndex, count, findLast: true);
9292
return lastIndex != -1 ?
9393
leftStartIndex + lastIndex :
9494
-1;

0 commit comments

Comments
 (0)