1 //---------------------------------------------------------------------
2 // <copyright file="StringUtil.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
12 using System
.Collections
;
13 using System
.Collections
.Generic
;
15 using System
.Globalization
;
16 using System
.Diagnostics
;
18 namespace System
.Data
.Common
.Utils
{
20 // This class provides some useful string utilities, e.g., converting a
22 internal static class StringUtil
{
23 private const string s_defaultDelimiter
= ", ";
25 #region String Conversion - Unsorted
27 /// Converts an enumeration of values to a delimited string list.
29 /// <typeparam name="T">Type of elements to convert.</typeparam>
30 /// <param name="values">Values. If null, returns empty string.</param>
31 /// <param name="converter">Converter. If null, uses default invariant culture converter.</param>
32 /// <param name="delimiter">Delimiter. If null, uses default (', ')</param>
33 /// <returns>Delimited list of values in string.</returns>
34 internal static string BuildDelimitedList
<T
>(IEnumerable
<T
> values
, ToStringConverter
<T
> converter
, string delimiter
) {
35 if (null == values
) { return String.Empty; }
36 if (null == converter
) { converter = new ToStringConverter<T>(InvariantConvertToString<T>); }
37 if (null == delimiter
) { delimiter = s_defaultDelimiter; }
39 StringBuilder sb
= new StringBuilder();
41 foreach (T
value in values
) {
42 if (first
) { first = false; }
43 else { sb.Append(delimiter); }
44 sb
.Append(converter(value));
50 // effects: Converts list to a string separated by a comma with
51 // string.Empty used for null values
52 internal static string ToCommaSeparatedString(IEnumerable list
) {
53 return ToSeparatedString(list
, s_defaultDelimiter
, string.Empty
);
56 // effects: Converts list to a string separated by "separator" with
57 // "nullValue" used for null values
58 internal static string ToSeparatedString(IEnumerable list
, string separator
, string nullValue
) {
59 StringBuilder builder
= new StringBuilder();
60 ToSeparatedString(builder
, list
, separator
, nullValue
);
61 return builder
.ToString();
65 #region String Conversion - Sorted
66 // effects: Converts the list to a list of strings, sorts its
67 // and then converts to a string separated by a comma with
68 // string.Empty used for null values
69 internal static string ToCommaSeparatedStringSorted(IEnumerable list
) {
70 return ToSeparatedStringSorted(list
, s_defaultDelimiter
, string.Empty
);
73 // effects: Converts the list to a list of strings, sorts its using
74 // StringComparer.Ordinal
75 // and then converts to a string separated by "separator" with
76 // with "nullValue" used for null values
77 internal static string ToSeparatedStringSorted(IEnumerable list
, string separator
, string nullValue
) {
78 StringBuilder builder
= new StringBuilder();
79 ToSeparatedStringPrivate(builder
, list
, separator
, nullValue
, true);
80 return builder
.ToString();
84 #region StringBuilder routines
86 internal static string MembersToCommaSeparatedString(IEnumerable members
)
88 StringBuilder builder
= new StringBuilder();
90 StringUtil
.ToCommaSeparatedString(builder
, members
);
92 return builder
.ToString();
95 internal static void ToCommaSeparatedString(StringBuilder builder
, IEnumerable list
) {
96 ToSeparatedStringPrivate(builder
, list
, s_defaultDelimiter
, string.Empty
, false);
99 internal static void ToCommaSeparatedStringSorted(StringBuilder builder
, IEnumerable list
) {
100 ToSeparatedStringPrivate(builder
, list
, s_defaultDelimiter
, string.Empty
, true);
103 internal static void ToSeparatedString(StringBuilder builder
, IEnumerable list
, string separator
) {
104 ToSeparatedStringPrivate(builder
, list
, separator
, string.Empty
, false);
107 internal static void ToSeparatedStringSorted(StringBuilder builder
, IEnumerable list
, string separator
) {
108 ToSeparatedStringPrivate(builder
, list
, separator
, string.Empty
, true);
111 // effects: Modifies stringBuilder to contain a string of values from list
112 // separated by "separator" with "nullValue" used for null values
113 internal static void ToSeparatedString(StringBuilder stringBuilder
, IEnumerable list
, string separator
,
115 ToSeparatedStringPrivate(stringBuilder
, list
, separator
, nullValue
, false);
118 // effects: Converts the list to a list of strings, sorts its (if
119 // toSort is true) and then converts to a string separated by
120 // "separator" with "nullValue" used for null values.
121 private static void ToSeparatedStringPrivate(StringBuilder stringBuilder
, IEnumerable list
, string separator
,
122 string nullValue
, bool toSort
) {
127 // Get the list of strings first
128 List
<string> elementStrings
= new List
<string>();
129 foreach (object element
in list
) {
131 // Get the element or its default null value
132 if (element
== null) {
135 str
= FormatInvariant("{0}", element
);
137 elementStrings
.Add(str
);
140 if (toSort
== true) {
142 elementStrings
.Sort(StringComparer
.Ordinal
);
145 // Now add the strings to the stringBuilder
146 foreach (string str
in elementStrings
) {
147 if (false == isFirst
) {
148 stringBuilder
.Append(separator
);
150 stringBuilder
.Append(str
);
156 #region Some Helper routines
158 /// This private static method checks a string to make sure that it is not empty.
159 /// Comparing with String.Empty is not sufficient since a string with nothing
160 /// but white space isn't considered "empty" by that rationale.
162 internal static bool IsNullOrEmptyOrWhiteSpace(string value)
164 return IsNullOrEmptyOrWhiteSpace(value, 0);
167 internal static bool IsNullOrEmptyOrWhiteSpace(string value, int offset
)
169 // don't use Trim(), which will copy the string, which may be large, just to test for emptyness
170 //return String.IsNullOrEmpty(value) || String.IsNullOrEmpty(value.Trim());
173 for(int i
= offset
; i
< value.Length
; ++i
)
175 if (!Char
.IsWhiteSpace(value[i
]))
184 // separate implementation from IsNullOrEmptyOrWhiteSpace(string, int) because that one will
185 // pick up the jit optimization to avoid boundary checks and the this won't is unknown (most likely not)
186 [System
.Diagnostics
.CodeAnalysis
.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] // referenced by System.Data.Entity.Design.dll
187 internal static bool IsNullOrEmptyOrWhiteSpace(string value, int offset
, int length
)
189 // don't use Trim(), which will copy the string, which may be large, just to test for emptyness
190 //return String.IsNullOrEmpty(value) || String.IsNullOrEmpty(value.Trim());
193 length
= Math
.Min(value.Length
, length
);
194 for(int i
= offset
; i
< length
; ++i
)
196 if (!Char
.IsWhiteSpace(value[i
]))
205 internal static string FormatInvariant(string format
, params object[] args
) {
206 Debug
.Assert(args
.Length
> 0, "Formatting utilities must be called with at least one argument");
207 return String
.Format(CultureInfo
.InvariantCulture
, format
, args
);
210 // effects: Formats args according to the format string and adds it
211 // to builder. Returns the modified builder
212 internal static StringBuilder
FormatStringBuilder(StringBuilder builder
, string format
, params object[] args
) {
213 Debug
.Assert(args
.Length
> 0, "Formatting utilities must be called with at least one argument");
214 builder
.AppendFormat(CultureInfo
.InvariantCulture
, format
, args
);
218 // effects: Generates a new line and then indents the new line by
219 // indent steps in builder -- indent steps are determined internally
220 // by this method. Returns the modified builder
221 internal static StringBuilder
IndentNewLine(StringBuilder builder
, int indent
) {
222 builder
.AppendLine();
223 for (int i
= 0; i
< indent
; i
++) {
229 // effects: returns a string of the form 'arrayVarName[index]'
230 internal static string FormatIndex(string arrayVarName
, int index
) {
231 System
.Text
.StringBuilder builder
= new System
.Text
.StringBuilder(arrayVarName
.Length
+ 10 + 2);
232 return builder
.Append(arrayVarName
).Append('[').Append(index
).Append(']').ToString();
235 private static string InvariantConvertToString
<T
>(T
value) {
236 return String
.Format(CultureInfo
.InvariantCulture
, "{0}", value);
241 internal delegate string ToStringConverter
<T
>(T
value);