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

Reply via email to