Skip to content
This repository was archived by the owner on Nov 1, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2468,7 +2468,7 @@ internal TokenHashValue[] CreateTokenHashTable()
case DateTimeFormatInfoScanner.IgnorableSymbolChar:
String symbol = dateWords[i].Substring(1);
InsertHash(temp, symbol, TokenType.IgnorableSymbol, 0);
if (this.DateSeparator.Trim(null).Equals(symbol))
if (this.DateSeparator.Trim().Equals(symbol))
{
// The date separator is the same as the ignorable symbol.
useDateSepAsIgnorableSymbol = true;
Expand Down Expand Up @@ -2868,7 +2868,7 @@ private void InsertHash(TokenHashValue[] hashTable, String str, TokenType tokenT
// DateTime.Parse().
if (Char.IsWhiteSpace(str[0]) || Char.IsWhiteSpace(str[str.Length - 1]))
{
str = str.Trim(null); // Trim white space characters.
str = str.Trim(); // Trim white space characters.
// Could have space for separators
if (str.Length == 0)
return;
Expand Down
160 changes: 95 additions & 65 deletions src/System.Private.CoreLib/src/System/String.Manipulation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ namespace System
{
public partial class String
{
private const int TrimHead = 0;
private const int TrimTail = 1;
private const int TrimBoth = 2;

unsafe private static void FillStringChecked(String dest, int destPos, String src)
{
if (src.Length > dest.Length - destPos)
Expand Down Expand Up @@ -1545,110 +1541,146 @@ public String ToUpperInvariant()
return FormatProvider.ToUpperInvariant(this);
}

// Removes a set of characters from the end of this string.
// Trims the whitespace from both ends of the string. Whitespace is defined by
// Char.IsWhiteSpace.
//
public string Trim() => TrimWhiteSpaceHelper(TrimType.Both);

// Removes a set of characters from the beginning and end of this string.
public unsafe string Trim(char trimChar) => TrimHelper(&trimChar, 1, TrimType.Both);

public String Trim(params char[] trimChars)
// Removes a set of characters from the beginning and end of this string.
public unsafe string Trim(params char[] trimChars)
{
if (null == trimChars || trimChars.Length == 0)
if (trimChars == null || trimChars.Length == 0)
{
return TrimHelper(TrimBoth);
return TrimWhiteSpaceHelper(TrimType.Both);
}
fixed (char* pTrimChars = &trimChars[0])
{
return TrimHelper(pTrimChars, trimChars.Length, TrimType.Both);
}
return TrimHelper(trimChars, TrimBoth);
}

// Removes a set of characters from the beginning of this string.
public String TrimStart(params char[] trimChars)
public string TrimStart() => TrimWhiteSpaceHelper(TrimType.Head);

// Removes a set of characters from the beginning of this string.
public unsafe string TrimStart(char trimChar) => TrimHelper(&trimChar, 1, TrimType.Head);

// Removes a set of characters from the beginning of this string.
public unsafe string TrimStart(params char[] trimChars)
{
if (null == trimChars || trimChars.Length == 0)
if (trimChars == null || trimChars.Length == 0)
{
return TrimWhiteSpaceHelper(TrimType.Head);
}
fixed (char* pTrimChars = &trimChars[0])
{
return TrimHelper(TrimHead);
return TrimHelper(pTrimChars, trimChars.Length, TrimType.Head);
}
return TrimHelper(trimChars, TrimHead);
}

// Removes a set of characters from the end of this string.
public string TrimEnd() => TrimWhiteSpaceHelper(TrimType.Tail);

// Removes a set of characters from the end of this string.
public unsafe string TrimEnd(char trimChar) => TrimHelper(&trimChar, 1, TrimType.Tail);

// Removes a set of characters from the end of this string.
public String TrimEnd(params char[] trimChars)
public unsafe string TrimEnd(params char[] trimChars)
{
if (null == trimChars || trimChars.Length == 0)
if (trimChars == null || trimChars.Length == 0)
{
return TrimHelper(TrimTail);
return TrimWhiteSpaceHelper(TrimType.Tail);
}
fixed (char* pTrimChars = &trimChars[0])
{
return TrimHelper(pTrimChars, trimChars.Length, TrimType.Tail);
}
return TrimHelper(trimChars, TrimTail);
}

// Trims the whitespace from both ends of the string. Whitespace is defined by
// Char.IsWhiteSpace.
//
public String Trim()
{
return TrimHelper(TrimBoth);
}

private String TrimHelper(int trimType)
private string TrimWhiteSpaceHelper(TrimType 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
int end = this.Length - 1;
// end will point to the first non-trimmed character on the right.
// start will point to the first non-trimmed character on the left.
int end = Length - 1;
int start = 0;

//Trim specified characters.
if (trimType != TrimTail)
// Trim specified characters.
if (trimType != TrimType.Tail)
{
for (start = 0; start < this.Length; start++)
for (start = 0; start < Length; start++)
{
if (!Char.IsWhiteSpace(this[start])) break;
if (!char.IsWhiteSpace(this[start]))
{
break;
}
}
}

if (trimType != TrimHead)
if (trimType != TrimType.Head)
{
for (end = Length - 1; end >= start; end--)
{
if (!Char.IsWhiteSpace(this[end])) break;
if (!char.IsWhiteSpace(this[end]))
{
break;
}
}
}

return CreateTrimmedString(start, end);
}

private String TrimHelper(char[] trimChars, int trimType)
private unsafe string TrimHelper(char* trimChars, int trimCharsLength, TrimType 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
int end = this.Length - 1;
Debug.Assert(trimChars != null);
Debug.Assert(trimCharsLength > 0);

// end will point to the first non-trimmed character on the right.
// start will point to the first non-trimmed character on the left.
int end = Length - 1;
int start = 0;

//Trim specified characters.
if (trimType != TrimTail)
// Trim specified characters.
if (trimType != TrimType.Tail)
{
for (start = 0; start < this.Length; start++)
for (start = 0; start < Length; start++)
{
int i = 0;
char ch = this[start];
for (i = 0; i < trimChars.Length; i++)
for (i = 0; i < trimCharsLength; i++)
{
if (trimChars[i] == ch) break;
if (trimChars[i] == ch)
{
break;
}
}
if (i == trimChars.Length)
{ // the character is not white space
if (i == trimCharsLength)
{
// The character is not in trimChars, so stop trimming.
break;
}
}
}

if (trimType != TrimHead)
if (trimType != TrimType.Head)
{
for (end = Length - 1; end >= start; end--)
{
int i = 0;
char ch = this[end];
for (i = 0; i < trimChars.Length; i++)
for (i = 0; i < trimCharsLength; i++)
{
if (trimChars[i] == ch) break;
if (trimChars[i] == ch)
{
break;
}
}
if (i == trimChars.Length)
{ // the character is not white space
if (i == trimCharsLength)
{
// The character is not in trimChars, so stop trimming.
break;
}
}
Expand All @@ -1657,22 +1689,20 @@ private String TrimHelper(char[] trimChars, int trimType)
return CreateTrimmedString(start, end);
}

private String CreateTrimmedString(int start, int end)
private string CreateTrimmedString(int start, int end)
{
int len = end - start + 1;
if (len == this.Length)
{
// Don't allocate a new string as the trimmed string has not changed.
return this;
}
else
{
if (len == 0)
{
return String.Empty;
}
return InternalSubString(start, len);
}
return
len == Length ? this :
len == 0 ? string.Empty :
InternalSubString(start, len);
}

private enum TrimType
{
Head = 0,
Tail = 1,
Both = 2
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -845,7 +845,7 @@ private static string TryGetLocalizedNameByMuiNativeResource(string resource)
string system32 = sb.ToString();

// trim the string "@tzres.dll" => "tzres.dll"
string tzresDll = resources[0].TrimStart(new char[] { '@' });
string tzresDll = resources[0].TrimStart('@');

try
{
Expand Down