From 07efc64d03a7ae713fa90729ad5a4add9c3112d5 Mon Sep 17 00:00:00 2001 From: Sebastien Pouliot Date: Tue, 27 Oct 2009 23:42:55 +0000 Subject: [PATCH] In System: 2009-10-27 Sebastien Pouliot * String.cs: Remove unused (and unneeded) internal call defs. Reduce duplication (and fix test) for Concat (object,object). Avoid allocating zero-length strings in the cases where the FX does not do so. In Test/System.Text: 2009-10-27 Sebastien Pouliot * UnicodeEncodingTest.cs: Add test cases with an odd number of bytes being used in GetString (it does not crash but it does not work like MS FX either). In Test/System: 2009-10-27 Sebastien Pouliot * StringTest.cs: Add test case for methods that can return empty strings. In System.Globalization: 2009-10-27 Sebastien Pouliot * TextInfo.cs: Avoid allocating zero-length strings in ToLower and ToUpper methods svn path=/trunk/mcs/; revision=144921 --- mcs/class/corlib/System.Globalization/ChangeLog | 5 ++ mcs/class/corlib/System.Globalization/TextInfo.cs | 6 ++ mcs/class/corlib/System/ChangeLog | 7 ++ mcs/class/corlib/System/String.cs | 74 ++++------------------ mcs/class/corlib/Test/System.Text/ChangeLog | 6 ++ .../corlib/Test/System.Text/UnicodeEncodingTest.cs | 24 +++++++ mcs/class/corlib/Test/System/ChangeLog | 5 ++ mcs/class/corlib/Test/System/StringTest.cs | 43 +++++++++++++ 8 files changed, 109 insertions(+), 61 deletions(-) diff --git a/mcs/class/corlib/System.Globalization/ChangeLog b/mcs/class/corlib/System.Globalization/ChangeLog index 114682b3e59..6efc232e25f 100644 --- a/mcs/class/corlib/System.Globalization/ChangeLog +++ b/mcs/class/corlib/System.Globalization/ChangeLog @@ -1,3 +1,8 @@ +2009-10-27 Sebastien Pouliot + + * TextInfo.cs: Avoid allocating zero-length strings in ToLower + and ToUpper methods + 2009-10-14 Jonathan Pryor * CultureInfo.cs: Re-add GetCultures() to the MonoTouch profile. diff --git a/mcs/class/corlib/System.Globalization/TextInfo.cs b/mcs/class/corlib/System.Globalization/TextInfo.cs index 452988ee9fd..d77993bb90e 100644 --- a/mcs/class/corlib/System.Globalization/TextInfo.cs +++ b/mcs/class/corlib/System.Globalization/TextInfo.cs @@ -436,6 +436,9 @@ namespace System.Globalization { if (str == null) throw new ArgumentNullException ("str"); + if (str.Length == 0) + return String.Empty; + string tmp = String.InternalAllocateStr (str.Length); fixed (char* source = str, dest = tmp) { @@ -461,6 +464,9 @@ namespace System.Globalization { if (str == null) throw new ArgumentNullException ("str"); + if (str.Length == 0) + return String.Empty; + string tmp = String.InternalAllocateStr (str.Length); fixed (char* source = str, dest = tmp) { diff --git a/mcs/class/corlib/System/ChangeLog b/mcs/class/corlib/System/ChangeLog index d9717051784..ce262fee83a 100644 --- a/mcs/class/corlib/System/ChangeLog +++ b/mcs/class/corlib/System/ChangeLog @@ -1,3 +1,10 @@ +2009-10-27 Sebastien Pouliot + + * String.cs: Remove unused (and unneeded) internal call defs. + Reduce duplication (and fix test) for Concat (object,object). + Avoid allocating zero-length strings in the cases where the + FX does not do so. + 2009-10-22 Miguel de Icaza * String.cs (IsNullOrWhiteSpace, Concat, Join): New 4.0 methods. diff --git a/mcs/class/corlib/System/String.cs b/mcs/class/corlib/System/String.cs index 4a5a8cd5123..30057fff9ad 100644 --- a/mcs/class/corlib/System/String.cs +++ b/mcs/class/corlib/System/String.cs @@ -1483,6 +1483,8 @@ namespace System if (totalWidth < this.length) return this; + if (this.Length == 0) + return String.Empty; String tmp = InternalAllocateStr (totalWidth); @@ -1723,6 +1725,9 @@ namespace System public unsafe String ToLowerInvariant () { + if (length == 0) + return String.Empty; + string tmp = InternalAllocateStr (length); fixed (char* source = &start_char, dest = tmp) { @@ -1756,6 +1761,9 @@ namespace System public unsafe String ToUpperInvariant () { + if (length == 0) + return String.Empty; + string tmp = InternalAllocateStr (length); fixed (char* source = &start_char, dest = tmp) { @@ -1934,34 +1942,9 @@ namespace System return arg0.ToString (); } - public unsafe static String Concat (Object arg0, Object arg1) + public static String Concat (Object arg0, Object arg1) { - string s1, s2; - - s1 = (arg0 != null) ? arg0.ToString () : null; - s2 = (arg1 != null) ? arg1.ToString () : null; - - if (s1 == null) { - if (s2 == null) - return String.Empty; - else - return s2; - } else if (s2 == null) - return s1; - - String tmp = InternalAllocateStr (s1.Length + s2.Length); - if (s1.Length != 0) { - fixed (char *dest = tmp, src = s1) { - CharCopy (dest, src, s1.length); - } - } - if (s2.Length != 0) { - fixed (char *dest = tmp, src = s2) { - CharCopy (dest + s1.Length, src, s2.length); - } - } - - return tmp; + return Concat ((arg0 != null) ? arg0.ToString () : null, (arg1 != null) ? arg1.ToString () : null); } public static String Concat (Object arg0, Object arg1, Object arg2) @@ -2146,8 +2129,6 @@ namespace System len += strings[i].length; } } - if (len == 0) - return String.Empty; return ConcatInternal (strings, len); } @@ -2163,14 +2144,15 @@ namespace System if (s != null) len += s.length; } - if (len == 0) - return String.Empty; return ConcatInternal (values, len); } private static unsafe String ConcatInternal (String[] values, int length) { + if (length == 0) + return String.Empty; + String tmp = InternalAllocateStr (length); fixed (char* dest = tmp) { @@ -3034,43 +3016,13 @@ namespace System [MethodImplAttribute (MethodImplOptions.InternalCall)] public extern String (char c, int count); -// [MethodImplAttribute (MethodImplOptions.InternalCall)] -// private extern static string InternalJoin (string separator, string[] value, int sIndex, int count); - -// [MethodImplAttribute (MethodImplOptions.InternalCall)] -// private extern String InternalReplace (String oldValue, string newValue, CompareInfo comp); - -// [MethodImplAttribute (MethodImplOptions.InternalCall)] -// private extern void InternalCopyTo (int sIndex, char[] dest, int destIndex, int count); - [MethodImplAttribute (MethodImplOptions.InternalCall)] private extern String[] InternalSplit (char[] separator, int count, int options); -// [MethodImplAttribute (MethodImplOptions.InternalCall)] -// private extern String InternalTrim (char[] chars, int typ); - -// [MethodImplAttribute (MethodImplOptions.InternalCall)] -// private extern int InternalLastIndexOfAny (char [] anyOf, int sIndex, int count); - -// [MethodImplAttribute (MethodImplOptions.InternalCall)] -// private extern String InternalPad (int width, char chr, bool right); - [MethodImplAttribute (MethodImplOptions.InternalCall)] internal extern static String InternalAllocateStr (int length); -#if false - [MethodImplAttribute (MethodImplOptions.InternalCall)] - internal extern static void InternalStrcpy (String dest, int destPos, String src); - - [MethodImplAttribute (MethodImplOptions.InternalCall)] - internal extern static void InternalStrcpy (String dest, int destPos, char[] chars); [MethodImplAttribute (MethodImplOptions.InternalCall)] - internal extern static void InternalStrcpy (String dest, int destPos, String src, int sPos, int count); - - [MethodImplAttribute (MethodImplOptions.InternalCall)] - internal extern static void InternalStrcpy (String dest, int destPos, char[] chars, int sPos, int count); -#endif - [MethodImplAttribute (MethodImplOptions.InternalCall)] private extern static string InternalIntern (string str); [MethodImplAttribute (MethodImplOptions.InternalCall)] diff --git a/mcs/class/corlib/Test/System.Text/ChangeLog b/mcs/class/corlib/Test/System.Text/ChangeLog index eef30af1cac..6156bfa83ca 100644 --- a/mcs/class/corlib/Test/System.Text/ChangeLog +++ b/mcs/class/corlib/Test/System.Text/ChangeLog @@ -1,3 +1,9 @@ +2009-10-27 Sebastien Pouliot + + * UnicodeEncodingTest.cs: Add test cases with an odd number of + bytes being used in GetString (it does not crash but it does not + work like MS FX either). + 2009-09-12 Gonzalo Paniagua Javier * StringBuilderTest.cs: new test. diff --git a/mcs/class/corlib/Test/System.Text/UnicodeEncodingTest.cs b/mcs/class/corlib/Test/System.Text/UnicodeEncodingTest.cs index b4ef5970124..9938bcef1ae 100644 --- a/mcs/class/corlib/Test/System.Text/UnicodeEncodingTest.cs +++ b/mcs/class/corlib/Test/System.Text/UnicodeEncodingTest.cs @@ -233,5 +233,29 @@ namespace MonoTests.System.Text Assert.AreEqual (encoding.GetString (littleEndianBytes), bigEndianString, "BOM #7"); Assert.AreEqual (encoding.GetString (bigEndianBytes), littleEndianString, "BOM #8"); } + + [Test] + [Category ("NotWorking")] + public void GetString_Odd_Count_0 () + { + byte [] array = new byte [3]; + string s = Encoding.Unicode.GetString (array, 0, 3); + Assert.AreEqual (0, (int) s [0], "0"); + + Assert.AreEqual (2, s.Length, "Length"); + Assert.AreEqual (65533, (int) s [1], "1"); + } + + [Test] + [Category ("NotWorking")] + public void GetString_Odd_Count_ff () + { + byte [] array = new byte [3] { 0xff, 0xff, 0xff }; + string s = Encoding.Unicode.GetString (array, 0, 3); + Assert.AreEqual (65535, (int) s [0], "0"); + + Assert.AreEqual (2, s.Length, "Length"); + Assert.AreEqual (65533, (int) s [1], "1"); + } } } diff --git a/mcs/class/corlib/Test/System/ChangeLog b/mcs/class/corlib/Test/System/ChangeLog index 560ee1eb4ae..333644a8cee 100644 --- a/mcs/class/corlib/Test/System/ChangeLog +++ b/mcs/class/corlib/Test/System/ChangeLog @@ -1,3 +1,8 @@ +2009-10-27 Sebastien Pouliot + + * StringTest.cs: Add test case for methods that can return + empty strings. + 2009-10-26 Sebastien Pouliot * TypeTest.cs: New. Add test cases for IsInstanceOfType diff --git a/mcs/class/corlib/Test/System/StringTest.cs b/mcs/class/corlib/Test/System/StringTest.cs index 355e7e4b770..006e0e64e04 100644 --- a/mcs/class/corlib/Test/System/StringTest.cs +++ b/mcs/class/corlib/Test/System/StringTest.cs @@ -4246,6 +4246,49 @@ public class StringTest Assert.AreEqual (formKC, s.Normalize (NormalizationForm.FormKC), "#4"); } #endif + [Test] + public void Emptiness () + { + // note: entries using AreEqual are in reality AreNotSame on MS FX + // but I prefer Mono implementation ;-) and it minimize the changes + Assert.AreSame (String.Empty, "", "Empty"); + + Assert.AreSame (String.Empty, String.Concat ((object) null), "Concat(null)"); + Assert.AreSame (String.Empty, String.Concat ((object) String.Empty), "Concat(empty)"); + Assert.AreSame (String.Empty, String.Concat ((object) String.Empty, (object) String.Empty), "Concat(object,object)"); + Assert.AreSame (String.Empty, String.Concat (String.Empty, String.Empty), "Concat(string,string)"); + Assert.AreEqual (String.Empty, String.Concat (String.Empty, String.Empty, String.Empty), "Concat(string,string,string)"); + Assert.AreEqual (String.Empty, String.Concat ((object) null, (object) (object) null, (object) null, (object) null), "Concat(null,null,null,null)-object"); + Assert.AreSame (String.Empty, String.Concat ((string) null, (string) (string) null, (string) null, (string) null), "Concat(null,null,null,null)-string"); + Assert.AreNotSame (String.Empty, String.Concat (String.Empty, String.Empty, String.Empty, String.Empty), "Concat(string,string,string,string)"); + Assert.AreEqual (String.Empty, String.Concat (new object [] { String.Empty, String.Empty }), "Concat(object[])"); + Assert.AreEqual (String.Empty, String.Concat (new string [] { String.Empty, String.Empty }), "Concat(string[])"); + + Assert.AreNotSame (String.Empty, String.Copy (String.Empty), "Copy"); + + Assert.AreEqual (String.Empty, "".Insert (0, String.Empty), "Insert(Empty)"); + Assert.AreEqual (String.Empty, String.Empty.Insert (0, ""), "Empty.Insert"); + + Assert.AreNotSame (String.Empty, String.Empty.PadLeft (0), "PadLeft(int)"); + Assert.AreNotSame (String.Empty, String.Empty.PadLeft (0, '.'), "PadLeft(int.char)"); + Assert.AreSame (String.Empty, String.Empty.PadRight (0), "PadRight(int)"); + Assert.AreSame (String.Empty, String.Empty.PadRight (0, '.'), "PadRight(int.char)"); + + Assert.AreSame (String.Empty, "".Substring (0), "Substring(int)"); + Assert.AreSame (String.Empty, "ab".Substring (1, 0), "Substring(int,int)"); + + Assert.AreSame (String.Empty, "".ToLower (), "ToLower"); + Assert.AreSame (String.Empty, "".ToUpper (), "ToUpper"); + Assert.AreSame (String.Empty, "".ToLower (CultureInfo.CurrentCulture), "ToLower(CultureInfo)"); + Assert.AreSame (String.Empty, "".ToUpper (CultureInfo.CurrentCulture), "ToUpper(CultureInfo)"); + Assert.AreSame (String.Empty, "".ToLowerInvariant (), "ToLowerInvariant"); + Assert.AreSame (String.Empty, "".ToUpperInvariant (), "ToUpperInvariant"); + + Assert.AreSame (String.Empty, "".Trim (), "Trim()"); + Assert.AreSame (String.Empty, "a".Trim ('a'), "Trim(char)"); + Assert.AreSame (String.Empty, "a".TrimEnd ('a'), "TrimEnd(char)"); + Assert.AreSame (String.Empty, "a".TrimStart ('a'), "TrimStart(char)"); + } } } -- 2.11.4.GIT