1 /* ****************************************************************************
3 * Copyright (c) Microsoft Corporation.
5 * This source code is subject to terms and conditions of the Apache License, Version 2.0. A
6 * copy of the license can be found in the License.html file at the root of this distribution. If
7 * you cannot locate the Apache License, Version 2.0, please send an email to
8 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
9 * by the terms of the Apache License, Version 2.0.
11 * You must not remove this notice, or any other, from this software.
14 * ***************************************************************************/
17 using System.Collections.Generic;
18 using System.Globalization;
21 namespace Microsoft.Scripting.Utils {
22 public static class StringUtils {
24 public static Encoding DefaultEncoding {
27 return Encoding.Default;
34 public static string GetSuffix(string str, char separator, bool includeSeparator) {
35 ContractUtils.RequiresNotNull(str, "str");
36 int last = str.LastIndexOf(separator);
37 return (last != -1) ? str.Substring(includeSeparator ? last : last + 1) : null;
40 public static string GetLongestPrefix(string str, char separator, bool includeSeparator) {
41 ContractUtils.RequiresNotNull(str, "str");
42 int last = str.LastIndexOf(separator);
43 return (last != -1) ? str.Substring(0, (includeSeparator || last == 0) ? last : last - 1) : null;
46 public static int CountOf(string str, char c) {
47 if (System.String.IsNullOrEmpty(str)) return 0;
50 for (int i = 0; i < str.Length; i++) {
58 public static string[] Split(string str, string separator, int maxComponents, StringSplitOptions options) {
59 ContractUtils.RequiresNotNull(str, "str");
60 #if SILVERLIGHT || WP75
61 if (string.IsNullOrEmpty(separator)) throw new ArgumentNullException("separator");
63 bool keep_empty = (options & StringSplitOptions.RemoveEmptyEntries) != StringSplitOptions.RemoveEmptyEntries;
65 List<string> result = new List<string>(maxComponents == Int32.MaxValue ? 1 : maxComponents + 1);
69 while (maxComponents > 1 && i < str.Length && (next = str.IndexOf(separator, i)) != -1) {
71 if (next > i || keep_empty) {
72 result.Add(str.Substring(i, next - i));
76 i = next + separator.Length;
79 if (i < str.Length || keep_empty) {
80 result.Add(str.Substring(i));
83 return result.ToArray();
85 return str.Split(new string[] { separator }, maxComponents, options);
89 public static string[] Split(string str, char[] separators, int maxComponents, StringSplitOptions options) {
90 ContractUtils.RequiresNotNull(str, "str");
91 #if SILVERLIGHT || WP75
92 if (separators == null) return SplitOnWhiteSpace(str, maxComponents, options);
94 bool keep_empty = (options & StringSplitOptions.RemoveEmptyEntries) != StringSplitOptions.RemoveEmptyEntries;
96 List<string> result = new List<string>(maxComponents == Int32.MaxValue ? 1 : maxComponents + 1);
100 while (maxComponents > 1 && i < str.Length && (next = str.IndexOfAny(separators, i)) != -1) {
102 if (next > i || keep_empty) {
103 result.Add(str.Substring(i, next - i));
110 if (i < str.Length || keep_empty) {
111 result.Add(str.Substring(i));
114 return result.ToArray();
116 return str.Split(separators, maxComponents, options);
120 #if SILVERLIGHT|| WP75
121 public static string[] SplitOnWhiteSpace(string str, int maxComponents, StringSplitOptions options) {
122 ContractUtils.RequiresNotNull(str, "str");
124 bool keep_empty = (options & StringSplitOptions.RemoveEmptyEntries) != StringSplitOptions.RemoveEmptyEntries;
126 List<string> result = new List<string>(maxComponents == Int32.MaxValue ? 1 : maxComponents + 1);
130 while (maxComponents > 1 && i < str.Length && (next = IndexOfWhiteSpace(str, i)) != -1) {
132 if (next > i || keep_empty) {
133 result.Add(str.Substring(i, next - i));
140 if (i < str.Length || keep_empty) {
141 result.Add(str.Substring(i));
144 return result.ToArray();
147 public static int IndexOfWhiteSpace(string str, int start) {
148 ContractUtils.RequiresNotNull(str, "str");
149 if (start < 0 || start > str.Length) throw new ArgumentOutOfRangeException("start");
151 while (start < str.Length && !Char.IsWhiteSpace(str[start])) start++;
153 return (start == str.Length) ? -1 : start;
158 /// Splits text and optionally indents first lines - breaks along words, not characters.
160 public static string SplitWords(string text, bool indentFirst, int lineWidth) {
161 ContractUtils.RequiresNotNull(text, "text");
163 const string indent = " ";
165 if (text.Length <= lineWidth || lineWidth <= 0) {
166 if (indentFirst) return indent + text;
170 StringBuilder res = new StringBuilder();
171 int start = 0, len = lineWidth;
172 while (start != text.Length) {
173 if (len >= lineWidth) {
174 // find last space to break on
175 while (len != 0 && !Char.IsWhiteSpace(text[start + len - 1]))
179 if (res.Length != 0) res.Append(' ');
180 if (indentFirst || res.Length != 0) res.Append(indent);
183 int copying = System.Math.Min(lineWidth, text.Length - start);
184 res.Append(text, start, copying);
187 res.Append(text, start, len);
191 len = System.Math.Min(lineWidth, text.Length - start);
193 return res.ToString();
196 public static string AddSlashes(string str) {
197 ContractUtils.RequiresNotNull(str, "str");
200 StringBuilder result = new StringBuilder(str.Length);
201 for (int i = 0; i < str.Length; i++) {
203 case '\a': result.Append("\\a"); break;
204 case '\b': result.Append("\\b"); break;
205 case '\f': result.Append("\\f"); break;
206 case '\n': result.Append("\\n"); break;
207 case '\r': result.Append("\\r"); break;
208 case '\t': result.Append("\\t"); break;
209 case '\v': result.Append("\\v"); break;
210 default: result.Append(str[i]); break;
214 return result.ToString();
217 public static bool TryParseDouble(string s, NumberStyles style, IFormatProvider provider, out double result) {
218 return Double.TryParse(s, style, provider, out result);
221 public static bool TryParseInt32(string s, out int result) {
222 return Int32.TryParse(s, out result);
225 public static bool TryParseDateTimeExact(string s, string format, IFormatProvider provider, DateTimeStyles style, out DateTime result) {
226 return DateTime.TryParseExact(s, format, provider, style, out result);
229 public static bool TryParseDateTimeExact(string s, string[] formats, IFormatProvider provider, DateTimeStyles style, out DateTime result) {
230 return DateTime.TryParseExact(s, formats, provider, style, out result);
233 public static bool TryParseDate(string s, IFormatProvider provider, DateTimeStyles style, out DateTime result) {
234 return DateTime.TryParse(s, provider, style, out result);
238 #if SILVERLIGHT || WP75
239 private static Dictionary<string, CultureInfo> _cultureInfoCache = new Dictionary<string, CultureInfo>();
242 // Aims to be equivalent to Culture.GetCultureInfo for Silverlight
243 public static CultureInfo GetCultureInfo(string name) {
244 #if SILVERLIGHT || WP75
245 lock (_cultureInfoCache) {
247 if (_cultureInfoCache.TryGetValue(name, out result)) {
250 _cultureInfoCache[name] = result = new CultureInfo(name);
254 return CultureInfo.GetCultureInfo(name);
258 // Like string.Split, but enumerates
259 public static IEnumerable<string> Split(string str, string sep) {
261 while ((end = str.IndexOf(sep, start)) != -1) {
262 yield return str.Substring(start, end - start);
264 start = end + sep.Length;
266 yield return str.Substring(start);