@@ -20,7 +20,7 @@ internal unsafe CompareInfo(CultureInfo culture)
20
20
m_sortNameAsUtf8 = System . Text . Encoding . UTF8 . GetBytes ( m_sortName ) ;
21
21
}
22
22
23
- internal static int IndexOfOrdinal ( string source , string value , int startIndex , int count , bool ignoreCase )
23
+ internal static unsafe int IndexOfOrdinal ( string source , string value , int startIndex , int count , bool ignoreCase )
24
24
{
25
25
Contract . Assert ( source != null ) ;
26
26
Contract . Assert ( value != null ) ;
@@ -30,33 +30,41 @@ internal static int IndexOfOrdinal(string source, string value, int startIndex,
30
30
return startIndex ;
31
31
}
32
32
33
- // TODO (dotnet/corefx#3468): Move this into the shim so we don't have to do the ToUpper or call substring.
33
+ if ( count < value . Length )
34
+ {
35
+ return - 1 ;
36
+ }
34
37
35
38
if ( ignoreCase )
36
39
{
37
- source = source . ToUpper ( CultureInfo . InvariantCulture ) ;
38
- value = value . ToUpper ( CultureInfo . InvariantCulture ) ;
40
+ fixed ( char * pSource = source )
41
+ {
42
+ int index = Interop . GlobalizationInterop . IndexOfOrdinalIgnoreCase ( value , value . Length , pSource + startIndex , count , findLast : false ) ;
43
+ return index != - 1 ?
44
+ startIndex + index :
45
+ - 1 ;
46
+ }
39
47
}
40
48
41
- source = source . Substring ( startIndex , count ) ;
42
-
43
- for ( int i = 0 ; i + value . Length <= source . Length ; i ++ )
49
+ int endIndex = startIndex + ( count - value . Length ) ;
50
+ for ( int i = startIndex ; i <= endIndex ; i ++ )
44
51
{
45
- for ( int j = 0 ; j < value . Length ; j ++ ) {
46
- if ( source [ i + j ] != value [ j ] ) {
47
- break ;
48
- }
52
+ int valueIndex , sourceIndex ;
53
+
54
+ for ( valueIndex = 0 , sourceIndex = i ;
55
+ valueIndex < value . Length && source [ sourceIndex ] == value [ valueIndex ] ;
56
+ valueIndex ++ , sourceIndex ++ ) ;
49
57
50
- if ( j == value . Length - 1 ) {
51
- return i + startIndex ;
52
- }
58
+ if ( valueIndex == value . Length )
59
+ {
60
+ return i ;
53
61
}
54
62
}
55
63
56
64
return - 1 ;
57
65
}
58
66
59
- internal static int LastIndexOfOrdinal ( string source , string value , int startIndex , int count , bool ignoreCase )
67
+ internal static unsafe int LastIndexOfOrdinal ( string source , string value , int startIndex , int count , bool ignoreCase )
60
68
{
61
69
Contract . Assert ( source != null ) ;
62
70
Contract . Assert ( value != null ) ;
@@ -66,27 +74,41 @@ internal static int LastIndexOfOrdinal(string source, string value, int startInd
66
74
return startIndex ;
67
75
}
68
76
69
- // TODO (dotnet/corefx#3468): Move this into the shim so we don't have to do the ToUpper or call substring.
77
+ if ( count < value . Length )
78
+ {
79
+ return - 1 ;
80
+ }
81
+
82
+ // startIndex is the index into source where we start search backwards from.
83
+ // leftStartIndex is the index into source of the start of the string that is
84
+ // count characters away from startIndex.
85
+ int leftStartIndex = startIndex - count + 1 ;
70
86
71
87
if ( ignoreCase )
72
88
{
73
- source = source . ToUpper ( CultureInfo . InvariantCulture ) ;
74
- value = value . ToUpper ( CultureInfo . InvariantCulture ) ;
89
+ fixed ( char * pSource = source )
90
+ {
91
+ int lastIndex = Interop . GlobalizationInterop . IndexOfOrdinalIgnoreCase ( value , value . Length , pSource + leftStartIndex , count , findLast : true ) ;
92
+ return lastIndex != - 1 ?
93
+ leftStartIndex + lastIndex :
94
+ - 1 ;
95
+ }
75
96
}
76
97
77
- source = source . Substring ( startIndex - count + 1 , count ) ;
98
+ for ( int i = startIndex - value . Length + 1 ; i >= leftStartIndex ; i -- )
99
+ {
100
+ int valueIndex , sourceIndex ;
78
101
79
- int last = - 1 ;
102
+ for ( valueIndex = 0 , sourceIndex = i ;
103
+ valueIndex < value . Length && source [ sourceIndex ] == value [ valueIndex ] ;
104
+ valueIndex ++ , sourceIndex ++ ) ;
80
105
81
- int cur = 0 ;
82
- while ( ( cur = IndexOfOrdinal ( source , value , last + 1 , source . Length - last - 1 , false ) ) != - 1 )
83
- {
84
- last = cur ;
106
+ if ( valueIndex == value . Length ) {
107
+ return i ;
108
+ }
85
109
}
86
110
87
- return last >= 0 ?
88
- last + startIndex - count + 1 :
89
- - 1 ;
111
+ return - 1 ;
90
112
}
91
113
92
114
private unsafe int GetHashCodeOfStringCore ( string source , CompareOptions options )
@@ -138,9 +160,9 @@ private unsafe int IndexOfCore(string source, string target, int startIndex, int
138
160
139
161
fixed ( char * pSource = source )
140
162
{
141
- int lastIndex = Interop . GlobalizationInterop . IndexOf ( m_sortNameAsUtf8 , target , pSource + startIndex , count , options ) ;
163
+ int index = Interop . GlobalizationInterop . IndexOf ( m_sortNameAsUtf8 , target , pSource + startIndex , count , options ) ;
142
164
143
- return lastIndex != - 1 ? lastIndex + startIndex : - 1 ;
165
+ return index != - 1 ? index + startIndex : - 1 ;
144
166
}
145
167
}
146
168
0 commit comments