Author: atsushi
Date: 2006-12-25 04:45:38 -0500 (Mon, 25 Dec 2006)
New Revision: 70037
Modified:
trunk/mcs/class/corlib/Mono.Globalization.Unicode/ChangeLog
trunk/mcs/class/corlib/Mono.Globalization.Unicode/SimpleCollator.cs
trunk/mcs/class/corlib/System.Globalization/ChangeLog
trunk/mcs/class/corlib/System.Globalization/CompareInfo.cs
trunk/mcs/class/corlib/Test/System.Globalization/ChangeLog
trunk/mcs/class/corlib/Test/System.Globalization/CompareInfoTest.cs
Log:
2006-12-25 Atsushi Enomoto <[EMAIL PROTECTED]>
* SimpleCollator.cs : added IndexOf() implementation for Ordinal
and OrdinalIgnoreCase, though Ordinal version is not used (since
it is slower than icall).
* CompareInfo.cs : for OrdinalIgnoreCase, IndexOf() and LastIndexOf()
will use managed version (icalls for them are case sensitive).
Removed MonoTODOs.
* CompareInfoTest.cs : added tests for OrdinalIgnoreCase versions
of IndexOf() and LastIndexOf(). Added Ordinal LastIndexOf() tests.
Modified: trunk/mcs/class/corlib/Mono.Globalization.Unicode/ChangeLog
===================================================================
--- trunk/mcs/class/corlib/Mono.Globalization.Unicode/ChangeLog 2006-12-25
05:09:15 UTC (rev 70036)
+++ trunk/mcs/class/corlib/Mono.Globalization.Unicode/ChangeLog 2006-12-25
09:45:38 UTC (rev 70037)
@@ -1,3 +1,9 @@
+2006-12-25 Atsushi Enomoto <[EMAIL PROTECTED]>
+
+ * SimpleCollator.cs : added IndexOf() implementation for Ordinal
+ and OrdinalIgnoreCase, though Ordinal version is not used (since
+ it is slower than icall).
+
2006-05-30 Miguel de Icaza <[EMAIL PROTECTED]>
* MSCompatUnicodeTable.cs: Remove the fixed loading and compute it
Modified: trunk/mcs/class/corlib/Mono.Globalization.Unicode/SimpleCollator.cs
===================================================================
--- trunk/mcs/class/corlib/Mono.Globalization.Unicode/SimpleCollator.cs
2006-12-25 05:09:15 UTC (rev 70036)
+++ trunk/mcs/class/corlib/Mono.Globalization.Unicode/SimpleCollator.cs
2006-12-25 09:45:38 UTC (rev 70037)
@@ -1390,6 +1390,8 @@
#region IndexOf() / LastIndexOf()
+ // string
+
public int IndexOf (string s, string target, CompareOptions opt)
{
return IndexOf (s, target, 0, s.Length, opt);
@@ -1440,6 +1442,12 @@
public unsafe int IndexOf (string s, string target, int start,
int length, CompareOptions opt)
{
+ if (opt == CompareOptions.Ordinal)
+ return IndexOfOrdinal (s, target, start,
length);
+#if NET_2_0
+ if (opt == CompareOptions.OrdinalIgnoreCase)
+ return IndexOfOrdinalIgnoreCase (s, target,
start, length);
+#endif
if (opt == CompareOptions.None) {
bool testWasUnable;
int ret = QuickIndexOf (s, target, start,
length, out testWasUnable);
@@ -1463,6 +1471,57 @@
targetSortKey, ref ctx);
}
+ // note that it wouldn't be used since ordinal IndexOf()
+ // should be directed to icall.
+ int IndexOfOrdinal (string s, string target, int start, int
length)
+ {
+ if (target.Length == 0)
+ return 0;
+ else if (target.Length > length)
+ return -1;
+
+ int end = start + length - target.Length + 1;
+ for (int i = start; i < end; i++) {
+ bool no = false;
+ for (int j = 0; j < target.Length; j++) {
+ if (s [i + j] != target [j]) {
+ no = true;
+ break;
+ }
+ }
+ if (no)
+ continue;
+ return i;
+ }
+ return -1;
+ }
+
+ int IndexOfOrdinalIgnoreCase (string s, string target, int
start, int length)
+ {
+ if (target.Length == 0)
+ return 0;
+ else if (target.Length > length)
+ return -1;
+
+ int end = start + length - target.Length + 1;
+ for (int i = start; i < end; i++) {
+ bool no = false;
+ for (int j = 0; j < target.Length; j++) {
+ // I think almost all text has more
lower letters than upper ones. Thus with this invariant comparison ToLower()
should be faster since it costs less operations.
+ if (textInfo.ToLower (s [i + j]) !=
textInfo.ToLower (target [j])) {
+ no = true;
+ break;
+ }
+ }
+ if (no)
+ continue;
+ return i;
+ }
+ return -1;
+ }
+
+ // char
+
public int IndexOf (string s, char target, CompareOptions opt)
{
return IndexOf (s, target, 0, s.Length, opt);
@@ -1470,6 +1529,12 @@
public unsafe int IndexOf (string s, char target, int start,
int length, CompareOptions opt)
{
+ if (opt == CompareOptions.Ordinal)
+ return IndexOfOrdinal (s, target, start,
length);
+#if NET_2_0
+ if (opt == CompareOptions.OrdinalIgnoreCase)
+ return IndexOfOrdinalIgnoreCase (s, target,
start, length);
+#endif
byte* alwaysMatchFlags = stackalloc byte [16];
byte* neverMatchFlags = stackalloc byte [16];
byte* targetSortKey = stackalloc byte [4];
@@ -1507,6 +1572,27 @@
}
}
+ // note that it wouldn't be used since ordinal IndexOf()
+ // should be directed to icall.
+ int IndexOfOrdinal (string s, char target, int start, int
length)
+ {
+ int end = start + length;
+ for (int i = start; i < end; i++)
+ if (s [i] == target)
+ return i;
+ return -1;
+ }
+
+ int IndexOfOrdinalIgnoreCase (string s, char target, int start,
int length)
+ {
+ int end = start + length;
+ target = textInfo.ToLower (target);
+ for (int i = start; i < end; i++)
+ if (textInfo.ToLower (s [i]) == target)
+ return i;
+ return -1;
+ }
+
// Searches target byte[] keydata
unsafe int IndexOfSortKey (string s, int start, int length,
byte* sortkey, char target, int ti, bool noLv4, ref Context ctx)
{
@@ -1586,10 +1672,13 @@
}
//
- // There are the same number of IndexOf() related methods,
- // with the same functionalities for each.
+ // There are the same number of LastIndexOf() methods as
+ // IndexOf() related methods, with the same functionalities
+ // for each.
//
+ // string
+
public int LastIndexOf (string s, string target, CompareOptions
opt)
{
return LastIndexOf (s, target, s.Length - 1, s.Length,
opt);
@@ -1597,6 +1686,12 @@
public unsafe int LastIndexOf (string s, string target, int
start, int length, CompareOptions opt)
{
+ if (opt == CompareOptions.Ordinal)
+ return LastIndexOfOrdinal (s, target, start,
length);
+#if NET_2_0
+ if (opt == CompareOptions.OrdinalIgnoreCase)
+ return LastIndexOfOrdinalIgnoreCase (s, target,
start, length);
+#endif
byte* alwaysMatchFlags = stackalloc byte [16];
byte* neverMatchFlags = stackalloc byte [16];
byte* targetSortKey = stackalloc byte [4];
@@ -1613,6 +1708,64 @@
targetSortKey, ref ctx);
}
+ int LastIndexOfOrdinal (string s, string target, int start, int
length)
+ {
+ if (target.Length == 0)
+ return 0;
+ if (s.Length < target.Length || target.Length > length)
+ return -1;
+ int end = start - length + target.Length -1;
+ char tail = target [target.Length - 1];
+ for (int i = start; i > end;) {
+ if (s [i] != tail) {
+ i--;
+ continue;
+ }
+ int x = i - target.Length + 1;
+ i--;
+ bool mismatch = false;
+ for (int j = target.Length - 2; j >= 0; j--)
+ if (s [x + j] != target [j]) {
+ mismatch = true;
+ break;
+ }
+ if (mismatch)
+ continue;
+ return x;
+ }
+ return -1;
+ }
+
+ int LastIndexOfOrdinalIgnoreCase (string s, string target, int
start, int length)
+ {
+ if (target.Length == 0)
+ return 0;
+ if (s.Length < length || target.Length > length)
+ return -1;
+ int end = start - length + target.Length - 1;
+ char tail = textInfo.ToLower (target [target.Length -
1]);
+ for (int i = start; i > end;) {
+ if (textInfo.ToLower (s [i]) != tail) {
+ i--;
+ continue;
+ }
+ int x = i - target.Length + 1;
+ i--;
+ bool mismatch = false;
+ for (int j = target.Length - 2; j >= 0; j--)
+ if (textInfo.ToLower (s [x + j]) !=
textInfo.ToLower (target [j])) {
+ mismatch = true;
+ break;
+ }
+ if (mismatch)
+ continue;
+ return x;
+ }
+ return -1;
+ }
+
+ // char
+
public int LastIndexOf (string s, char target, CompareOptions
opt)
{
return LastIndexOf (s, target, s.Length - 1, s.Length,
opt);
@@ -1620,6 +1773,12 @@
public unsafe int LastIndexOf (string s, char target, int
start, int length, CompareOptions opt)
{
+ if (opt == CompareOptions.Ordinal)
+ return LastIndexOfOrdinal (s, target, start,
length);
+#if NET_2_0
+ if (opt == CompareOptions.OrdinalIgnoreCase)
+ return LastIndexOfOrdinalIgnoreCase (s, target,
start, length);
+#endif
byte* alwaysMatchFlags = stackalloc byte [16];
byte* neverMatchFlags = stackalloc byte [16];
byte* targetSortKey = stackalloc byte [4];
@@ -1662,6 +1821,29 @@
}
}
+ int LastIndexOfOrdinal (string s, char target, int start, int
length)
+ {
+ if (s.Length == 0)
+ return -1;
+ int end = start - length;
+ for (int i = start; i > end; i--)
+ if (s [i] == target)
+ return i;
+ return -1;
+ }
+
+ int LastIndexOfOrdinalIgnoreCase (string s, char target, int
start, int length)
+ {
+ if (s.Length == 0)
+ return -1;
+ int end = start - length;
+ char c = textInfo.ToUpper (target);
+ for (int i = start; i > end; i--)
+ if (textInfo.ToUpper (s [i]) == c)
+ return i;
+ return -1;
+ }
+
// Searches target byte[] keydata
unsafe int LastIndexOfSortKey (string s, int start, int
orgStart, int length, byte* sortkey, int ti, bool noLv4, ref Context ctx)
{
Modified: trunk/mcs/class/corlib/System.Globalization/ChangeLog
===================================================================
--- trunk/mcs/class/corlib/System.Globalization/ChangeLog 2006-12-25
05:09:15 UTC (rev 70036)
+++ trunk/mcs/class/corlib/System.Globalization/ChangeLog 2006-12-25
09:45:38 UTC (rev 70037)
@@ -1,3 +1,9 @@
+2006-12-25 Atsushi Enomoto <[EMAIL PROTECTED]>
+
+ * CompareInfo.cs : for OrdinalIgnoreCase, IndexOf() and LastIndexOf()
+ will use managed version (icalls for them are case sensitive).
+ Removed MonoTODOs.
+
2006-12-17 Igor Zelmanovich <[EMAIL PROTECTED]>
* DateTimeFormatInfo.cs : added missing properties and methods.
Modified: trunk/mcs/class/corlib/System.Globalization/CompareInfo.cs
===================================================================
--- trunk/mcs/class/corlib/System.Globalization/CompareInfo.cs 2006-12-25
05:09:15 UTC (rev 70036)
+++ trunk/mcs/class/corlib/System.Globalization/CompareInfo.cs 2006-12-25
09:45:38 UTC (rev 70037)
@@ -241,7 +241,6 @@
CompareOptions.None));
}
- [MonoTODO("Does not support CompareOptions.OrdinalIgnoreCase")]
public virtual int Compare (string string1, int offset1,
int length1, string string2,
int offset2, int length2,
@@ -465,18 +464,15 @@
int count, char c, CompareOptions opt,
bool first)
{
- return UseManagedCollation &&
-#if NET_2_0
- ((CompareOptions.Ordinal & opt) == 0 &&
- (CompareOptions.OrdinalIgnoreCase & opt) == 0) ?
-#else
- (CompareOptions.Ordinal & opt) == 0 ?
-#endif
+ // - forward IndexOf() icall is much faster than
+ // manged version, so always use icall. However,
+ // it does not work for OrdinalIgnoreCase, so
+ // do not avoid managed collator for that option.
+ return UseManagedCollation && ! (first && opt ==
CompareOptions.Ordinal) ?
internal_index_managed (s, sindex, count, c,
opt, first) :
internal_index (s, sindex, count, c, opt,
first);
}
- [MonoTODO("Does not support CompareOptions.OrdinalIgnoreCase")]
public virtual int IndexOf (string source, char value,
int startIndex, int count,
CompareOptions options)
@@ -533,18 +529,15 @@
int count, string s2, CompareOptions opt,
bool first)
{
- return UseManagedCollation &&
-#if NET_2_0
- ((CompareOptions.Ordinal & opt) == 0 ||
- (CompareOptions.OrdinalIgnoreCase & opt) == 0) ?
-#else
- (CompareOptions.Ordinal & opt) == 0 ?
-#endif
+ // - forward IndexOf() icall is much faster than
+ // manged version, so always use icall. However,
+ // it does not work for OrdinalIgnoreCase, so
+ // do not avoid managed collator for that option.
+ return UseManagedCollation && ! (first && opt ==
CompareOptions.Ordinal) ?
internal_index_managed (s1, sindex, count, s2,
opt, first) :
internal_index (s1, sindex, count, s2, opt,
first);
}
- [MonoTODO("Does not support CompareOptions.OrdinalIgnoreCase")]
public virtual int IndexOf (string source, string value,
int startIndex, int count,
CompareOptions options)
@@ -698,7 +691,6 @@
CompareOptions.None));
}
- [MonoTODO("Does not support CompareOptions.OrdinalIgnoreCase")]
public virtual int LastIndexOf(string source, char value,
int startIndex, int count,
CompareOptions options)
Modified: trunk/mcs/class/corlib/Test/System.Globalization/ChangeLog
===================================================================
--- trunk/mcs/class/corlib/Test/System.Globalization/ChangeLog 2006-12-25
05:09:15 UTC (rev 70036)
+++ trunk/mcs/class/corlib/Test/System.Globalization/ChangeLog 2006-12-25
09:45:38 UTC (rev 70037)
@@ -1,3 +1,8 @@
+2006-12-25 Atsushi Enomoto <[EMAIL PROTECTED]>
+
+ * CompareInfoTest.cs : added tests for OrdinalIgnoreCase versions
+ of IndexOf() and LastIndexOf(). Added Ordinal LastIndexOf() tests.
+
2006-11-27 Atsushi Enomoto <[EMAIL PROTECTED]>
* CompareInfoTest.cs : why there was "return" before OrdinalIgnoreCase
Modified: trunk/mcs/class/corlib/Test/System.Globalization/CompareInfoTest.cs
===================================================================
--- trunk/mcs/class/corlib/Test/System.Globalization/CompareInfoTest.cs
2006-12-25 05:09:15 UTC (rev 70036)
+++ trunk/mcs/class/corlib/Test/System.Globalization/CompareInfoTest.cs
2006-12-25 09:45:38 UTC (rev 70037)
@@ -1080,6 +1080,21 @@
}
[Test]
+ public void LastIndexOfOrdinalString ()
+ {
+ if (!doTest)
+ return;
+
+ AssertLastIndexOf ("#1", -1, "ABC", "1",
CompareOptions.Ordinal);
+ AssertLastIndexOf ("#2", 5, "ABCABC", "C",
CompareOptions.Ordinal);
+ AssertLastIndexOf ("#3", -1, "ABCABC", "\uFF22",
CompareOptions.Ordinal);
+ AssertLastIndexOf ("#4", 4, "ABCABC", "BC",
CompareOptions.Ordinal);
+ AssertLastIndexOf ("#5", 4, "BBCBBC", "BC",
CompareOptions.Ordinal);
+ AssertLastIndexOf ("#6", 1, "original", "rig",
CompareOptions.Ordinal);
+ AssertLastIndexOf ("#7", 0, "\\b\\a a", "\\b\\a a",
CompareOptions.Ordinal);
+ }
+
+ [Test]
// for bug #76702
public void NullCharacter ()
{
@@ -1127,6 +1142,40 @@
AssertCompare ("#13", 0, "ae", "AE",
CompareOptions.OrdinalIgnoreCase);
AssertCompare ("#14", 0, "ola", "OLA",
CompareOptions.OrdinalIgnoreCase);
}
+
+ [Test]
+ public void OrdinalIgnoreCaseIndexOf ()
+ {
+ AssertIndexOf ("#1-1", 0, "ABC", "abc",
CompareOptions.OrdinalIgnoreCase);
+ AssertIndexOf ("#1-2", -1, "AEBECE", "\u00E6",
CompareOptions.OrdinalIgnoreCase);
+ AssertIndexOf ("#1-3", -1, "@_@", "`_`",
CompareOptions.OrdinalIgnoreCase);
+ }
+
+ [Test]
+ public void OrdinalIgnoreCaseIndexOfChar ()
+ {
+ AssertIndexOf ("#2-1", 0, "ABC", 'a',
CompareOptions.OrdinalIgnoreCase);
+ AssertIndexOf ("#2-2", -1, "AEBECE", '\u00C0',
CompareOptions.OrdinalIgnoreCase);
+ AssertIndexOf ("#2-3", -1, "@_@", '`',
CompareOptions.OrdinalIgnoreCase);
+ }
+
+ [Test]
+ public void OrdinalIgnoreCaseLastIndexOf ()
+ {
+ AssertLastIndexOf ("#1-1", 0, "ABC", "abc",
CompareOptions.OrdinalIgnoreCase);
+ AssertLastIndexOf ("#1-2", -1, "AEBECE", "\u00E6",
CompareOptions.OrdinalIgnoreCase);
+ AssertLastIndexOf ("#1-3", -1, "@_@", "`_`",
CompareOptions.OrdinalIgnoreCase);
+ AssertLastIndexOf ("#1-4", 1, "ABCDE", "bc",
CompareOptions.OrdinalIgnoreCase);
+ AssertLastIndexOf ("#1-5", -1, "BBBBB", "ab",
CompareOptions.OrdinalIgnoreCase);
+ }
+
+ [Test]
+ public void OrdinalIgnoreCaseLastIndexOfChar ()
+ {
+ AssertLastIndexOf ("#2-1", 0, "ABC", 'a',
CompareOptions.OrdinalIgnoreCase);
+ AssertLastIndexOf ("#2-2", -1, "AEBECE", '\u00C0',
CompareOptions.OrdinalIgnoreCase);
+ AssertLastIndexOf ("#2-3", -1, "@_@", '`',
CompareOptions.OrdinalIgnoreCase);
+ }
#endif
}
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches