diff options
Diffstat (limited to 'src/mscorlib/src/System/String.Manipulation.cs')
-rw-r--r-- | src/mscorlib/src/System/String.Manipulation.cs | 634 |
1 files changed, 411 insertions, 223 deletions
diff --git a/src/mscorlib/src/System/String.Manipulation.cs b/src/mscorlib/src/System/String.Manipulation.cs index e06141d669..33e341c58e 100644 --- a/src/mscorlib/src/System/String.Manipulation.cs +++ b/src/mscorlib/src/System/String.Manipulation.cs @@ -18,18 +18,21 @@ namespace System { Contract.Requires(dest != null); Contract.Requires(src != null); - if (src.Length > dest.Length - destPos) { + if (src.Length > dest.Length - destPos) + { throw new IndexOutOfRangeException(); } Contract.EndContractBlock(); - fixed(char *pDest = &dest.m_firstChar) - fixed (char *pSrc = &src.m_firstChar) { - wstrcpy(pDest + destPos, pSrc, src.Length); - } + fixed (char* pDest = &dest.m_firstChar) + fixed (char* pSrc = &src.m_firstChar) + { + wstrcpy(pDest + destPos, pSrc, src.Length); + } } - public static String Concat(Object arg0) { + public static String Concat(Object arg0) + { Contract.Ensures(Contract.Result<String>() != null); Contract.EndContractBlock(); @@ -39,8 +42,9 @@ namespace System } return arg0.ToString(); } - - public static String Concat(Object arg0, Object arg1) { + + public static String Concat(Object arg0, Object arg1) + { Contract.Ensures(Contract.Result<String>() != null); Contract.EndContractBlock(); @@ -48,14 +52,16 @@ namespace System { arg0 = String.Empty; } - - if (arg1==null) { + + if (arg1 == null) + { arg1 = String.Empty; } return Concat(arg0.ToString(), arg1.ToString()); } - - public static String Concat(Object arg0, Object arg1, Object arg2) { + + public static String Concat(Object arg0, Object arg1, Object arg2) + { Contract.Ensures(Contract.Result<String>() != null); Contract.EndContractBlock(); @@ -63,42 +69,45 @@ namespace System { arg0 = String.Empty; } - - if (arg1==null) { + + if (arg1 == null) + { arg1 = String.Empty; } - - if (arg2==null) { + + if (arg2 == null) + { arg2 = String.Empty; } - + return Concat(arg0.ToString(), arg1.ToString(), arg2.ToString()); } - [CLSCompliant(false)] - public static String Concat(Object arg0, Object arg1, Object arg2, Object arg3, __arglist) + [CLSCompliant(false)] + public static String Concat(Object arg0, Object arg1, Object arg2, Object arg3, __arglist) { Contract.Ensures(Contract.Result<String>() != null); Contract.EndContractBlock(); - Object[] objArgs; - int argCount; - + Object[] objArgs; + int argCount; + ArgIterator args = new ArgIterator(__arglist); //+4 to account for the 4 hard-coded arguments at the beginning of the list. argCount = args.GetRemainingCount() + 4; - + objArgs = new Object[argCount]; - + //Handle the hard-coded arguments objArgs[0] = arg0; objArgs[1] = arg1; objArgs[2] = arg2; objArgs[3] = arg3; - + //Walk all of the args in the variable part of the argument list. - for (int i=4; i<argCount; i++) { + for (int i = 4; i < argCount; i++) + { objArgs[i] = TypedReference.ToObject(args.GetNextArg()); } @@ -131,7 +140,7 @@ namespace System // linked-list style implementation) var strings = new string[args.Length]; - + int totalLength = 0; for (int i = 0; i < args.Length; i++) @@ -183,7 +192,7 @@ namespace System { if (!en.MoveNext()) return string.Empty; - + // We called MoveNext once, so this will be the first item T currentValue = en.Current; @@ -203,7 +212,7 @@ namespace System } StringBuilder result = StringBuilderCache.Acquire(); - + result.Append(firstString); do @@ -233,7 +242,7 @@ namespace System { if (!en.MoveNext()) return string.Empty; - + string firstValue = en.Current; if (!en.MoveNext()) @@ -255,35 +264,40 @@ namespace System } - public static String Concat(String str0, String str1) { + public static String Concat(String str0, String str1) + { Contract.Ensures(Contract.Result<String>() != null); Contract.Ensures(Contract.Result<String>().Length == (str0 == null ? 0 : str0.Length) + (str1 == null ? 0 : str1.Length)); Contract.EndContractBlock(); - if (IsNullOrEmpty(str0)) { - if (IsNullOrEmpty(str1)) { + if (IsNullOrEmpty(str0)) + { + if (IsNullOrEmpty(str1)) + { return String.Empty; } return str1; } - if (IsNullOrEmpty(str1)) { + if (IsNullOrEmpty(str1)) + { return str0; } int str0Length = str0.Length; - + String result = FastAllocateString(str0Length + str1.Length); - - FillStringChecked(result, 0, str0); + + FillStringChecked(result, 0, str0); FillStringChecked(result, str0Length, str1); - + return result; } - public static String Concat(String str0, String str1, String str2) { + public static String Concat(String str0, String str1, String str2) + { Contract.Ensures(Contract.Result<String>() != null); Contract.Ensures(Contract.Result<String>().Length == (str0 == null ? 0 : str0.Length) + @@ -316,9 +330,10 @@ namespace System return result; } - public static String Concat(String str0, String str1, String str2, String str3) { + public static String Concat(String str0, String str1, String str2, String str3) + { Contract.Ensures(Contract.Result<String>() != null); - Contract.Ensures(Contract.Result<String>().Length == + Contract.Ensures(Contract.Result<String>().Length == (str0 == null ? 0 : str0.Length) + (str1 == null ? 0 : str1.Length) + (str2 == null ? 0 : str2.Length) + @@ -356,7 +371,8 @@ namespace System return result; } - public static String Concat(params String[] values) { + public static String Concat(params String[] values) + { if (values == null) throw new ArgumentNullException(nameof(values)); Contract.Ensures(Contract.Result<String>() != null); @@ -424,23 +440,27 @@ namespace System // fall back should be extremely rare. return copiedLength == totalLength ? result : Concat((string[])values.Clone()); } - - public static String Format(String format, Object arg0) { + + public static String Format(String format, Object arg0) + { Contract.Ensures(Contract.Result<String>() != null); return FormatHelper(null, format, new ParamsArray(arg0)); } - - public static String Format(String format, Object arg0, Object arg1) { + + public static String Format(String format, Object arg0, Object arg1) + { Contract.Ensures(Contract.Result<String>() != null); return FormatHelper(null, format, new ParamsArray(arg0, arg1)); } - - public static String Format(String format, Object arg0, Object arg1, Object arg2) { + + public static String Format(String format, Object arg0, Object arg1, Object arg2) + { Contract.Ensures(Contract.Result<String>() != null); return FormatHelper(null, format, new ParamsArray(arg0, arg1, arg2)); } - public static String Format(String format, params Object[] args) { + public static String Format(String format, params Object[] args) + { if (args == null) { // To preserve the original exception behavior, throw an exception about format if both @@ -449,26 +469,30 @@ namespace System } Contract.Ensures(Contract.Result<String>() != null); Contract.EndContractBlock(); - + return FormatHelper(null, format, new ParamsArray(args)); } - - public static String Format(IFormatProvider provider, String format, Object arg0) { + + public static String Format(IFormatProvider provider, String format, Object arg0) + { Contract.Ensures(Contract.Result<String>() != null); return FormatHelper(provider, format, new ParamsArray(arg0)); } - - public static String Format(IFormatProvider provider, String format, Object arg0, Object arg1) { + + public static String Format(IFormatProvider provider, String format, Object arg0, Object arg1) + { Contract.Ensures(Contract.Result<String>() != null); return FormatHelper(provider, format, new ParamsArray(arg0, arg1)); } - - public static String Format(IFormatProvider provider, String format, Object arg0, Object arg1, Object arg2) { + + public static String Format(IFormatProvider provider, String format, Object arg0, Object arg1, Object arg2) + { Contract.Ensures(Contract.Result<String>() != null); return FormatHelper(provider, format, new ParamsArray(arg0, arg1, arg2)); } - public static String Format(IFormatProvider provider, String format, params Object[] args) { + public static String Format(IFormatProvider provider, String format, params Object[] args) + { if (args == null) { // To preserve the original exception behavior, throw an exception about format if both @@ -477,20 +501,21 @@ namespace System } Contract.Ensures(Contract.Result<String>() != null); Contract.EndContractBlock(); - + return FormatHelper(provider, format, new ParamsArray(args)); } - - private static String FormatHelper(IFormatProvider provider, String format, ParamsArray args) { + + private static String FormatHelper(IFormatProvider provider, String format, ParamsArray args) + { if (format == null) throw new ArgumentNullException(nameof(format)); - + return StringBuilderCache.GetStringAndRelease( StringBuilderCache .Acquire(format.Length + args.Length * 8) .AppendFormatHelper(provider, format, args)); } - + public String Insert(int startIndex, String value) { if (value == null) @@ -500,15 +525,15 @@ namespace System Contract.Ensures(Contract.Result<String>() != null); Contract.Ensures(Contract.Result<String>().Length == this.Length + value.Length); Contract.EndContractBlock(); - + int oldLength = Length; int insertLength = value.Length; - + if (oldLength == 0) return value; if (insertLength == 0) return this; - + // In case this computation overflows, newLength will be negative and FastAllocateString throws OutOfMemoryException int newLength = oldLength + insertLength; String result = FastAllocateString(newLength); @@ -557,7 +582,7 @@ namespace System // 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) @@ -686,7 +711,7 @@ namespace System { return string.Empty; } - + // We called MoveNext once, so this will be the first item T currentValue = en.Current; @@ -738,17 +763,17 @@ namespace System } if (startIndex < 0) { - throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndex")); + throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_StartIndex); } if (count < 0) { - throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NegativeCount")); + throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NegativeCount); } if (startIndex > value.Length - count) { - throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer")); + throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_IndexCountBuffer); } - + if (count <= 1) { return count == 0 ? @@ -803,7 +828,7 @@ namespace System FillStringChecked(result, copiedLength, currentValue); copiedLength += valueLen; } - + if (i < end - 1) { // Fill in the separator. @@ -833,18 +858,20 @@ namespace System result : JoinCore(separator, separatorLength, (string[])value.Clone(), startIndex, count); } - + // // [Pure] - public String PadLeft(int totalWidth) { + public String PadLeft(int totalWidth) + { return PadLeft(totalWidth, ' '); } [Pure] - public String PadLeft(int totalWidth, char paddingChar) { + public String PadLeft(int totalWidth, char paddingChar) + { if (totalWidth < 0) - throw new ArgumentOutOfRangeException(nameof(totalWidth), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(totalWidth), SR.ArgumentOutOfRange_NeedNonNegNum); int oldLength = Length; int count = totalWidth - oldLength; if (count <= 0) @@ -866,14 +893,16 @@ namespace System } [Pure] - public String PadRight(int totalWidth) { + public String PadRight(int totalWidth) + { return PadRight(totalWidth, ' '); } [Pure] - public String PadRight(int totalWidth, char paddingChar) { + public String PadRight(int totalWidth, char paddingChar) + { if (totalWidth < 0) - throw new ArgumentOutOfRangeException(nameof(totalWidth), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(totalWidth), SR.ArgumentOutOfRange_NeedNonNegNum); int oldLength = Length; int count = totalWidth - oldLength; if (count <= 0) @@ -897,24 +926,24 @@ namespace System public String Remove(int startIndex, int count) { if (startIndex < 0) - throw new ArgumentOutOfRangeException(nameof(startIndex), - Environment.GetResourceString("ArgumentOutOfRange_StartIndex")); + throw new ArgumentOutOfRangeException(nameof(startIndex), + SR.ArgumentOutOfRange_StartIndex); if (count < 0) - throw new ArgumentOutOfRangeException(nameof(count), - Environment.GetResourceString("ArgumentOutOfRange_NegativeCount")); + throw new ArgumentOutOfRangeException(nameof(count), + SR.ArgumentOutOfRange_NegativeCount); if (count > Length - startIndex) - throw new ArgumentOutOfRangeException(nameof(count), - Environment.GetResourceString("ArgumentOutOfRange_IndexCount")); + throw new ArgumentOutOfRangeException(nameof(count), + SR.ArgumentOutOfRange_IndexCount); Contract.Ensures(Contract.Result<String>() != null); Contract.Ensures(Contract.Result<String>().Length == this.Length - count); Contract.EndContractBlock(); - + if (count == 0) return this; int newLength = Length - count; if (newLength == 0) return String.Empty; - + String result = FastAllocateString(newLength); unsafe { @@ -931,22 +960,113 @@ namespace System } // a remove that just takes a startindex. - public string Remove( int startIndex ) { - if (startIndex < 0) { - throw new ArgumentOutOfRangeException(nameof(startIndex), - Environment.GetResourceString("ArgumentOutOfRange_StartIndex")); + public string Remove(int startIndex) + { + if (startIndex < 0) + { + throw new ArgumentOutOfRangeException(nameof(startIndex), + SR.ArgumentOutOfRange_StartIndex); } - - if (startIndex >= Length) { - throw new ArgumentOutOfRangeException(nameof(startIndex), - Environment.GetResourceString("ArgumentOutOfRange_StartIndexLessThanLength")); + + if (startIndex >= Length) + { + throw new ArgumentOutOfRangeException(nameof(startIndex), + SR.ArgumentOutOfRange_StartIndexLessThanLength); } - + Contract.Ensures(Contract.Result<String>() != null); Contract.EndContractBlock(); return Substring(0, startIndex); - } + } + + public string Replace(string oldValue, string newValue, bool ignoreCase, CultureInfo culture) + { + Contract.Ensures(Contract.Result<String>() != null); + Contract.EndContractBlock(); + + return ReplaceCore(oldValue, newValue, culture, ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None); + } + + public string Replace(string oldValue, string newValue, StringComparison comparisonType) + { + Contract.Ensures(Contract.Result<String>() != null); + Contract.EndContractBlock(); + + switch (comparisonType) + { + case StringComparison.CurrentCulture: + return ReplaceCore(oldValue, newValue, CultureInfo.CurrentCulture, CompareOptions.None); + + case StringComparison.CurrentCultureIgnoreCase: + return ReplaceCore(oldValue, newValue, CultureInfo.CurrentCulture, CompareOptions.IgnoreCase); + + case StringComparison.InvariantCulture: + return ReplaceCore(oldValue, newValue, CultureInfo.InvariantCulture, CompareOptions.None); + + case StringComparison.InvariantCultureIgnoreCase: + return ReplaceCore(oldValue, newValue, CultureInfo.InvariantCulture, CompareOptions.IgnoreCase); + + case StringComparison.Ordinal: + return ReplaceCore(oldValue, newValue, CultureInfo.InvariantCulture, CompareOptions.Ordinal); + + case StringComparison.OrdinalIgnoreCase: + return ReplaceCore(oldValue, newValue, CultureInfo.InvariantCulture, CompareOptions.OrdinalIgnoreCase); + + default: + throw new ArgumentException(SR.NotSupported_StringComparison, nameof(comparisonType)); + } + } + + private unsafe String ReplaceCore(string oldValue, string newValue, CultureInfo culture, CompareOptions options) + { + if (oldValue == null) + throw new ArgumentNullException(nameof(oldValue)); + + // If they asked to replace oldValue with a null, replace all occurences + // with the empty string. + if (newValue == null) + newValue = string.Empty; + + CultureInfo referenceCulture = culture ?? CultureInfo.CurrentCulture; + StringBuilder result = StringBuilderCache.Acquire(); + + int startIndex = 0; + int index = 0; + + int matchLength = 0; + + bool hasDoneAnyReplacements = false; + + do + { + index = referenceCulture.CompareInfo.IndexOfCore(this, oldValue, startIndex, m_stringLength - startIndex, options, &matchLength); + if (index >= 0) + { + // append the unmodified portion of string + result.Append(this, startIndex, index - startIndex); + + // append the replacement + result.Append(newValue); + + startIndex = index + matchLength; + hasDoneAnyReplacements = true; + } + else if (!hasDoneAnyReplacements) + { + // small optimization, + // if we have not done any replacements, + // we will return the original string + return this; + } + else + { + result.Append(this, startIndex, m_stringLength - startIndex); + } + } while (index >= 0); + + return StringBuilderCache.GetStringAndRelease(result); + } // Replaces all instances of oldChar with newChar. // @@ -1034,12 +1154,14 @@ namespace System return ReplaceInternal(oldValue, newValue); } - public unsafe String[] Split(char separator, StringSplitOptions options = StringSplitOptions.None) { + public unsafe String[] Split(char separator, StringSplitOptions options = StringSplitOptions.None) + { Contract.Ensures(Contract.Result<String[]>() != null); return SplitInternal(&separator, 1, int.MaxValue, options); } - public unsafe String[] Split(char separator, int count, StringSplitOptions options = StringSplitOptions.None) { + public unsafe String[] Split(char separator, int count, StringSplitOptions options = StringSplitOptions.None) + { Contract.Ensures(Contract.Result<String[]>() != null); return SplitInternal(&separator, 1, count, options); } @@ -1053,7 +1175,8 @@ namespace System // If the separator is null // whitespace (i.e., Character.IsWhitespace) is used as the separator. // - public String [] Split(params char [] separator) { + public String[] Split(params char[] separator) + { Contract.Ensures(Contract.Result<String[]>() != null); return SplitInternal(separator, Int32.MaxValue, StringSplitOptions.None); } @@ -1069,12 +1192,14 @@ namespace System // If there are more than count different strings, the last n-(count-1) // elements are concatenated and added as the last String. // - public string[] Split(char[] separator, int count) { + public string[] Split(char[] separator, int count) + { Contract.Ensures(Contract.Result<String[]>() != null); return SplitInternal(separator, count, StringSplitOptions.None); } - public String[] Split(char[] separator, StringSplitOptions options) { + public String[] Split(char[] separator, StringSplitOptions options) + { Contract.Ensures(Contract.Result<String[]>() != null); return SplitInternal(separator, Int32.MaxValue, options); } @@ -1098,72 +1223,79 @@ namespace System { if (count < 0) throw new ArgumentOutOfRangeException(nameof(count), - Environment.GetResourceString("ArgumentOutOfRange_NegativeCount")); + SR.ArgumentOutOfRange_NegativeCount); if (options < StringSplitOptions.None || options > StringSplitOptions.RemoveEmptyEntries) - throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", options)); + throw new ArgumentException(SR.Format(SR.Arg_EnumIllegalVal, options)); Contract.Ensures(Contract.Result<String[]>() != null); Contract.EndContractBlock(); bool omitEmptyEntries = (options == StringSplitOptions.RemoveEmptyEntries); - if ((count == 0) || (omitEmptyEntries && this.Length == 0)) + if ((count == 0) || (omitEmptyEntries && this.Length == 0)) { - return EmptyArray<String>.Value; + return Array.Empty<String>(); } if (count == 1) { return new String[] { this }; } - + int[] sepList = new int[Length]; int numReplaces = MakeSeparatorList(separators, separatorsLength, sepList); - + // Handle the special case of no replaces. - if (0 == numReplaces) { + if (0 == numReplaces) + { return new String[] { this }; } - if(omitEmptyEntries) + if (omitEmptyEntries) { return SplitOmitEmptyEntries(sepList, null, 1, numReplaces, count); } - else + else { return SplitKeepEmptyEntries(sepList, null, 1, numReplaces, count); } } - public String[] Split(String separator, StringSplitOptions options = StringSplitOptions.None) { + public String[] Split(String separator, StringSplitOptions options = StringSplitOptions.None) + { Contract.Ensures(Contract.Result<String[]>() != null); return SplitInternal(separator ?? String.Empty, null, Int32.MaxValue, options); } - public String[] Split(String separator, Int32 count, StringSplitOptions options = StringSplitOptions.None) { + 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); } - public String [] Split(String[] separator, StringSplitOptions options) { + public String[] Split(String[] separator, StringSplitOptions options) + { Contract.Ensures(Contract.Result<String[]>() != null); return SplitInternal(null, separator, Int32.MaxValue, options); } - public String[] Split(String[] separator, Int32 count, StringSplitOptions options) { + public String[] Split(String[] separator, Int32 count, StringSplitOptions options) + { Contract.Ensures(Contract.Result<String[]>() != null); return SplitInternal(null, separator, count, options); } private String[] SplitInternal(String separator, String[] separators, Int32 count, StringSplitOptions options) { - if (count < 0) { + if (count < 0) + { throw new ArgumentOutOfRangeException(nameof(count), - Environment.GetResourceString("ArgumentOutOfRange_NegativeCount")); + SR.ArgumentOutOfRange_NegativeCount); } - if (options < StringSplitOptions.None || options > StringSplitOptions.RemoveEmptyEntries) { - throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)options)); + if (options < StringSplitOptions.None || options > StringSplitOptions.RemoveEmptyEntries) + { + throw new ArgumentException(SR.Format(SR.Arg_EnumIllegalVal, (int)options)); } Contract.EndContractBlock(); @@ -1171,15 +1303,18 @@ namespace System bool singleSeparator = separator != null; - if (!singleSeparator && (separators == null || separators.Length == 0)) { - return SplitInternal((char[]) null, count, options); + if (!singleSeparator && (separators == null || separators.Length == 0)) + { + return SplitInternal((char[])null, count, options); } - - if ((count == 0) || (omitEmptyEntries && this.Length ==0)) { - return EmptyArray<String>.Value; + + if ((count == 0) || (omitEmptyEntries && this.Length == 0)) + { + return Array.Empty<String>(); } - if (count == 1 || (singleSeparator && separator.Length == 0)) { + if (count == 1 || (singleSeparator && separator.Length == 0)) + { return new String[] { this }; } @@ -1188,40 +1323,46 @@ namespace System int defaultLength; int numReplaces; - if (singleSeparator) { + if (singleSeparator) + { lengthList = null; defaultLength = separator.Length; numReplaces = MakeSeparatorList(separator, sepList); } - else { + else + { lengthList = new int[Length]; defaultLength = 0; numReplaces = MakeSeparatorList(separators, sepList, lengthList); } // Handle the special case of no replaces. - if (0 == numReplaces) { + if (0 == numReplaces) + { return new String[] { this }; } - - if (omitEmptyEntries) { + + if (omitEmptyEntries) + { return SplitOmitEmptyEntries(sepList, lengthList, defaultLength, numReplaces, count); } - else { + else + { return SplitKeepEmptyEntries(sepList, lengthList, defaultLength, numReplaces, count); } - } - + } + // Note a special case in this function: // If there is no separator in the string, a string array which only contains // the original string will be returned regardless of the count. // - private String[] SplitKeepEmptyEntries(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); - + int currIndex = 0; int arrIndex = 0; @@ -1230,30 +1371,33 @@ namespace System //Allocate space for the new array. //+1 for the string from the end of the last replace to the end of the String. - String[] splitStrings = new String[numActualReplaces+1]; + String[] splitStrings = new String[numActualReplaces + 1]; - for (int i = 0; i < numActualReplaces && currIndex < Length; i++) { - splitStrings[arrIndex++] = Substring(currIndex, sepList[i]-currIndex ); - currIndex=sepList[i] + ((lengthList == null) ? defaultLength : lengthList[i]); + for (int i = 0; i < numActualReplaces && currIndex < Length; i++) + { + splitStrings[arrIndex++] = Substring(currIndex, sepList[i] - currIndex); + currIndex = sepList[i] + ((lengthList == null) ? defaultLength : lengthList[i]); } //Handle the last string at the end of the array if there is one. - if (currIndex < Length && numActualReplaces >= 0) { + if (currIndex < Length && numActualReplaces >= 0) + { splitStrings[arrIndex] = Substring(currIndex); - } - else if (arrIndex==numActualReplaces) { + } + else if (arrIndex == numActualReplaces) + { //We had a separator character at the end of a string. Rather than just allowing //a null character, we'll replace the last element in the array with an empty string. splitStrings[arrIndex] = String.Empty; - } return splitStrings; } - + // This function will not keep the Empty String - private String[] SplitOmitEmptyEntries(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); @@ -1262,20 +1406,24 @@ namespace System // filled completely in this function, we will create a // new array and copy string references to that new array. - int maxItems = (numReplaces < count) ? (numReplaces+1): count ; + int maxItems = (numReplaces < count) ? (numReplaces + 1) : count; String[] splitStrings = new String[maxItems]; int currIndex = 0; int arrIndex = 0; - for(int i=0; i< numReplaces && currIndex < Length; i++) { - if( sepList[i]-currIndex > 0) { - splitStrings[arrIndex++] = Substring(currIndex, sepList[i]-currIndex ); + for (int i = 0; i < numReplaces && currIndex < Length; i++) + { + if (sepList[i] - currIndex > 0) + { + splitStrings[arrIndex++] = Substring(currIndex, sepList[i] - currIndex); } - currIndex=sepList[i] + ((lengthList == null) ? defaultLength : lengthList[i]); - if( arrIndex == count -1 ) { + currIndex = sepList[i] + ((lengthList == null) ? defaultLength : lengthList[i]); + if (arrIndex == count - 1) + { // If all the remaining entries at the end are empty, skip them - while( i < numReplaces - 1 && currIndex == sepList[++i]) { + while (i < numReplaces - 1 && currIndex == sepList[++i]) + { currIndex += ((lengthList == null) ? defaultLength : lengthList[i]); } break; @@ -1286,19 +1434,22 @@ namespace System Debug.Assert(arrIndex < maxItems); //Handle the last string at the end of the array if there is one. - if (currIndex< Length) { + if (currIndex < Length) + { splitStrings[arrIndex++] = Substring(currIndex); } String[] stringArray = splitStrings; - if( arrIndex!= maxItems) { + if (arrIndex != maxItems) + { stringArray = new String[arrIndex]; - for( int j = 0; j < arrIndex; j++) { + for (int j = 0; j < arrIndex; j++) + { stringArray[j] = splitStrings[j]; - } + } } return stringArray; - } + } //-------------------------------------------------------------------- // This function returns the number of the places within this instance where @@ -1306,56 +1457,71 @@ namespace System // Args: separator -- A string containing all of the split characters. // sepList -- an array of ints for split char indicies. //-------------------------------------------------------------------- - private unsafe int MakeSeparatorList(char* separators, int separatorsLength, int[] sepList) { + private unsafe int MakeSeparatorList(char* separators, int separatorsLength, int[] sepList) + { Debug.Assert(separatorsLength >= 0, "separatorsLength >= 0"); - int foundCount=0; + int foundCount = 0; - if (separators == null || separatorsLength == 0) { - fixed (char* pwzChars = &this.m_firstChar) { + if (separators == null || separatorsLength == 0) + { + fixed (char* pwzChars = &m_firstChar) + { //If they passed null or an empty string, look for whitespace. - for (int i=0; i < Length && foundCount < sepList.Length; i++) { - if (Char.IsWhiteSpace(pwzChars[i])) { - sepList[foundCount++]=i; + for (int i = 0; i < Length && foundCount < sepList.Length; i++) + { + if (Char.IsWhiteSpace(pwzChars[i])) + { + sepList[foundCount++] = i; } } } - } - else { + } + else + { int sepListCount = sepList.Length; //If they passed in a string of chars, actually look for those chars. - fixed (char* pwzChars = &this.m_firstChar) { - for (int i=0; i< Length && foundCount < sepListCount; i++) { + fixed (char* pwzChars = &m_firstChar) + { + for (int i = 0; i < Length && foundCount < sepListCount; i++) + { char* pSep = separators; - for (int j = 0; j < separatorsLength; j++, pSep++) { - if ( pwzChars[i] == *pSep) { - sepList[foundCount++]=i; - break; - } + for (int j = 0; j < separatorsLength; j++, pSep++) + { + if (pwzChars[i] == *pSep) + { + sepList[foundCount++] = i; + break; + } } } } } return foundCount; - } - + } + //-------------------------------------------------------------------- // This function returns number of the places within baseString where // instances of the separator string occurs. // Args: separator -- the separator // sepList -- an array of ints for split string indicies. //-------------------------------------------------------------------- - private unsafe int MakeSeparatorList(string separator, int[] sepList) { + private unsafe int MakeSeparatorList(string separator, int[] sepList) + { Debug.Assert(!string.IsNullOrEmpty(separator), "!string.IsNullOrEmpty(separator)"); int foundCount = 0; int sepListCount = sepList.Length; int currentSepLength = separator.Length; - fixed (char* pwzChars = &this.m_firstChar) { - for (int i = 0; i < Length && foundCount < sepListCount; i++) { - if (pwzChars[i] == separator[0] && currentSepLength <= Length - i) { + fixed (char* pwzChars = &m_firstChar) + { + for (int i = 0; i < Length && foundCount < sepListCount; i++) + { + if (pwzChars[i] == separator[0] && currentSepLength <= Length - i) + { if (currentSepLength == 1 - || String.CompareOrdinal(this, i, separator, 0, currentSepLength) == 0) { + || String.CompareOrdinal(this, i, separator, 0, currentSepLength) == 0) + { sepList[foundCount] = i; foundCount++; i += currentSepLength - 1; @@ -1373,24 +1539,31 @@ namespace System // sepList -- an array of ints for split string indicies. // lengthList -- an array of ints for split string lengths. //-------------------------------------------------------------------- - private unsafe int MakeSeparatorList(String[] separators, int[] sepList, int[] lengthList) { + private unsafe int MakeSeparatorList(String[] separators, int[] sepList, int[] lengthList) + { Debug.Assert(separators != null && separators.Length > 0, "separators != null && separators.Length > 0"); - + int foundCount = 0; int sepListCount = sepList.Length; int sepCount = separators.Length; - fixed (char* pwzChars = &this.m_firstChar) { - for (int i=0; i< Length && foundCount < sepListCount; i++) { - for( int j =0; j < separators.Length; j++) { + fixed (char* pwzChars = &m_firstChar) + { + for (int i = 0; i < Length && foundCount < sepListCount; i++) + { + for (int j = 0; j < separators.Length; j++) + { String separator = separators[j]; - if (String.IsNullOrEmpty(separator)) { + if (String.IsNullOrEmpty(separator)) + { continue; } Int32 currentSepLength = separator.Length; - if ( pwzChars[i] == separator[0] && currentSepLength <= Length - i) { - if (currentSepLength == 1 - || String.CompareOrdinal(this, i, separator, 0, currentSepLength) == 0) { + if (pwzChars[i] == separator[0] && currentSepLength <= Length - i) + { + if (currentSepLength == 1 + || String.CompareOrdinal(this, i, separator, 0, currentSepLength) == 0) + { sepList[foundCount] = i; lengthList[foundCount] = currentSepLength; foundCount++; @@ -1403,71 +1576,82 @@ namespace System } return foundCount; } - + // Returns a substring of this string. // - public String Substring (int startIndex) { - return this.Substring (startIndex, Length-startIndex); + public String Substring(int startIndex) + { + return this.Substring(startIndex, Length - startIndex); } - + // Returns a substring of this string. // - public String Substring(int startIndex, int length) { - + public String Substring(int startIndex, int length) + { //Bounds Checking. - if (startIndex < 0) { - throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndex")); + if (startIndex < 0) + { + throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_StartIndex); } - if (startIndex > Length) { - throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndexLargerThanLength")); + if (startIndex > Length) + { + throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_StartIndexLargerThanLength); } - if (length < 0) { - throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_NegativeLength")); + if (length < 0) + { + throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_NegativeLength); } - if (startIndex > Length - length) { - throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_IndexLength")); + if (startIndex > Length - length) + { + throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_IndexLength); } Contract.EndContractBlock(); - if( length == 0) { + if (length == 0) + { return String.Empty; } - if( startIndex == 0 && length == this.Length) { + if (startIndex == 0 && length == this.Length) + { return this; } return InternalSubString(startIndex, length); } - unsafe string InternalSubString(int startIndex, int length) { - 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!"); - + private unsafe string InternalSubString(int startIndex, int length) + { + 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); - fixed(char* dest = &result.m_firstChar) - fixed(char* src = &this.m_firstChar) { - wstrcpy(dest, src + startIndex, length); - } + fixed (char* dest = &result.m_firstChar) + fixed (char* src = &m_firstChar) + { + wstrcpy(dest, src + startIndex, length); + } return result; } - + // Creates a copy of this string in lower case. [Pure] - public String ToLower() { + public String ToLower() + { Contract.Ensures(Contract.Result<String>() != null); Contract.EndContractBlock(); return this.ToLower(CultureInfo.CurrentCulture); } - + // Creates a copy of this string in lower case. The culture is set by culture. [Pure] - public String ToLower(CultureInfo culture) { + public String ToLower(CultureInfo culture) + { if (culture == null) { throw new ArgumentNullException(nameof(culture)); @@ -1479,24 +1663,27 @@ namespace System // Creates a copy of this string in lower case based on invariant culture. [Pure] - public String ToLowerInvariant() { + public String ToLowerInvariant() + { Contract.Ensures(Contract.Result<String>() != null); Contract.EndContractBlock(); return this.ToLower(CultureInfo.InvariantCulture); } - + // Creates a copy of this string in upper case. [Pure] - public String ToUpper() { + public String ToUpper() + { Contract.Ensures(Contract.Result<String>() != null); Contract.EndContractBlock(); return this.ToUpper(CultureInfo.CurrentCulture); } - + // Creates a copy of this string in upper case. The culture is set by culture. [Pure] - public String ToUpper(CultureInfo culture) { + public String ToUpper(CultureInfo culture) + { if (culture == null) { throw new ArgumentNullException(nameof(culture)); @@ -1509,7 +1696,8 @@ namespace System //Creates a copy of this string in upper case based on invariant culture. [Pure] - public String ToUpperInvariant() { + public String ToUpperInvariant() + { Contract.Ensures(Contract.Result<String>() != null); Contract.EndContractBlock(); return this.ToUpper(CultureInfo.InvariantCulture); |