#region License
// Copyright (c) 2010 Ross McDermott
// 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 Microsoft.SPOT;
using System.Collections;
namespace NetMf.CommonExtensions
{
///
/// Provides additional standard string operations
///
public abstract class StringUtility
{
///
/// Check if the provided string is either null or empty
///
/// String to validate
/// True if the string is null or empty
public static bool IsNullOrEmpty(string str)
{
if (str == null || str == string.Empty)
return true;
return false;
}
///
/// Replaces one or more format items in a specified string with the string representation of a specified object.
///
/// A composite format string.
/// The object to format.
/// A copy of format in which any format items are replaced by the string representation of arg0.
/// format is invalid, or the index of a format item is less than zero, or greater than or equal to the length of the args array.
/// format or args is null
public static string Format(string format, object arg)
{
return Format(format, new object[] { arg });
}
///
/// Format the given string using the provided collection of objects.
///
/// A composite format string.
/// An object array that contains zero or more objects to format.
/// A copy of format in which the format items have been replaced by the string representation of the corresponding objects in args.
/// format is invalid, or the index of a format item is less than zero, or greater than or equal to the length of the args array.
/// format or args is null
///
/// x = StringUtility.Format("Quick brown {0}","fox");
///
public static string Format(string format, params object[] args)
{
if (format == null)
throw new ArgumentNullException("format");
if (args == null)
throw new ArgumentNullException("args");
// Validate the structure of the format string.
ValidateFormatString(format);
StringBuilder bld = new StringBuilder();
int endOfLastMatch = 0;
int starting = 0;
while (starting >= 0)
{
starting = format.IndexOf('{', starting);
if (starting >= 0)
{
if (starting != format.Length - 1)
{
if (format[starting + 1] == '{')
{
// escaped starting bracket.
starting = starting + 2;
continue;
}
else
{
bool found = false;
int endsearch = format.IndexOf('}', starting);
while(endsearch > starting)
{
if (endsearch != (format.Length - 1) && format[endsearch + 1] == '}')
{
// escaped ending bracket
endsearch = endsearch + 2;
}
else
{
if(starting != endOfLastMatch)
{
string t = format.Substring(endOfLastMatch, starting - endOfLastMatch);
t = t.Replace("{{", "{"); // get rid of the escaped brace
t = t.Replace("}}", "}"); // get rid of the escaped brace
bld.Append(t);
}
// we have a winner
string fmt = format.Substring(starting, endsearch-starting + 1);
if (fmt.Length >= 3)
{
fmt = fmt.Substring(1, fmt.Length - 2);
string[] indexFormat = fmt.Split(new char[] { ':' });
string formatString = string.Empty;
if (indexFormat.Length == 2)
{
formatString = indexFormat[1];
}
int index = 0;
// no format, just number
if (Parse.TryParseInt(indexFormat[0], out index))
{
bld.Append(FormatParameter(args[index], formatString));
}
else
{
throw new FormatException(FormatException.ERROR_MESSAGE);
}
}
endOfLastMatch = endsearch + 1;
found = true;
starting = endsearch + 1;
break;
}
endsearch = format.IndexOf('}', endsearch);
}
// need to find the ending point
if(!found)
{
throw new FormatException(FormatException.ERROR_MESSAGE);
}
}
}
else
{
// invalid
throw new FormatException(FormatException.ERROR_MESSAGE);
}
}
}
// copy any additional remaining part of the format string.
if (endOfLastMatch != format.Length)
{
bld.Append(format.Substring(endOfLastMatch, format.Length - endOfLastMatch));
}
return bld.ToString();
}
private static void ValidateFormatString(string format)
{
char expected = '{';
int i = 0;
while ((i = format.IndexOfAny(new char[] { '{', '}' }, i)) >= 0)
{
if (i < (format.Length - 1) && format[i] == format[i + 1])
{
// escaped brace. continue looking.
i = i + 2;
continue;
}
else if (format[i] != expected)
{
// badly formed string.
throw new FormatException(FormatException.ERROR_MESSAGE);
}
else
{
// move it along.
i++;
// expected it.
if (expected == '{')
expected = '}';
else
expected = '{';
}
}
if (expected == '}')
{
// orpaned opening brace. Bad format.
throw new FormatException(FormatException.ERROR_MESSAGE);
}
}
///
/// Format the provided object using the provided format string.
///
/// Object to be formatted
/// Format string to be applied to the object
/// Formatted string for the object
private static string FormatParameter(object p, string formatString)
{
if (formatString == string.Empty)
return p.ToString();
if (p as IFormattable != null)
{
return ((IFormattable)p).ToString(formatString,null);
}
else if (p is DateTime)
{
return ((DateTime)p).ToString(formatString);
}
else if (p is Double)
{
return ((Double)p).ToString(formatString);
}
else if (p is Int16)
{
return ((Int16)p).ToString(formatString);
}
else if (p is Int32)
{
return ((Int32)p).ToString(formatString);
}
else if (p is Int64)
{
return ((Int64)p).ToString(formatString);
}
else if (p is SByte)
{
return ((SByte)p).ToString(formatString);
}
else if (p is Single)
{
return ((Single)p).ToString(formatString);
}
else if (p is UInt16)
{
return ((UInt16)p).ToString(formatString);
}
else if (p is UInt32)
{
return ((UInt32)p).ToString(formatString);
}
else if (p is UInt64)
{
return ((UInt64)p).ToString(formatString);
}
else
{
return p.ToString();
}
}
}
}