#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Linq;
using System.Globalization;
namespace Newtonsoft.Json.Utilities
{
internal static class StringUtils
{
public const string CarriageReturnLineFeed = "\r\n";
public const string Empty = "";
public const char CarriageReturn = '\r';
public const char LineFeed = '\n';
public const char Tab = '\t';
//public static string FormatWith(this string format, params object[] args)
//{
// return FormatWith(format, null, args);
//}
public static string FormatWith(this string format, IFormatProvider provider, params object[] args)
{
return string.Format(provider, format, args);
}
/// <summary>
/// Determines whether the string contains white space.
/// </summary>
/// <param name="s">The string to test for white space.</param>
/// <returns>
/// <c>true</c> if the string contains white space; otherwise, <c>false</c>.
/// </returns>
public static bool ContainsWhiteSpace(string s)
{
if (s == null)
throw new ArgumentNullException("s");
for (int i = 0; i < s.Length; i++)
{
if (char.IsWhiteSpace(s[i]))
return true;
}
return false;
}
/// <summary>
/// Determines whether the string is all white space. Empty string will return false.
/// </summary>
/// <param name="s">The string to test whether it is all white space.</param>
/// <returns>
/// <c>true</c> if the string is all white space; otherwise, <c>false</c>.
/// </returns>
public static bool IsWhiteSpace(string s)
{
if (s == null)
throw new ArgumentNullException("s");
if (s.Length == 0)
return false;
for (int i = 0; i < s.Length; i++)
{
if (!char.IsWhiteSpace(s[i]))
return false;
}
return true;
}
/// <summary>
/// Ensures the target string ends with the specified string.
/// </summary>
/// <param name="target">The target.</param>
/// <param name="value">The value.</param>
/// <returns>The target string with the value string at the end.</returns>
public static string EnsureEndsWith(string target, string value)
{
if (target == null)
throw new ArgumentNullException("target");
if (value == null)
throw new ArgumentNullException("value");
if (target.Length >= value.Length)
{
if (string.Compare(target, target.Length - value.Length, value, 0, value.Length, StringComparison.OrdinalIgnoreCase) ==
0)
return target;
string trimmedString = target.TrimEnd(null);
if (string.Compare(trimmedString, trimmedString.Length - value.Length, value, 0, value.Length,
StringComparison.OrdinalIgnoreCase) == 0)
return target;
}
return target + value;
}
public static bool IsNullOrEmptyOrWhiteSpace(string s)
{
if (string.IsNullOrEmpty(s))
return true;
else if (IsWhiteSpace(s))
return true;
else
return false;
}
/// <summary>
/// Perform an action if the string is not null or empty.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="action">The action to perform.</param>
public static void IfNotNullOrEmpty(string value, Action<string> action)
{
IfNotNullOrEmpty(value, action, null);
}
private static void IfNotNullOrEmpty(string value, Action<string> trueAction, Action<string> falseAction)
{
if (!string.IsNullOrEmpty(value))
{
if (trueAction != null)
trueAction(value);
}
else
{
if (falseAction != null)
falseAction(value);
}
}
/// <summary>
/// Indents the specified string.
/// </summary>
/// <param name="s">The string to indent.</param>
/// <param name="indentation">The number of characters to indent by.</param>
/// <returns></returns>
public static string Indent(string s, int indentation)
{
return Indent(s, indentation, ' ');
}
/// <summary>
/// Indents the specified string.
/// </summary>
/// <param name="s">The string to indent.</param>
/// <param name="indentation">The number of characters to indent by.</param>
/// <param name="indentChar">The indent character.</param>
/// <returns></returns>
public static string Indent(string s, int indentation, char indentChar)
{
if (s == null)
throw new ArgumentNullException("s");
if (indentation <= 0)
throw new ArgumentException("Must be greater than zero.", "indentation");
StringReader sr = new StringReader(s);
StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
ActionTextReaderLine(sr, sw, delegate(TextWriter tw, string line)
{
tw.Write(new string(indentChar, indentation));
tw.Write(line);
});
return sw.ToString();
}
private delegate void ActionLine(TextWriter textWriter, string line);
private static void ActionTextReaderLine(TextReader textReader, TextWriter textWriter, ActionLine lineAction)
{
string line;
bool firstLine = true;
while ((line = textReader.ReadLine()) != null)
{
if (!firstLine)
textWriter.WriteLine();
else
firstLine = false;
lineAction(textWriter, line);
}
}
/// <summary>
/// Numbers the lines.
/// </summary>
/// <param name="s">The string to number.</param>
/// <returns></returns>
public static string NumberLines(string s)
{
if (s == null)
throw new ArgumentNullException("s");
StringReader sr = new StringReader(s);
StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
int lineNumber = 1;
ActionTextReaderLine(sr, sw, delegate(TextWriter tw, string line)
{
tw.Write(lineNumber.ToString(CultureInfo.InvariantCulture).PadLeft(4));
tw.Write(". ");
tw.Write(line);
lineNumber++;
});
return sw.ToString();
}
/// <summary>
/// Nulls an empty string.
/// </summary>
/// <param name="s">The string.</param>
/// <returns>Null if the string was null, otherwise the string unchanged.</returns>
public static string NullEmptyString(string s)
{
return (string.IsNullOrEmpty(s)) ? null : s;
}
public static string ReplaceNewLines(string s, string replacement)
{
StringReader sr = new StringReader(s);
StringBuilder sb = new StringBuilder();
bool first = true;
string line;
while ((line = sr.ReadLine()) != null)
{
if (first)
first = false;
else
sb.Append(replacement);
sb.Append(line);
}
return sb.ToString();
}
public static string Truncate(string s, int maximumLength)
{
return Truncate(s, maximumLength, "...");
}
public static string Truncate(string s, int maximumLength, string suffix)
{
if (suffix == null)
throw new ArgumentNullException("suffix");
if (maximumLength <= 0)
throw new ArgumentException("Maximum length must be greater than zero.", "maximumLength");
int subStringLength = maximumLength - suffix.Length;
if (subStringLength <= 0)
throw new ArgumentException("Length of suffix string is greater or equal to maximumLength");
if (s != null && s.Length > maximumLength)
{
string truncatedString = s.Substring(0, subStringLength);
// incase the last character is a space
truncatedString = truncatedString.Trim();
truncatedString += suffix;
return truncatedString;
}
else
{
return s;
}
}
public static StringWriter CreateStringWriter(int capacity)
{
StringBuilder sb = new StringBuilder(capacity);
StringWriter sw = new StringWriter(sb, CultureInfo.InvariantCulture);
return sw;
}
public static int? GetLength(string value)
{
if (value == null)
return null;
else
return value.Length;
}
public static char IntToHex(int n)
{
if (n <= 9)
{
return (char)(n + 48);
}
return (char)((n - 10) + 97);
}
public static string ToCharAsUnicode(char c)
{
char h1 = IntToHex((c >> 12) & '\x000f');
char h2 = IntToHex((c >> 8) & '\x000f');
char h3 = IntToHex((c >> 4) & '\x000f');
char h4 = IntToHex(c & '\x000f');
return new string(new[] { '\\', 'u', h1, h2, h3, h4 });
}
public static void WriteCharAsUnicode(TextWriter writer, char c)
{
char h1 = IntToHex((c >> 12) & '\x000f');
char h2 = IntToHex((c >> 8) & '\x000f');
char h3 = IntToHex((c >> 4) & '\x000f');
char h4 = IntToHex(c & '\x000f');
writer.Write('\\');
writer.Write('u');
writer.Write(h1);
writer.Write(h2);
writer.Write(h3);
writer.Write(h4);
}
public static TSource ForgivingCaseSensitiveFind<TSource>(this IEnumerable<TSource> source, Func<TSource, string> valueSelector, string testValue)
{
if (source == null)
throw new ArgumentNullException("source");
if (valueSelector == null)
throw new ArgumentNullException("valueSelector");
var caseInsensitiveResults = source.Where(s => string.Compare(valueSelector(s), testValue, StringComparison.OrdinalIgnoreCase) == 0);
if (caseInsensitiveResults.Count() <= 1)
{
return caseInsensitiveResults.SingleOrDefault();
}
else
{
// multiple results returned. now filter using case sensitivity
var caseSensitiveResults = source.Where(s => string.Compare(valueSelector(s), testValue, StringComparison.Ordinal) == 0);
return caseSensitiveResults.SingleOrDefault();
}
}
}
}
|