Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
XPathScanner.cs
Go to the documentation of this file.
1using System;
4using System.Xml;
6
8
9internal struct XPathScanner
10{
11 public enum LexKind
12 {
13 Comma = 44,
14 Slash = 47,
15 At = 64,
16 Dot = 46,
17 LParens = 40,
18 RParens = 41,
19 LBracket = 91,
20 RBracket = 93,
21 Star = 42,
22 Plus = 43,
23 Minus = 45,
24 Eq = 61,
25 Lt = 60,
26 Gt = 62,
27 Bang = 33,
28 Dollar = 36,
29 Apos = 39,
30 Quote = 34,
31 Union = 124,
32 Ne = 78,
33 Le = 76,
34 Ge = 71,
35 And = 65,
36 Or = 79,
37 DotDot = 68,
38 SlashSlash = 83,
39 Name = 110,
40 String = 115,
41 Number = 100,
42 Axe = 97,
43 Eof = 69
44 }
45
46 private readonly string _xpathExpr;
47
48 private int _xpathExprIndex;
49
50 private LexKind _kind;
51
52 private char _currentChar;
53
54 private string _name;
55
56 private string _prefix;
57
58 private string _stringValue;
59
60 private double _numberValue;
61
62 private bool _canBeFunction;
63
64 public string SourceText => _xpathExpr;
65
66 private char CurrentChar => _currentChar;
67
68 public LexKind Kind => _kind;
69
70 public string Name => _name;
71
72 public string Prefix => _prefix;
73
74 public string StringValue => _stringValue;
75
76 public double NumberValue => _numberValue;
77
79
80 public XPathScanner(string xpathExpr)
81 {
82 this = default(XPathScanner);
83 if (xpathExpr == null)
84 {
85 throw XPathException.Create(System.SR.Xp_ExprExpected, string.Empty);
86 }
88 _numberValue = double.NaN;
89 NextChar();
90 NextLex();
91 }
92
93 private bool NextChar()
94 {
95 string xpathExpr = _xpathExpr;
97 if ((uint)xpathExprIndex < (uint)xpathExpr.Length)
98 {
101 return true;
102 }
103 _currentChar = '\0';
104 return false;
105 }
106
107 [MethodImpl(MethodImplOptions.AggressiveInlining)]
108 private void SkipSpace()
109 {
111 {
113 }
114 }
115
116 private void SkipKnownSpace()
117 {
119 {
120 }
121 }
122
123 public bool NextLex()
124 {
125 SkipSpace();
126 switch (CurrentChar)
127 {
128 case '\0':
129 _kind = LexKind.Eof;
130 return false;
131 case '#':
132 case '$':
133 case '(':
134 case ')':
135 case '*':
136 case '+':
137 case ',':
138 case '-':
139 case '=':
140 case '@':
141 case '[':
142 case ']':
143 case '|':
145 NextChar();
146 break;
147 case '<':
148 _kind = LexKind.Lt;
149 NextChar();
150 if (CurrentChar == '=')
151 {
152 _kind = LexKind.Le;
153 NextChar();
154 }
155 break;
156 case '>':
157 _kind = LexKind.Gt;
158 NextChar();
159 if (CurrentChar == '=')
160 {
161 _kind = LexKind.Ge;
162 NextChar();
163 }
164 break;
165 case '!':
166 _kind = LexKind.Bang;
167 NextChar();
168 if (CurrentChar == '=')
169 {
170 _kind = LexKind.Ne;
171 NextChar();
172 }
173 break;
174 case '.':
175 _kind = LexKind.Dot;
176 NextChar();
177 if (CurrentChar == '.')
178 {
179 _kind = LexKind.DotDot;
180 NextChar();
181 }
183 {
184 _kind = LexKind.Number;
186 }
187 break;
188 case '/':
189 _kind = LexKind.Slash;
190 NextChar();
191 if (CurrentChar == '/')
192 {
193 _kind = LexKind.SlashSlash;
194 NextChar();
195 }
196 break;
197 case '"':
198 case '\'':
199 _kind = LexKind.String;
201 break;
202 default:
204 {
205 _kind = LexKind.Number;
207 break;
208 }
210 {
211 _kind = LexKind.Name;
212 _name = ScanName();
213 _prefix = string.Empty;
214 if (CurrentChar == ':')
215 {
216 NextChar();
217 if (CurrentChar == ':')
218 {
219 NextChar();
220 _kind = LexKind.Axe;
221 }
222 else
223 {
224 _prefix = _name;
225 if (CurrentChar == '*')
226 {
227 NextChar();
228 _name = "*";
229 }
230 else
231 {
233 {
235 }
236 _name = ScanName();
237 }
238 }
239 }
240 else
241 {
242 SkipSpace();
243 if (CurrentChar == ':')
244 {
245 NextChar();
246 if (CurrentChar != ':')
247 {
249 }
250 NextChar();
251 _kind = LexKind.Axe;
252 }
253 }
254 SkipSpace();
256 break;
257 }
259 }
260 return true;
261 }
262
263 private double ScanNumber()
264 {
265 int startIndex = _xpathExprIndex - 1;
266 int num = 0;
268 {
269 NextChar();
270 num++;
271 }
272 if (CurrentChar == '.')
273 {
274 NextChar();
275 num++;
277 {
278 NextChar();
279 num++;
280 }
281 }
282 return XmlConvert.ToXPathDouble(_xpathExpr.Substring(startIndex, num));
283 }
284
285 private double ScanFraction()
286 {
287 int startIndex = _xpathExprIndex - 2;
288 int num = 1;
290 {
291 NextChar();
292 num++;
293 }
294 return XmlConvert.ToXPathDouble(_xpathExpr.Substring(startIndex, num));
295 }
296
297 private string ScanString()
298 {
300 NextChar();
301 int startIndex = _xpathExprIndex - 1;
302 int num = 0;
303 while (CurrentChar != currentChar)
304 {
305 if (!NextChar())
306 {
308 }
309 num++;
310 }
311 NextChar();
312 return _xpathExpr.Substring(startIndex, num);
313 }
314
315 private string ScanName()
316 {
318 int i;
320 {
321 }
322 if ((uint)i < (uint)readOnlySpan.Length)
323 {
325 _xpathExprIndex += i;
326 return readOnlySpan.Slice(0, i).ToString();
327 }
328 _currentChar = '\0';
329 _xpathExprIndex += i - 1;
330 return readOnlySpan.ToString();
331 }
332}
static int ToInt32(object? value)
Definition Convert.cs:1320
static CultureInfo InvariantCulture
static string Xp_InvalidName
Definition SR.cs:1240
static string Xp_ExprExpected
Definition SR.cs:1234
static string Xp_InvalidToken
Definition SR.cs:1242
static string Xp_UnclosedString
Definition SR.cs:1232
Definition SR.cs:7
static XPathException Create(string res)
static bool IsStartNCNameSingleChar(char ch)
static bool IsNCNameSingleChar(char ch)
static bool IsWhiteSpace(char ch)
static bool IsDigit(char ch)
static double ToXPathDouble(object o)