Updates referencesource to .NET 4.7
[mono-project.git] / mcs / class / referencesource / System.Data.Entity / System / Data / Common / Utils / StringUtil.cs
blob79e347e384316329443046959ff1be1ab73a0f2e
1 //---------------------------------------------------------------------
2 // <copyright file="StringUtil.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
4 // </copyright>
5 //
6 // @owner Microsoft
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
11 using System;
12 using System.Collections;
13 using System.Collections.Generic;
14 using System.Text;
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
21 // list to string.
22 internal static class StringUtil {
23 private const string s_defaultDelimiter = ", ";
25 #region String Conversion - Unsorted
26 /// <summary>
27 /// Converts an enumeration of values to a delimited string list.
28 /// </summary>
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();
40 bool first = true;
41 foreach (T value in values) {
42 if (first) { first = false; }
43 else { sb.Append(delimiter); }
44 sb.Append(converter(value));
47 return sb.ToString();
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();
63 #endregion
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();
82 #endregion
84 #region StringBuilder routines
86 internal static string MembersToCommaSeparatedString(IEnumerable members)
88 StringBuilder builder = new StringBuilder();
89 builder.Append("{");
90 StringUtil.ToCommaSeparatedString(builder, members);
91 builder.Append("}");
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,
114 string nullValue) {
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) {
123 if (null == list) {
124 return;
126 bool isFirst = true;
127 // Get the list of strings first
128 List<string> elementStrings = new List<string>();
129 foreach (object element in list) {
130 string str;
131 // Get the element or its default null value
132 if (element == null) {
133 str = nullValue;
134 } else {
135 str = FormatInvariant("{0}", element);
137 elementStrings.Add(str);
140 if (toSort == true) {
141 // Sort the list
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);
151 isFirst = false;
154 #endregion
156 #region Some Helper routines
157 /// <summary>
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.
161 /// </summary>
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());
171 if (null != value)
173 for(int i = offset; i < value.Length; ++i)
175 if (!Char.IsWhiteSpace(value[i]))
177 return false;
181 return true;
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());
191 if (null != value)
193 length = Math.Min(value.Length, length);
194 for(int i = offset; i < length; ++i)
196 if (!Char.IsWhiteSpace(value[i]))
198 return false;
202 return true;
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);
215 return builder;
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++) {
224 builder.Append(" ");
226 return builder;
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);
238 #endregion
240 #region Delegates
241 internal delegate string ToStringConverter<T>(T value);
242 #endregion