using System;
using System.Collections.Generic;
using System.Management.Automation.Host;
using System.Text;
namespace PSModuleDevelopment.Utility
{
///
/// Host class, containing statics in support of the utility namespace
///
public static class UtilityHost
{
///
/// Gives access to the host UI, in order to access window information
///
public static PSHostRawUserInterface RawUI;
///
/// Implement's VB's Like operator logic.
///
public static bool IsLike(string String, string Pattern, bool CaseSensitive = false)
{
if (!CaseSensitive)
{
String = String.ToLower();
Pattern = Pattern.ToLower();
}
// Characters matched so far
int matched = 0;
// Loop through pattern string
for (int i = 0; i < Pattern.Length;)
{
// Check for end of string
if (matched > String.Length)
return false;
// Get next pattern character
char c = Pattern[i++];
if (c == '[') // Character list
{
// Test for exclude character
bool exclude = (i < Pattern.Length && Pattern[i] == '!');
if (exclude)
i++;
// Build character list
int j = Pattern.IndexOf(']', i);
if (j < 0)
j = String.Length;
HashSet charList = CharListToSet(Pattern.Substring(i, j - i));
i = j + 1;
if (charList.Contains(String[matched]) == exclude)
return false;
matched++;
}
else if (c == '?') // Any single character
{
matched++;
}
else if (c == '#') // Any single digit
{
if (!Char.IsDigit(String[matched]))
return false;
matched++;
}
else if (c == '*') // Zero or more characters
{
if (i < Pattern.Length)
{
// Matches all characters until
// next character in pattern
char next = Pattern[i];
int j = String.IndexOf(next, matched);
if (j < 0)
return false;
matched = j;
}
else
{
// Matches all remaining characters
matched = String.Length;
break;
}
}
else // Exact character
{
if (matched >= String.Length || c != String[matched])
return false;
matched++;
}
}
// Return true if all characters matched
return (matched == String.Length);
}
///
/// Converts a string of characters to a HashSet of characters. If the string
/// contains character ranges, such as A-Z, all characters in the range are
/// also added to the returned set of characters.
///
/// Character list string
private static HashSet CharListToSet(string charList)
{
HashSet set = new HashSet();
for (int i = 0; i < charList.Length; i++)
{
if ((i + 1) < charList.Length && charList[i + 1] == '-')
{
// Character range
char startChar = charList[i++];
i++; // Hyphen
char endChar = (char)0;
if (i < charList.Length)
endChar = charList[i++];
for (int j = startChar; j <= endChar; j++)
set.Add((char)j);
}
else set.Add(charList[i]);
}
return set;
}
///
/// Replace a value in a string with another.
/// Extends the default c# String.Replace with the capability to be case-insensitive.
///
/// The string to modify
/// The value to look for and replace with someting else
/// The value to insert where you found the previous value. Leave empty to just delete the original value.
/// Whether to be case sensitive in your replacement. Defaults to false, this being PowerShell
/// The original string, with all instances of the looked for value replaced with the new value.
public static string Replace(string String, string OldString, string NewString, bool CaseSensitive = false)
{
// Validate User Inputs (emulating the original C# behavior
if (String == null)
throw new ArgumentNullException(nameof(String));
if (String.Length == 0)
return String;
if (OldString == null)
throw new ArgumentNullException(nameof(OldString));
if (OldString.Length == 0)
throw new ArgumentException("String cannot be of zero length.");
StringComparison comparisonType = StringComparison.OrdinalIgnoreCase;
if (CaseSensitive)
comparisonType = StringComparison.Ordinal;
StringBuilder resultStringBuilder = new StringBuilder();
bool isReplacementNullOrEmpty = string.IsNullOrEmpty(NewString);
int foundAt;
int startSearchFromIndex = 0;
while ((foundAt = String.IndexOf(OldString, startSearchFromIndex, comparisonType)) != -1)
{
int charsUntilReplacement = foundAt - startSearchFromIndex;
bool isNothingToAppend = charsUntilReplacement == 0;
if (!isNothingToAppend)
resultStringBuilder.Append(String, startSearchFromIndex, charsUntilReplacement);
// Process the replacement.
if (!isReplacementNullOrEmpty)
resultStringBuilder.Append(NewString);
// Reset Search Index
startSearchFromIndex = foundAt + OldString.Length;
if (startSearchFromIndex == String.Length)
return resultStringBuilder.ToString();
}
resultStringBuilder.Append(String, startSearchFromIndex, (String.Length - startSearchFromIndex));
return resultStringBuilder.ToString();
}
}
}