diff options
Diffstat (limited to 'src/mscorlib/src/System/String.Manipulation.cs')
-rw-r--r-- | src/mscorlib/src/System/String.Manipulation.cs | 475 |
1 files changed, 265 insertions, 210 deletions
diff --git a/src/mscorlib/src/System/String.Manipulation.cs b/src/mscorlib/src/System/String.Manipulation.cs index e9568a6d03..194b4f8c59 100644 --- a/src/mscorlib/src/System/String.Manipulation.cs +++ b/src/mscorlib/src/System/String.Manipulation.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; +using System.Diagnostics; using System.Diagnostics.Contracts; using System.Globalization; using System.Runtime.CompilerServices; @@ -17,7 +18,6 @@ namespace System private const int TrimTail = 1; private const int TrimBoth = 2; - [System.Security.SecuritySafeCritical] // auto-generated unsafe private static void FillStringChecked(String dest, int destPos, String src) { Contract.Requires(dest != null); @@ -109,12 +109,11 @@ namespace System return Concat(objArgs); } - [System.Security.SecuritySafeCritical] public static string Concat(params object[] args) { if (args == null) { - throw new ArgumentNullException("args"); + throw new ArgumentNullException(nameof(args)); } Contract.Ensures(Contract.Result<String>() != null); Contract.EndContractBlock(); @@ -167,8 +166,8 @@ namespace System { string s = strings[i]; - Contract.Assert(s != null); - Contract.Assert(position <= totalLength - s.Length, "We didn't allocate enough space for the result string!"); + Debug.Assert(s != null); + Debug.Assert(position <= totalLength - s.Length, "We didn't allocate enough space for the result string!"); FillStringChecked(result, position, s); position += s.Length; @@ -181,7 +180,7 @@ namespace System public static string Concat<T>(IEnumerable<T> values) { if (values == null) - throw new ArgumentNullException("values"); + throw new ArgumentNullException(nameof(values)); Contract.Ensures(Contract.Result<String>() != null); Contract.EndContractBlock(); @@ -232,7 +231,7 @@ namespace System public static string Concat(IEnumerable<string> values) { if (values == null) - throw new ArgumentNullException("values"); + throw new ArgumentNullException(nameof(values)); Contract.Ensures(Contract.Result<String>() != null); Contract.EndContractBlock(); @@ -262,7 +261,6 @@ namespace System } - [System.Security.SecuritySafeCritical] // auto-generated public static String Concat(String str0, String str1) { Contract.Ensures(Contract.Result<String>() != null); Contract.Ensures(Contract.Result<String>().Length == @@ -291,7 +289,6 @@ namespace System return result; } - [System.Security.SecuritySafeCritical] // auto-generated public static String Concat(String str0, String str1, String str2) { Contract.Ensures(Contract.Result<String>() != null); Contract.Ensures(Contract.Result<String>().Length == @@ -325,7 +322,6 @@ namespace System return result; } - [System.Security.SecuritySafeCritical] // auto-generated public static String Concat(String str0, String str1, String str2, String str3) { Contract.Ensures(Contract.Result<String>() != null); Contract.Ensures(Contract.Result<String>().Length == @@ -366,10 +362,9 @@ namespace System return result; } - [System.Security.SecuritySafeCritical] public static String Concat(params String[] values) { if (values == null) - throw new ArgumentNullException("values"); + throw new ArgumentNullException(nameof(values)); Contract.Ensures(Contract.Result<String>() != null); Contract.EndContractBlock(); @@ -456,7 +451,7 @@ namespace System { // To preserve the original exception behavior, throw an exception about format if both // args and format are null. The actual null check for format is in FormatHelper. - throw new ArgumentNullException((format == null) ? "format" : "args"); + throw new ArgumentNullException((format == null) ? nameof(format) : nameof(args)); } Contract.Ensures(Contract.Result<String>() != null); Contract.EndContractBlock(); @@ -484,7 +479,7 @@ namespace System { // To preserve the original exception behavior, throw an exception about format if both // args and format are null. The actual null check for format is in FormatHelper. - throw new ArgumentNullException((format == null) ? "format" : "args"); + throw new ArgumentNullException((format == null) ? nameof(format) : nameof(args)); } Contract.Ensures(Contract.Result<String>() != null); Contract.EndContractBlock(); @@ -494,7 +489,7 @@ namespace System private static String FormatHelper(IFormatProvider provider, String format, ParamsArray args) { if (format == null) - throw new ArgumentNullException("format"); + throw new ArgumentNullException(nameof(format)); return StringBuilderCache.GetStringAndRelease( StringBuilderCache @@ -502,13 +497,12 @@ namespace System .AppendFormatHelper(provider, format, args)); } - [System.Security.SecuritySafeCritical] // auto-generated public String Insert(int startIndex, String value) { if (value == null) - throw new ArgumentNullException("value"); + throw new ArgumentNullException(nameof(value)); if (startIndex < 0 || startIndex > this.Length) - throw new ArgumentOutOfRangeException("startIndex"); + throw new ArgumentOutOfRangeException(nameof(startIndex)); Contract.Ensures(Contract.Result<String>() != null); Contract.Ensures(Contract.Result<String>().Length == this.Length + value.Length); Contract.EndContractBlock(); @@ -541,27 +535,131 @@ namespace System } return result; } + + public static string Join(char separator, params string[] value) + { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + + return Join(separator, value, 0, value.Length); + } + + public unsafe static string Join(char separator, params object[] values) + { + // Defer argument validation to the internal function + return JoinCore(&separator, 1, values); + } + + public unsafe static string Join<T>(char separator, IEnumerable<T> values) + { + // Defer argument validation to the internal function + return JoinCore(&separator, 1, values); + } + + public unsafe static string Join(char separator, string[] value, int startIndex, int count) + { + // Defer argument validation to the internal function + return JoinCore(&separator, 1, value, startIndex, count); + } // Joins an array of strings together as one string with a separator between each original string. // - public static String Join(String separator, params String[] value) { - if (value==null) - throw new ArgumentNullException("value"); - Contract.EndContractBlock(); + public static string Join(string separator, params string[] value) + { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } return Join(separator, value, 0, value.Length); } [ComVisible(false)] - public static string Join(string separator, params object[] values) + public unsafe static string Join(string separator, params object[] values) + { + separator = separator ?? string.Empty; + fixed (char* pSeparator = &separator.m_firstChar) + { + // Defer argument validation to the internal function + return JoinCore(pSeparator, separator.Length, values); + } + } + + [ComVisible(false)] + public unsafe static string Join<T>(string separator, IEnumerable<T> values) + { + separator = separator ?? string.Empty; + fixed (char* pSeparator = &separator.m_firstChar) + { + // Defer argument validation to the internal function + return JoinCore(pSeparator, separator.Length, values); + } + } + + [ComVisible(false)] + public static string Join(string separator, IEnumerable<string> values) { if (values == null) - throw new ArgumentNullException("values"); - Contract.EndContractBlock(); + { + throw new ArgumentNullException(nameof(values)); + } + + using (IEnumerator<string> en = values.GetEnumerator()) + { + if (!en.MoveNext()) + { + return string.Empty; + } + + string firstValue = en.Current; - if (values.Length == 0 || values[0] == null) + if (!en.MoveNext()) + { + // Only one value available + return firstValue ?? string.Empty; + } + + // Null separator and values are handled by the StringBuilder + StringBuilder result = StringBuilderCache.Acquire(); + result.Append(firstValue); + + do + { + result.Append(separator); + result.Append(en.Current); + } + while (en.MoveNext()); + + return StringBuilderCache.GetStringAndRelease(result); + } + } + + // Joins an array of strings together as one string with a separator between each original string. + // + public unsafe static string Join(string separator, string[] value, int startIndex, int count) + { + separator = separator ?? string.Empty; + fixed (char* pSeparator = &separator.m_firstChar) + { + // Defer argument validation to the internal function + return JoinCore(pSeparator, separator.Length, value, startIndex, count); + } + } + + private unsafe static string JoinCore(char* separator, int separatorLength, object[] values) + { + if (values == null) + { + throw new ArgumentNullException(nameof(values)); + } + + if (values.Length == 0) + { return string.Empty; + } - string firstString = values[0].ToString(); + string firstString = values[0]?.ToString(); if (values.Length == 1) { @@ -573,7 +671,7 @@ namespace System for (int i = 1; i < values.Length; i++) { - result.Append(separator); + result.Append(separator, separatorLength); object value = values[i]; if (value != null) { @@ -584,18 +682,19 @@ namespace System return StringBuilderCache.GetStringAndRelease(result); } - [ComVisible(false)] - public static String Join<T>(String separator, IEnumerable<T> values) + private unsafe static string JoinCore<T>(char* separator, int separatorLength, IEnumerable<T> values) { if (values == null) - throw new ArgumentNullException("values"); - Contract.Ensures(Contract.Result<String>() != null); - Contract.EndContractBlock(); + { + throw new ArgumentNullException(nameof(values)); + } using (IEnumerator<T> en = values.GetEnumerator()) { if (!en.MoveNext()) + { return string.Empty; + } // We called MoveNext once, so this will be the first item T currentValue = en.Current; @@ -616,14 +715,14 @@ namespace System } StringBuilder result = StringBuilderCache.Acquire(); - + result.Append(firstString); do { currentValue = en.Current; - result.Append(separator); + result.Append(separator, separatorLength); if (currentValue != null) { result.Append(currentValue.ToString()); @@ -635,107 +734,113 @@ namespace System } } - [ComVisible(false)] - public static String Join(String separator, IEnumerable<String> values) { - if (values == null) - throw new ArgumentNullException("values"); - Contract.Ensures(Contract.Result<String>() != null); - Contract.EndContractBlock(); - - using(IEnumerator<String> en = values.GetEnumerator()) { - if (!en.MoveNext()) - return String.Empty; - - String firstValue = en.Current; - - if (!en.MoveNext()) { - // Only one value available - return firstValue ?? String.Empty; - } - - // Null separator and values are handled by the StringBuilder - StringBuilder result = StringBuilderCache.Acquire(); - result.Append(firstValue); - - do { - result.Append(separator); - result.Append(en.Current); - } while (en.MoveNext()); - return StringBuilderCache.GetStringAndRelease(result); - } - } + private unsafe static string JoinCore(char* separator, int separatorLength, string[] value, int startIndex, int count) + { + // If the separator is null, it is converted to an empty string before entering this function. + // Even for empty strings, fixed should never return null (it should return a pointer to a null char). + Debug.Assert(separator != null); + Debug.Assert(separatorLength >= 0); - // Joins an array of strings together as one string with a separator between each original string. - // - [System.Security.SecuritySafeCritical] // auto-generated - public unsafe static String Join(String separator, String[] value, int startIndex, int count) { - //Range check the array if (value == null) - throw new ArgumentNullException("value"); - + { + throw new ArgumentNullException(nameof(value)); + } if (startIndex < 0) - throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_StartIndex")); + { + throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndex")); + } if (count < 0) - throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NegativeCount")); - + { + throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NegativeCount")); + } if (startIndex > value.Length - count) - throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer")); - Contract.EndContractBlock(); - - //Treat null as empty string. - if (separator == null) { - separator = String.Empty; + { + throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer")); } - - //If count is 0, that skews a whole bunch of the calculations below, so just special case that. - if (count == 0) { - return String.Empty; + + if (count <= 1) + { + return count == 0 ? + string.Empty : + value[startIndex] ?? string.Empty; } - if (count == 1) { - return value[startIndex] ?? String.Empty; + long totalSeparatorsLength = (long)(count - 1) * separatorLength; + if (totalSeparatorsLength > int.MaxValue) + { + throw new OutOfMemoryException(); } + int totalLength = (int)totalSeparatorsLength; - int jointLength = 0; - //Figure out the total length of the strings in value - int endIndex = startIndex + count - 1; - for (int stringToJoinIndex = startIndex; stringToJoinIndex <= endIndex; stringToJoinIndex++) { - string currentValue = value[stringToJoinIndex]; - - if (currentValue != null) { - jointLength += currentValue.Length; + // Calculate the length of the resultant string so we know how much space to allocate. + for (int i = startIndex, end = startIndex + count; i < end; i++) + { + string currentValue = value[i]; + if (currentValue != null) + { + totalLength += currentValue.Length; + if (totalLength < 0) // Check for overflow + { + throw new OutOfMemoryException(); + } } } - - //Add enough room for the separator. - jointLength += (count - 1) * separator.Length; - // Note that we may not catch all overflows with this check (since we could have wrapped around the 4gb range any number of times - // and landed back in the positive range.) The input array might be modifed from other threads, - // so we have to do an overflow check before each append below anyway. Those overflows will get caught down there. - if ((jointLength < 0) || ((jointLength + 1) < 0) ) { - throw new OutOfMemoryException(); - } + // Copy each of the strings into the resultant buffer, interleaving with the separator. + string result = FastAllocateString(totalLength); + int copiedLength = 0; - //If this is an empty string, just return. - if (jointLength == 0) { - return String.Empty; - } + for (int i = startIndex, end = startIndex + count; i < end; i++) + { + // It's possible that another thread may have mutated the input array + // such that our second read of an index will not be the same string + // we got during the first read. - string jointString = FastAllocateString( jointLength ); - fixed (char * pointerToJointString = &jointString.m_firstChar) { - UnSafeCharBuffer charBuffer = new UnSafeCharBuffer( pointerToJointString, jointLength); - - // Append the first string first and then append each following string prefixed by the separator. - charBuffer.AppendString( value[startIndex] ); - for (int stringToJoinIndex = startIndex + 1; stringToJoinIndex <= endIndex; stringToJoinIndex++) { - charBuffer.AppendString( separator ); - charBuffer.AppendString( value[stringToJoinIndex] ); + // We range check again to avoid buffer overflows if this happens. + + string currentValue = value[i]; + if (currentValue != null) + { + int valueLen = currentValue.Length; + if (valueLen > totalLength - copiedLength) + { + copiedLength = -1; + break; + } + + // Fill in the value. + FillStringChecked(result, copiedLength, currentValue); + copiedLength += valueLen; + } + + if (i < end - 1) + { + // Fill in the separator. + fixed (char* pResult = &result.m_firstChar) + { + // If we are called from the char-based overload, we will not + // want to call MemoryCopy each time we fill in the separator. So + // specialize for 1-length separators. + if (separatorLength == 1) + { + pResult[copiedLength] = *separator; + } + else + { + wstrcpy(pResult + copiedLength, separator, separatorLength); + } + } + copiedLength += separatorLength; } - Contract.Assert(*(pointerToJointString + charBuffer.Length) == '\0', "String must be null-terminated!"); } - return jointString; + // If we copied exactly the right amount, return the new string. Otherwise, + // something changed concurrently to mutate the input array: fall back to + // doing the concatenation again, but this time with a defensive copy. This + // fall back should be extremely rare. + return copiedLength == totalLength ? + result : + JoinCore(separator, separatorLength, (string[])value.Clone(), startIndex, count); } // @@ -746,10 +851,9 @@ namespace System } [Pure] - [System.Security.SecuritySafeCritical] // auto-generated public String PadLeft(int totalWidth, char paddingChar) { if (totalWidth < 0) - throw new ArgumentOutOfRangeException("totalWidth", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(totalWidth), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); int oldLength = Length; int count = totalWidth - oldLength; if (count <= 0) @@ -776,10 +880,9 @@ namespace System } [Pure] - [System.Security.SecuritySafeCritical] // auto-generated public String PadRight(int totalWidth, char paddingChar) { if (totalWidth < 0) - throw new ArgumentOutOfRangeException("totalWidth", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(totalWidth), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); int oldLength = Length; int count = totalWidth - oldLength; if (count <= 0) @@ -800,17 +903,16 @@ namespace System return result; } - [System.Security.SecuritySafeCritical] // auto-generated public String Remove(int startIndex, int count) { if (startIndex < 0) - throw new ArgumentOutOfRangeException("startIndex", + throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndex")); if (count < 0) - throw new ArgumentOutOfRangeException("count", + throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NegativeCount")); if (count > Length - startIndex) - throw new ArgumentOutOfRangeException("count", + throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_IndexCount")); Contract.Ensures(Contract.Result<String>() != null); Contract.Ensures(Contract.Result<String>().Length == this.Length - count); @@ -840,12 +942,12 @@ namespace System // a remove that just takes a startindex. public string Remove( int startIndex ) { if (startIndex < 0) { - throw new ArgumentOutOfRangeException("startIndex", + throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndex")); } if (startIndex >= Length) { - throw new ArgumentOutOfRangeException("startIndex", + throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndexLessThanLength")); } @@ -857,7 +959,6 @@ namespace System // Replaces all instances of oldChar with newChar. // - [System.Security.SecuritySafeCritical] // auto-generated public String Replace(char oldChar, char newChar) { Contract.Ensures(Contract.Result<String>() != null); @@ -928,14 +1029,13 @@ namespace System // This method contains the same functionality as StringBuilder Replace. The only difference is that // a new String has to be allocated since Strings are immutable - [System.Security.SecuritySafeCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern String ReplaceInternal(String oldValue, String newValue); public String Replace(String oldValue, String newValue) { if (oldValue == null) - throw new ArgumentNullException("oldValue"); + throw new ArgumentNullException(nameof(oldValue)); // Note that if newValue is null, we treat it like String.Empty. Contract.Ensures(Contract.Result<String>() != null); Contract.EndContractBlock(); @@ -944,19 +1044,13 @@ namespace System } [ComVisible(false)] - public String[] Split(char separator) { - Contract.Ensures(Contract.Result<String[]>() != null); - return SplitInternal(separator, Int32.MaxValue, StringSplitOptions.None); - } - - [ComVisible(false)] - public String[] Split(char separator, StringSplitOptions options) { + public String[] Split(char separator, StringSplitOptions options = StringSplitOptions.None) { Contract.Ensures(Contract.Result<String[]>() != null); return SplitInternal(separator, Int32.MaxValue, options); } [ComVisible(false)] - public String[] Split(char separator, int count, StringSplitOptions options) { + public String[] Split(char separator, int count, StringSplitOptions options = StringSplitOptions.None) { Contract.Ensures(Contract.Result<String[]>() != null); return SplitInternal(separator, count, options); } @@ -1004,33 +1098,24 @@ namespace System return SplitInternal(separator, count, options); } - [System.Security.SecuritySafeCritical] private unsafe String[] SplitInternal(char separator, int count, StringSplitOptions options) { - char* pSeparators = stackalloc char[1]; - pSeparators[0] = separator; - return SplitInternal(pSeparators, /*separatorsLength*/ 1, count, options); + return SplitInternal(&separator, 1, count, options); } - [ComVisible(false)] - [System.Security.SecuritySafeCritical] - internal String[] SplitInternal(char[] separator, int count, StringSplitOptions options) + private unsafe String[] SplitInternal(char[] separator, int count, StringSplitOptions options) { - unsafe + fixed (char* pSeparators = separator) { - fixed (char* pSeparators = separator) - { - int separatorsLength = separator == null ? 0 : separator.Length; - return SplitInternal(pSeparators, separatorsLength, count, options); - } + int separatorsLength = separator == null ? 0 : separator.Length; + return SplitInternal(pSeparators, separatorsLength, count, options); } } - [System.Security.SecurityCritical] private unsafe String[] SplitInternal(char* separators, int separatorsLength, int count, StringSplitOptions options) { if (count < 0) - throw new ArgumentOutOfRangeException("count", + throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NegativeCount")); if (options < StringSplitOptions.None || options > StringSplitOptions.RemoveEmptyEntries) @@ -1041,14 +1126,8 @@ namespace System bool omitEmptyEntries = (options == StringSplitOptions.RemoveEmptyEntries); if ((count == 0) || (omitEmptyEntries && this.Length == 0)) - { -#if FEATURE_CORECLR + { return EmptyArray<String>.Value; -#else - // Keep the old behavior of returning a new empty array - // to mitigate any potential compat risk. - return new String[0]; -#endif } if (count == 1) @@ -1056,38 +1135,32 @@ namespace System return new String[] { this }; } - int[] sepList = new int[Length]; + int[] sepList = new int[Length]; int numReplaces = MakeSeparatorList(separators, separatorsLength, sepList); // Handle the special case of no replaces. if (0 == numReplaces) { return new String[] { this }; - } + } if(omitEmptyEntries) { - return InternalSplitOmitEmptyEntries(sepList, null, 1, numReplaces, count); + return SplitOmitEmptyEntries(sepList, null, 1, numReplaces, count); } else { - return InternalSplitKeepEmptyEntries(sepList, null, 1, numReplaces, count); - } - } - - [ComVisible(false)] - public String[] Split(String separator) { - Contract.Ensures(Contract.Result<String[]>() != null); - return SplitInternal(separator ?? String.Empty, null, Int32.MaxValue, StringSplitOptions.None); + return SplitKeepEmptyEntries(sepList, null, 1, numReplaces, count); + } } [ComVisible(false)] - public String[] Split(String separator, StringSplitOptions options) { + public String[] Split(String separator, StringSplitOptions options = StringSplitOptions.None) { Contract.Ensures(Contract.Result<String[]>() != null); return SplitInternal(separator ?? String.Empty, null, Int32.MaxValue, options); } [ComVisible(false)] - public String[] Split(String separator, Int32 count, StringSplitOptions options) { + public String[] Split(String separator, Int32 count, StringSplitOptions options = StringSplitOptions.None) { Contract.Ensures(Contract.Result<String[]>() != null); return SplitInternal(separator ?? String.Empty, null, count, options); } @@ -1107,7 +1180,7 @@ namespace System private String[] SplitInternal(String separator, String[] separators, Int32 count, StringSplitOptions options) { if (count < 0) { - throw new ArgumentOutOfRangeException("count", + throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NegativeCount")); } @@ -1125,23 +1198,13 @@ namespace System } if ((count == 0) || (omitEmptyEntries && this.Length ==0)) { -#if FEATURE_CORECLR return EmptyArray<String>.Value; -#else - // Keep the old behavior of returning a new empty array - // to mitigate any potential compat risk. - return new String[0]; -#endif } - if (count == 1) { + if (count == 1 || (singleSeparator && separator.Length == 0)) { return new String[] { this }; } - if (singleSeparator && separator.Length == 0) { - return new[] { this }; - } - int[] sepList = new int[Length]; int[] lengthList; int defaultLength; @@ -1164,10 +1227,10 @@ namespace System } if (omitEmptyEntries) { - return InternalSplitOmitEmptyEntries(sepList, lengthList, defaultLength, numReplaces, count); + return SplitOmitEmptyEntries(sepList, lengthList, defaultLength, numReplaces, count); } else { - return InternalSplitKeepEmptyEntries(sepList, lengthList, defaultLength, numReplaces, count); + return SplitKeepEmptyEntries(sepList, lengthList, defaultLength, numReplaces, count); } } @@ -1176,7 +1239,7 @@ namespace System // the original string will be returned regardless of the count. // - private String[] InternalSplitKeepEmptyEntries(Int32[] sepList, Int32[] lengthList, Int32 defaultLength, Int32 numReplaces, int count) { + private String[] SplitKeepEmptyEntries(Int32[] sepList, Int32[] lengthList, Int32 defaultLength, Int32 numReplaces, int count) { Contract.Requires(numReplaces >= 0); Contract.Requires(count >= 2); Contract.Ensures(Contract.Result<String[]>() != null); @@ -1212,7 +1275,7 @@ namespace System // This function will not keep the Empty String - private String[] InternalSplitOmitEmptyEntries(Int32[] sepList, Int32[] lengthList, Int32 defaultLength, Int32 numReplaces, int count) { + private String[] SplitOmitEmptyEntries(Int32[] sepList, Int32[] lengthList, Int32 defaultLength, Int32 numReplaces, int count) { Contract.Requires(numReplaces >= 0); Contract.Requires(count >= 2); Contract.Ensures(Contract.Result<String[]>() != null); @@ -1242,7 +1305,7 @@ namespace System } // we must have at least one slot left to fill in the last string. - Contract.Assert(arrIndex < maxItems); + Debug.Assert(arrIndex < maxItems); //Handle the last string at the end of the array if there is one. if (currIndex< Length) { @@ -1265,9 +1328,8 @@ namespace System // Args: separator -- A string containing all of the split characters. // sepList -- an array of ints for split char indicies. //-------------------------------------------------------------------- - [System.Security.SecurityCritical] private unsafe int MakeSeparatorList(char* separators, int separatorsLength, int[] sepList) { - Contract.Assert(separatorsLength >= 0, "separatorsLength >= 0"); + Debug.Assert(separatorsLength >= 0, "separatorsLength >= 0"); int foundCount=0; if (separators == null || separatorsLength == 0) { @@ -1304,9 +1366,8 @@ namespace System // Args: separator -- the separator // sepList -- an array of ints for split string indicies. //-------------------------------------------------------------------- - [System.Security.SecuritySafeCritical] // auto-generated private unsafe int MakeSeparatorList(string separator, int[] sepList) { - Contract.Assert(!string.IsNullOrEmpty(separator), "!string.IsNullOrEmpty(separator)"); + Debug.Assert(!string.IsNullOrEmpty(separator), "!string.IsNullOrEmpty(separator)"); int foundCount = 0; int sepListCount = sepList.Length; @@ -1334,9 +1395,8 @@ namespace System // sepList -- an array of ints for split string indicies. // lengthList -- an array of ints for split string lengths. //-------------------------------------------------------------------- - [System.Security.SecuritySafeCritical] // auto-generated private unsafe int MakeSeparatorList(String[] separators, int[] sepList, int[] lengthList) { - Contract.Assert(separators != null && separators.Length > 0, "separators != null && separators.Length > 0"); + Debug.Assert(separators != null && separators.Length > 0, "separators != null && separators.Length > 0"); int foundCount = 0; int sepListCount = sepList.Length; @@ -1374,24 +1434,23 @@ namespace System // Returns a substring of this string. // - [System.Security.SecuritySafeCritical] // auto-generated public String Substring(int startIndex, int length) { //Bounds Checking. if (startIndex < 0) { - throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_StartIndex")); + throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndex")); } if (startIndex > Length) { - throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_StartIndexLargerThanLength")); + throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndexLargerThanLength")); } if (length < 0) { - throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_NegativeLength")); + throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_NegativeLength")); } if (startIndex > Length - length) { - throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_IndexLength")); + throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_IndexLength")); } Contract.EndContractBlock(); @@ -1406,10 +1465,9 @@ namespace System return InternalSubString(startIndex, length); } - [System.Security.SecurityCritical] // auto-generated unsafe string InternalSubString(int startIndex, int length) { - Contract.Assert( startIndex >= 0 && startIndex <= this.Length, "StartIndex is out of range!"); - Contract.Assert( length >= 0 && startIndex <= this.Length - length, "length is out of range!"); + Debug.Assert( startIndex >= 0 && startIndex <= this.Length, "StartIndex is out of range!"); + Debug.Assert( length >= 0 && startIndex <= this.Length - length, "length is out of range!"); String result = FastAllocateString(length); @@ -1434,7 +1492,7 @@ namespace System public String ToLower(CultureInfo culture) { if (culture == null) { - throw new ArgumentNullException("culture"); + throw new ArgumentNullException(nameof(culture)); } Contract.Ensures(Contract.Result<String>() != null); Contract.EndContractBlock(); @@ -1463,7 +1521,7 @@ namespace System public String ToUpper(CultureInfo culture) { if (culture == null) { - throw new ArgumentNullException("culture"); + throw new ArgumentNullException(nameof(culture)); } Contract.Ensures(Contract.Result<String>() != null); Contract.EndContractBlock(); @@ -1517,7 +1575,6 @@ namespace System } - [System.Security.SecuritySafeCritical] // auto-generated private String TrimHelper(int trimType) { //end will point to the first non-trimmed character on the right //start will point to the first non-trimmed character on the Left @@ -1541,7 +1598,6 @@ namespace System } - [System.Security.SecuritySafeCritical] // auto-generated private String TrimHelper(char[] trimChars, int trimType) { //end will point to the first non-trimmed character on the right //start will point to the first non-trimmed character on the Left @@ -1579,7 +1635,6 @@ namespace System } - [System.Security.SecurityCritical] // auto-generated private String CreateTrimmedString(int start, int end) { int len = end -start + 1; if (len == this.Length) { |