Fri Oct 26 19:43:09 CEST 2007 Paolo Molaro <lupus@ximian.com>
authorPaolo Molaro <lupus@oddwiz.org>
Fri, 26 Oct 2007 17:29:18 +0000 (17:29 -0000)
committerPaolo Molaro <lupus@oddwiz.org>
Fri, 26 Oct 2007 17:29:18 +0000 (17:29 -0000)
* Environment.cs, String.cs: patch from Tyler Larson
<mono-devel@tlarson.com> to fix the handling of the RemoveEmptyEntries
option in string.Split (bug #322375).

svn path=/trunk/mcs/; revision=88277

mcs/class/corlib/System/ChangeLog
mcs/class/corlib/System/Environment.cs
mcs/class/corlib/System/String.cs
mcs/class/corlib/Test/System/StringTest.cs

index e8701fba74016c677645c72f7f92a6ad7d94688b..edf9316af81c147ed365ead1982f95d9fc0bbfb4 100644 (file)
@@ -1,3 +1,10 @@
+
+Fri Oct 26 19:43:09 CEST 2007 Paolo Molaro <lupus@ximian.com>
+
+       * Environment.cs, String.cs: patch from Tyler Larson
+       <mono-devel@tlarson.com> to fix the handling of the RemoveEmptyEntries
+       option in string.Split (bug #322375).
+
 2007-10-26  Dick Porter  <dick@ximian.com>
 
        * Environment.cs: Bump version because of Thread initialisation
index 0c06e767048aa1847b34d007ebe401c8f6c58d38..5c6aef2a576dd0e10aaf1a5fa268451cb8f1e7e8 100644 (file)
@@ -63,7 +63,7 @@ namespace System {
                 * Changes which are already detected at runtime, like the addition
                 * of icalls, do not require an increment.
                 */
-               private const int mono_corlib_version = 59;
+               private const int mono_corlib_version = 60;
                
                public enum SpecialFolder
                {       // TODO: Determine if these windoze style folder identifiers 
index cf0cdcd28657aba9aa9f8eb6a59aff117fef7d76..df5b4451f3e772ea0dca6578dce2014ac27318ec 100644 (file)
@@ -216,12 +216,12 @@ namespace System
                        if (count == 1) 
                                return new String[1] { ToString() };
 
-                       return InternalSplit (separator, count);
+                       return InternalSplit (separator, count, 0);
                }
 
 #if NET_2_0
                [ComVisible (false)]
-               [MonoDocumentationNote ("optimization")]
+               [MonoDocumentationNote ("code should be moved to managed")]
                public String[] Split (char[] separator, int count, StringSplitOptions options)
                {
                        if (separator == null || separator.Length == 0)
@@ -232,28 +232,10 @@ namespace System
                        if ((options != StringSplitOptions.None) && (options != StringSplitOptions.RemoveEmptyEntries))
                                throw new ArgumentException ("options must be one of the values in the StringSplitOptions enumeration", "options");
 
-                       bool removeEmpty = (options & StringSplitOptions.RemoveEmptyEntries) == StringSplitOptions.RemoveEmptyEntries;
+                       if (count == 0)
+                               return new string [0];
 
-                       if (!removeEmpty)
-                               return Split (separator, count);
-                       else {
-                               /* FIXME: Optimize this */
-                               String[] res = Split (separator, count);
-                               int n = 0;
-                               for (int i = 0; i < res.Length; ++i)
-                                       if (res [i] == String.Empty)
-                                               n ++;
-                               if (n > 0) {
-                                       String[] arr = new String [res.Length - n];
-                                       int pos = 0;
-                                       for (int i = 0; i < res.Length; ++i)
-                                               if (res [i] != String.Empty)
-                                                       arr [pos ++] = res [i];
-                                       return arr;
-                               }
-                               else
-                                       return res;
-                       }
+                       return InternalSplit (separator, count, (int)options);
                }
 
                [ComVisible (false)]
@@ -2461,7 +2443,7 @@ namespace System
                private extern void InternalCopyTo (int sIndex, char[] dest, int destIndex, int count);
 
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               private extern String[] InternalSplit (char[] separator, int count);
+               private extern String[] InternalSplit (char[] separator, int count, int options);
 
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                private extern String InternalTrim (char[] chars, int typ);
index 1f8eaf1cbcf7b4b30300c476d7ce80cdcde1cd48..a6ea9d53542221be5ca978a8016760a535e0439c 100644 (file)
@@ -1898,6 +1898,68 @@ public class StringTest : Assertion
                AssertEquals ("B", res [1]);
                AssertEquals ("C", res [2]);
        }
+       
+       [Test]
+       public void SplitStringChars()
+       {
+               String[] res;
+
+               // count == 0
+               res = "..A..B..".Split (new Char[] { '.' }, 0, StringSplitOptions.None);
+               AssertEquals ("#01-01", 0, res.Length);
+
+               // count == 1
+               res = "..A..B..".Split (new Char[] { '.' }, 1, StringSplitOptions.None);
+               AssertEquals ("#02-01", 1, res.Length);
+               AssertEquals ("#02-02", "..A..B..", res [0]);
+
+               // count == 1 + RemoveEmpty
+               res = "..A..B..".Split (new Char[] { '.' }, 1, StringSplitOptions.RemoveEmptyEntries);
+               AssertEquals ("#03-01", 1, res.Length);
+               AssertEquals ("#03-02", "..A..B..", res [0]);
+               
+               // Keeping Empties and multipe split chars
+               res = "..A;.B.;".Split (new Char[] { '.', ';' }, StringSplitOptions.None);
+               AssertEquals ("#04-01", 7, res.Length);
+               AssertEquals ("#04-02", "",  res [0]);
+               AssertEquals ("#04-03", "",  res [1]);
+               AssertEquals ("#04-04", "A", res [2]);
+               AssertEquals ("#04-05", "",  res [3]);
+               AssertEquals ("#04-06", "B", res [4]);
+               AssertEquals ("#04-07", "",  res [5]);
+               AssertEquals ("#04-08", "",  res [6]);
+
+               // Trimming (3 tests)
+               res = "..A".Split (new Char[] { '.' }, 2, StringSplitOptions.RemoveEmptyEntries);
+               AssertEquals ("#05-01", 1, res.Length);
+               AssertEquals ("#05-02", "A", res [0]);
+               
+               res = "A..".Split (new Char[] { '.' }, 2, StringSplitOptions.RemoveEmptyEntries);
+               AssertEquals ("#06-01", 1, res.Length);
+               AssertEquals ("#06-02", "A", res [0]);
+               
+               res = "..A..".Split (new Char[] { '.' }, 2, StringSplitOptions.RemoveEmptyEntries);
+               AssertEquals ("#07-01", 1, res.Length);
+               AssertEquals ("#07-02", "A", res [0]);
+
+               // Lingering Tail
+               res = "..A..B..".Split (new Char[] { '.' }, 2, StringSplitOptions.RemoveEmptyEntries);
+               AssertEquals ("#08-01", 2, res.Length);
+               AssertEquals ("#08-02", "A", res [0]);
+               AssertEquals ("#08-03", "B..", res [1]);
+
+               // Whitespace and Long split chain (removing empty chars)
+               res = "  A\tBC\n\rDEF    GHI  ".Split ((Char[])null, StringSplitOptions.RemoveEmptyEntries);
+               AssertEquals ("#09-01", 4, res.Length);
+               AssertEquals ("#09-02", "A", res [0]);
+               AssertEquals ("#09-03", "BC", res [1]);
+               AssertEquals ("#09-04", "DEF", res [2]);
+               AssertEquals ("#09-05", "GHI", res [3]);
+
+               // Nothing but separators
+               res = "..,.;.,".Split (new Char[]{'.',',',';'},2,StringSplitOptions.RemoveEmptyEntries);
+               AssertEquals ("#10-01", 0, res.Length);
+       }
 #endif
 }