Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
FileSystemName.cs
Go to the documentation of this file.
1using System.Text;
2
4
5public static class FileSystemName
6{
7 private static readonly char[] s_wildcardChars = new char[5] { '"', '<', '>', '*', '?' };
8
9 private static readonly char[] s_simpleWildcardChars = new char[2] { '*', '?' };
10
11 public static string TranslateWin32Expression(string? expression)
12 {
13 if (string.IsNullOrEmpty(expression) || expression == "*" || expression == "*.*")
14 {
15 return "*";
16 }
17 bool flag = false;
18 Span<char> initialBuffer = stackalloc char[32];
19 ValueStringBuilder valueStringBuilder = new ValueStringBuilder(initialBuffer);
20 int length = expression.Length;
21 for (int i = 0; i < length; i++)
22 {
23 char c = expression[i];
24 switch (c)
25 {
26 case '.':
27 flag = true;
28 if (i >= 1 && i == length - 1 && expression[i - 1] == '*')
29 {
30 valueStringBuilder[valueStringBuilder.Length - 1] = '<';
31 }
32 else if (i < length - 1 && (expression[i + 1] == '?' || expression[i + 1] == '*'))
33 {
34 valueStringBuilder.Append('"');
35 }
36 else
37 {
38 valueStringBuilder.Append('.');
39 }
40 break;
41 case '?':
42 flag = true;
43 valueStringBuilder.Append('>');
44 break;
45 default:
46 valueStringBuilder.Append(c);
47 break;
48 }
49 }
50 if (!flag)
51 {
52 return expression;
53 }
54 return valueStringBuilder.ToString();
55 }
56
57 public static bool MatchesWin32Expression(ReadOnlySpan<char> expression, ReadOnlySpan<char> name, bool ignoreCase = true)
58 {
59 return MatchPattern(expression, name, ignoreCase, useExtendedWildcards: true);
60 }
61
62 public static bool MatchesSimpleExpression(ReadOnlySpan<char> expression, ReadOnlySpan<char> name, bool ignoreCase = true)
63 {
64 return MatchPattern(expression, name, ignoreCase, useExtendedWildcards: false);
65 }
66
67 private static bool MatchPattern(ReadOnlySpan<char> expression, ReadOnlySpan<char> name, bool ignoreCase, bool useExtendedWildcards)
68 {
69 if (expression.Length == 0 || name.Length == 0)
70 {
71 return false;
72 }
73 if (expression[0] == '*')
74 {
75 if (expression.Length == 1)
76 {
77 return true;
78 }
79 ReadOnlySpan<char> readOnlySpan = expression.Slice(1);
80 if (readOnlySpan.IndexOfAny(useExtendedWildcards ? s_wildcardChars : s_simpleWildcardChars) == -1)
81 {
82 if (name.Length < readOnlySpan.Length)
83 {
84 return false;
85 }
86 return name.EndsWith(readOnlySpan, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal);
87 }
88 }
89 int num = 0;
90 int num2 = 1;
91 char c = '\0';
92 Span<int> span = default(Span<int>);
93 Span<int> span2 = stackalloc int[16];
94 Span<int> span3 = stackalloc int[16];
95 span3[0] = 0;
96 int num3 = expression.Length * 2;
97 bool flag = false;
98 int num6;
99 while (!flag)
100 {
101 if (num < name.Length)
102 {
103 c = name[num++];
104 }
105 else
106 {
107 if (span3[num2 - 1] == num3)
108 {
109 break;
110 }
111 flag = true;
112 }
113 int i = 0;
114 int num4 = 0;
115 int j = 0;
116 while (i < num2)
117 {
118 int num5 = (span3[i++] + 1) / 2;
119 while (num5 < expression.Length)
120 {
121 num6 = num5 * 2;
122 char c2 = expression[num5];
123 if (num4 >= span2.Length - 2)
124 {
125 int num7 = span2.Length * 2;
126 span = new int[num7];
127 span2.CopyTo(span);
128 span2 = span;
129 span = new int[num7];
130 span3.CopyTo(span);
131 span3 = span;
132 }
133 if (c2 != '*')
134 {
135 if (!useExtendedWildcards || c2 != '<')
136 {
137 num6 += 2;
138 if (useExtendedWildcards && c2 == '>')
139 {
140 if (!flag && c != '.')
141 {
142 span2[num4++] = num6;
143 break;
144 }
145 }
146 else
147 {
148 if (!useExtendedWildcards || c2 != '"')
149 {
150 if (c2 == '\\')
151 {
152 if (++num5 == expression.Length)
153 {
154 span2[num4++] = num3;
155 break;
156 }
157 num6 = num5 * 2 + 2;
158 c2 = expression[num5];
159 }
160 if (!flag)
161 {
162 if (c2 == '?')
163 {
164 span2[num4++] = num6;
165 }
166 else if (ignoreCase ? (char.ToUpperInvariant(c2) == char.ToUpperInvariant(c)) : (c2 == c))
167 {
168 span2[num4++] = num6;
169 }
170 }
171 break;
172 }
173 if (!flag)
174 {
175 if (c == '.')
176 {
177 span2[num4++] = num6;
178 }
179 break;
180 }
181 }
182 goto IL_02e4;
183 }
184 bool flag2 = false;
185 if (!flag && c == '.')
186 {
187 for (int k = num; k < name.Length; k++)
188 {
189 if (name[k] == '.')
190 {
191 flag2 = true;
192 break;
193 }
194 }
195 }
196 if (!(flag || c != '.' || flag2))
197 {
198 goto IL_02d3;
199 }
200 }
201 span2[num4++] = num6;
202 goto IL_02d3;
203 IL_02e4:
204 if (++num5 == expression.Length)
205 {
206 span2[num4++] = num3;
207 }
208 continue;
209 IL_02d3:
210 span2[num4++] = num6 + 1;
211 goto IL_02e4;
212 }
213 if (i >= num2 || j >= num4)
214 {
215 continue;
216 }
217 for (; j < num4; j++)
218 {
219 for (int length = span3.Length; i < length && span3[i] < span2[j]; i++)
220 {
221 }
222 }
223 }
224 if (num4 == 0)
225 {
226 return false;
227 }
228 span = span3;
229 span3 = span2;
230 span2 = span;
231 num2 = num4;
232 }
233 num6 = span3[num2 - 1];
234 return num6 == num3;
235 }
236}
static bool MatchesSimpleExpression(ReadOnlySpan< char > expression, ReadOnlySpan< char > name, bool ignoreCase=true)
static bool MatchesWin32Expression(ReadOnlySpan< char > expression, ReadOnlySpan< char > name, bool ignoreCase=true)
static readonly char[] s_wildcardChars
static string TranslateWin32Expression(string? expression)
static bool MatchPattern(ReadOnlySpan< char > expression, ReadOnlySpan< char > name, bool ignoreCase, bool useExtendedWildcards)
static readonly char[] s_simpleWildcardChars
ReadOnlySpan< T > Slice(int start)
void CopyTo(Span< T > destination)
Definition Span.cs:224
int Length
Definition Span.cs:70