e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
245 lines
10 KiB
C#
245 lines
10 KiB
C#
//---------------------------------------------------------------------
|
|
// <copyright file="StringUtil.cs" company="Microsoft">
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// </copyright>
|
|
//
|
|
// @owner [....]
|
|
// @backupOwner [....]
|
|
//---------------------------------------------------------------------
|
|
|
|
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using System.Globalization;
|
|
using System.Diagnostics;
|
|
|
|
namespace System.Data.Common.Utils {
|
|
|
|
// This class provides some useful string utilities, e.g., converting a
|
|
// list to string.
|
|
internal static class StringUtil {
|
|
private const string s_defaultDelimiter = ", ";
|
|
|
|
#region String Conversion - Unsorted
|
|
/// <summary>
|
|
/// Converts an enumeration of values to a delimited string list.
|
|
/// </summary>
|
|
/// <typeparam name="T">Type of elements to convert.</typeparam>
|
|
/// <param name="values">Values. If null, returns empty string.</param>
|
|
/// <param name="converter">Converter. If null, uses default invariant culture converter.</param>
|
|
/// <param name="delimiter">Delimiter. If null, uses default (', ')</param>
|
|
/// <returns>Delimited list of values in string.</returns>
|
|
internal static string BuildDelimitedList<T>(IEnumerable<T> values, ToStringConverter<T> converter, string delimiter) {
|
|
if (null == values) { return String.Empty; }
|
|
if (null == converter) { converter = new ToStringConverter<T>(InvariantConvertToString<T>); }
|
|
if (null == delimiter) { delimiter = s_defaultDelimiter; }
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
bool first = true;
|
|
foreach (T value in values) {
|
|
if (first) { first = false; }
|
|
else { sb.Append(delimiter); }
|
|
sb.Append(converter(value));
|
|
}
|
|
|
|
return sb.ToString();
|
|
}
|
|
|
|
// effects: Converts list to a string separated by a comma with
|
|
// string.Empty used for null values
|
|
internal static string ToCommaSeparatedString(IEnumerable list) {
|
|
return ToSeparatedString(list, s_defaultDelimiter, string.Empty);
|
|
}
|
|
|
|
// effects: Converts list to a string separated by "separator" with
|
|
// "nullValue" used for null values
|
|
internal static string ToSeparatedString(IEnumerable list, string separator, string nullValue) {
|
|
StringBuilder builder = new StringBuilder();
|
|
ToSeparatedString(builder, list, separator, nullValue);
|
|
return builder.ToString();
|
|
}
|
|
#endregion
|
|
|
|
#region String Conversion - Sorted
|
|
// effects: Converts the list to a list of strings, sorts its
|
|
// and then converts to a string separated by a comma with
|
|
// string.Empty used for null values
|
|
internal static string ToCommaSeparatedStringSorted(IEnumerable list) {
|
|
return ToSeparatedStringSorted(list, s_defaultDelimiter, string.Empty);
|
|
}
|
|
|
|
// effects: Converts the list to a list of strings, sorts its using
|
|
// StringComparer.Ordinal
|
|
// and then converts to a string separated by "separator" with
|
|
// with "nullValue" used for null values
|
|
internal static string ToSeparatedStringSorted(IEnumerable list, string separator, string nullValue) {
|
|
StringBuilder builder = new StringBuilder();
|
|
ToSeparatedStringPrivate(builder, list, separator, nullValue, true);
|
|
return builder.ToString();
|
|
}
|
|
#endregion
|
|
|
|
#region StringBuilder routines
|
|
|
|
internal static string MembersToCommaSeparatedString(IEnumerable members)
|
|
{
|
|
StringBuilder builder = new StringBuilder();
|
|
builder.Append("{");
|
|
StringUtil.ToCommaSeparatedString(builder, members);
|
|
builder.Append("}");
|
|
return builder.ToString();
|
|
}
|
|
|
|
internal static void ToCommaSeparatedString(StringBuilder builder, IEnumerable list) {
|
|
ToSeparatedStringPrivate(builder, list, s_defaultDelimiter, string.Empty, false);
|
|
}
|
|
|
|
internal static void ToCommaSeparatedStringSorted(StringBuilder builder, IEnumerable list) {
|
|
ToSeparatedStringPrivate(builder, list, s_defaultDelimiter, string.Empty, true);
|
|
}
|
|
|
|
internal static void ToSeparatedString(StringBuilder builder, IEnumerable list, string separator) {
|
|
ToSeparatedStringPrivate(builder, list, separator, string.Empty, false);
|
|
}
|
|
|
|
internal static void ToSeparatedStringSorted(StringBuilder builder, IEnumerable list, string separator) {
|
|
ToSeparatedStringPrivate(builder, list, separator, string.Empty, true);
|
|
}
|
|
|
|
// effects: Modifies stringBuilder to contain a string of values from list
|
|
// separated by "separator" with "nullValue" used for null values
|
|
internal static void ToSeparatedString(StringBuilder stringBuilder, IEnumerable list, string separator,
|
|
string nullValue) {
|
|
ToSeparatedStringPrivate(stringBuilder, list, separator, nullValue, false);
|
|
}
|
|
|
|
// effects: Converts the list to a list of strings, sorts its (if
|
|
// toSort is true) and then converts to a string separated by
|
|
// "separator" with "nullValue" used for null values.
|
|
private static void ToSeparatedStringPrivate(StringBuilder stringBuilder, IEnumerable list, string separator,
|
|
string nullValue, bool toSort) {
|
|
if (null == list) {
|
|
return;
|
|
}
|
|
bool isFirst = true;
|
|
// Get the list of strings first
|
|
List<string> elementStrings = new List<string>();
|
|
foreach (object element in list) {
|
|
string str;
|
|
// Get the element or its default null value
|
|
if (element == null) {
|
|
str = nullValue;
|
|
} else {
|
|
str = FormatInvariant("{0}", element);
|
|
}
|
|
elementStrings.Add(str);
|
|
}
|
|
|
|
if (toSort == true) {
|
|
// Sort the list
|
|
elementStrings.Sort(StringComparer.Ordinal);
|
|
}
|
|
|
|
// Now add the strings to the stringBuilder
|
|
foreach (string str in elementStrings) {
|
|
if (false == isFirst) {
|
|
stringBuilder.Append(separator);
|
|
}
|
|
stringBuilder.Append(str);
|
|
isFirst = false;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Some Helper routines
|
|
/// <summary>
|
|
/// This private static method checks a string to make sure that it is not empty.
|
|
/// Comparing with String.Empty is not sufficient since a string with nothing
|
|
/// but white space isn't considered "empty" by that rationale.
|
|
/// </summary>
|
|
internal static bool IsNullOrEmptyOrWhiteSpace(string value)
|
|
{
|
|
return IsNullOrEmptyOrWhiteSpace(value, 0);
|
|
}
|
|
|
|
internal static bool IsNullOrEmptyOrWhiteSpace(string value, int offset)
|
|
{
|
|
// don't use Trim(), which will copy the string, which may be large, just to test for emptyness
|
|
//return String.IsNullOrEmpty(value) || String.IsNullOrEmpty(value.Trim());
|
|
if (null != value)
|
|
{
|
|
for(int i = offset; i < value.Length; ++i)
|
|
{
|
|
if (!Char.IsWhiteSpace(value[i]))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// separate implementation from IsNullOrEmptyOrWhiteSpace(string, int) because that one will
|
|
// pick up the jit optimization to avoid boundary checks and the this won't is unknown (most likely not)
|
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] // referenced by System.Data.Entity.Design.dll
|
|
internal static bool IsNullOrEmptyOrWhiteSpace(string value, int offset, int length)
|
|
{
|
|
// don't use Trim(), which will copy the string, which may be large, just to test for emptyness
|
|
//return String.IsNullOrEmpty(value) || String.IsNullOrEmpty(value.Trim());
|
|
if (null != value)
|
|
{
|
|
length = Math.Min(value.Length, length);
|
|
for(int i = offset; i < length; ++i)
|
|
{
|
|
if (!Char.IsWhiteSpace(value[i]))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
internal static string FormatInvariant(string format, params object[] args) {
|
|
Debug.Assert(args.Length > 0, "Formatting utilities must be called with at least one argument");
|
|
return String.Format(CultureInfo.InvariantCulture, format, args);
|
|
}
|
|
|
|
// effects: Formats args according to the format string and adds it
|
|
// to builder. Returns the modified builder
|
|
internal static StringBuilder FormatStringBuilder(StringBuilder builder, string format, params object[] args) {
|
|
Debug.Assert(args.Length > 0, "Formatting utilities must be called with at least one argument");
|
|
builder.AppendFormat(CultureInfo.InvariantCulture, format, args);
|
|
return builder;
|
|
}
|
|
|
|
// effects: Generates a new line and then indents the new line by
|
|
// indent steps in builder -- indent steps are determined internally
|
|
// by this method. Returns the modified builder
|
|
internal static StringBuilder IndentNewLine(StringBuilder builder, int indent) {
|
|
builder.AppendLine();
|
|
for (int i = 0; i < indent; i++) {
|
|
builder.Append(" ");
|
|
}
|
|
return builder;
|
|
}
|
|
|
|
// effects: returns a string of the form 'arrayVarName[index]'
|
|
internal static string FormatIndex(string arrayVarName, int index) {
|
|
System.Text.StringBuilder builder = new System.Text.StringBuilder(arrayVarName.Length + 10 + 2);
|
|
return builder.Append(arrayVarName).Append('[').Append(index).Append(']').ToString();
|
|
}
|
|
|
|
private static string InvariantConvertToString<T>(T value) {
|
|
return String.Format(CultureInfo.InvariantCulture, "{0}", value);
|
|
}
|
|
#endregion
|
|
|
|
#region Delegates
|
|
internal delegate string ToStringConverter<T>(T value);
|
|
#endregion
|
|
}
|
|
}
|