Repository navigation
Expand file tree
/
Copy pathUtilityHost.cs
More file actions
179 lines (162 loc) · 7.02 KB
/
Copy pathUtilityHost.cs
File metadata and controls
179 lines (162 loc) · 7.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
using System;
using System.Collections.Generic;
using System.Management.Automation.Host;
using System.Text;
namespace PSModuleDevelopment.Utility
{
/// <summary>
/// Host class, containing statics in support of the utility namespace
/// </summary>
public static class UtilityHost
{
/// <summary>
/// Gives access to the host UI, in order to access window information
/// </summary>
public static PSHostRawUserInterface RawUI;
/// <summary>
/// Implement's VB's Like operator logic.
/// </summary>
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<char> 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);
}
/// <summary>
/// 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.
/// </summary>
/// <param name="charList">Character list string</param>
private static HashSet<char> CharListToSet(string charList)
{
HashSet<char> set = new HashSet<char>();
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;
}
/// <summary>
/// Replace a value in a string with another.
/// Extends the default c# String.Replace with the capability to be case-insensitive.
/// </summary>
/// <param name="String">The string to modify</param>
/// <param name="OldString">The value to look for and replace with someting else</param>
/// <param name="NewString">The value to insert where you found the previous value. Leave empty to just delete the original value.</param>
/// <param name="CaseSensitive">Whether to be case sensitive in your replacement. Defaults to false, this being PowerShell</param>
/// <returns>The original string, with all instances of the looked for value replaced with the new value.</returns>
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();
}
}
}