using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Security;
using System.Runtime.InteropServices;
using System.Net;
namespace TradeIdeas.Stocks.ETrade
{
public static class StringExtensions
{
///
/// Extension method that replaces keys in a string with the values of matching object properties.
/// Uses String.Format() internally; custom formats should match those used for that method.
///
/// The format string, containing keys like {foo} and {foo:SomeFormat}.
/// The object whose properties should be injected in the string
/// A version of the formatString string with keys replaced by (formatted) key values.
public static string Inject(this string formatString, object injectionObject)
{
return formatString.Inject(GetPropertyHash(injectionObject));
}
///
/// Extension method that replaces keys in a string with the values of matching dictionary entries.
/// Uses String.Format() internally; custom formats should match those used for that method.
///
/// The format string, containing keys like {foo} and {foo:SomeFormat}.
/// An with keys and values to inject into the string
/// A version of the formatString string with dictionary keys replaced by (formatted) key values.
public static string Inject(this string formatString, IDictionary dictionary)
{
return formatString.Inject(new Hashtable(dictionary));
}
///
/// Extension method that replaces keys in a string with the values of matching hashtable entries.
/// Uses String.Format() internally; custom formats should match those used for that method.
///
/// The format string, containing keys like {foo} and {foo:SomeFormat}.
/// A with keys and values to inject into the string
/// A version of the formatString string with hastable keys replaced by (formatted) key values.
public static string Inject(this string formatString, Hashtable attributes)
{
var result = formatString;
if (attributes == null || formatString == null)
{
return result;
}
return attributes.Keys.Cast().Aggregate(result, (current, attributeKey) => current.InjectSingleValue(attributeKey, attributes[attributeKey]));
}
///
/// Replaces all instances of a 'key' (e.g. {foo} or {foo:SomeFormat}) in a string with an optionally formatted value, and returns the result.
///
/// The string containing the key; unformatted ({foo}), or formatted ({foo:SomeFormat})
/// The key name (foo)
/// The replacement value; if null is replaced with an empty string
/// The input string with any instances of the key replaced with the replacement value
public static string InjectSingleValue(this string formatString, string key, object replacementValue)
{
string result = formatString;
//regex replacement of key with value, where the generic key format is:
//Regex foo = new Regex("{(foo)(?:}|(?::(.[^}]*)}))");
var attributeRegex = new Regex("{(" + key + ")(?:}|(?::(.[^}]*)}))"); //for key = foo, matches {foo} and {foo:SomeFormat}
//loop through matches, since each key may be used more than once (and with a different format string)
foreach (Match m in attributeRegex.Matches(formatString))
{
string replacement;
if (m.Groups[2].Length > 0) //matched {foo:SomeFormat}
{
//do a double string.Format - first to build the proper format string, and then to format the replacement value
string attributeFormatString = string.Format(CultureInfo.InvariantCulture, "{{0:{0}}}", m.Groups[2]);
replacement = string.Format(CultureInfo.CurrentCulture, attributeFormatString, replacementValue);
}
else //matched {foo}
{
replacement = (replacementValue ?? string.Empty).ToString();
}
//perform replacements, one match at a time
result = result.Replace(m.ToString(), replacement); //attributeRegex.Replace(result, replacement, 1);
}
return result;
}
///
/// Creates a HashTable based on current object state.
/// Copied from the MVCToolkit HtmlExtensionUtility class
///
/// The object from which to get the properties
/// A containing the object instance's property names and their values
private static Hashtable GetPropertyHash(object properties)
{
Hashtable values = null;
if (properties != null)
{
values = new Hashtable();
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(properties);
foreach (PropertyDescriptor prop in props)
{
values.Add(prop.Name, prop.GetValue(properties));
}
}
return values;
}
// http://blogs.msdn.com/b/fpintos/archive/2009/06/12/how-to-properly-convert-securestring-to-string.aspx
public static string AsString(this SecureString value)
{
if (value == null)
{
return null;
}
IntPtr unmanagedString = IntPtr.Zero;
try
{
unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(value);
return Marshal.PtrToStringUni(unmanagedString);
}
finally
{
Marshal.ZeroFreeGlobalAllocUnicode(unmanagedString);
}
}
public static SecureString AsSecureString(this string value)
{
if (string.IsNullOrEmpty(value))
{
return null;
}
unsafe
{
fixed (char* passwordChars = value)
{
var ss = new SecureString(passwordChars, value.Length);
ss.MakeReadOnly();
return ss;
}
}
//var ss = new SecureString();
//foreach (var c in value.ToCharArray())
//{
// ss.AppendChar(c);
//}
//ss.MakeReadOnly;
//return ss;
}
public static string ToDelimitedString(this IEnumerable value, string delimiter)
{
return string.Join(delimiter, from v in value select v);
}
}
}