Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
JsonReaderHelper.cs
Go to the documentation of this file.
7
8namespace System.Text.Json;
9
10internal static class JsonReaderHelper
11{
13
14 public static (int, int) CountNewLines(ReadOnlySpan<byte> data)
15 {
16 int item = -1;
17 int num = 0;
18 for (int i = 0; i < data.Length; i++)
19 {
20 if (data[i] == 10)
21 {
22 item = i;
23 num++;
24 }
25 }
26 return (num, item);
27 }
28
29 internal static JsonValueKind ToValueKind(this JsonTokenType tokenType)
30 {
31 switch (tokenType)
32 {
33 case JsonTokenType.None:
34 return JsonValueKind.Undefined;
35 case JsonTokenType.StartArray:
36 return JsonValueKind.Array;
37 case JsonTokenType.StartObject:
38 return JsonValueKind.Object;
39 case JsonTokenType.String:
40 case JsonTokenType.Number:
41 case JsonTokenType.True:
42 case JsonTokenType.False:
43 case JsonTokenType.Null:
44 return (JsonValueKind)(tokenType - 4);
45 default:
46 return JsonValueKind.Undefined;
47 }
48 }
49
50 public static bool IsTokenTypePrimitive(JsonTokenType tokenType)
51 {
52 return (int)(tokenType - 7) <= 4;
53 }
54
55 public static bool IsHexDigit(byte nextByte)
56 {
58 }
59
60 [MethodImpl(MethodImplOptions.AggressiveInlining)]
62 {
63 return IndexOfOrLessThan(ref MemoryMarshal.GetReference(span), 34, 92, 32, span.Length);
64 }
65
66 private unsafe static int IndexOfOrLessThan(ref byte searchSpace, byte value0, byte value1, byte lessThan, int length)
67 {
68 IntPtr intPtr = (IntPtr)0;
71 {
72 int num = (int)Unsafe.AsPointer(ref searchSpace) & (Vector<byte>.Count - 1);
73 intPtr2 = (IntPtr)((Vector<byte>.Count - num) & (Vector<byte>.Count - 1));
74 }
75 while (true)
76 {
77 if ((nuint)(void*)intPtr2 >= (nuint)8u)
78 {
79 intPtr2 -= 8;
80 uint num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr);
81 if (value0 == num2 || value1 == num2 || lessThan > num2)
82 {
83 goto IL_0393;
84 }
85 num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 1);
86 if (value0 == num2 || value1 == num2 || lessThan > num2)
87 {
88 goto IL_039b;
89 }
90 num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 2);
91 if (value0 == num2 || value1 == num2 || lessThan > num2)
92 {
93 goto IL_03a9;
94 }
95 num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 3);
96 if (value0 != num2 && value1 != num2 && lessThan <= num2)
97 {
98 num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 4);
99 if (value0 != num2 && value1 != num2 && lessThan <= num2)
100 {
101 num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 5);
102 if (value0 != num2 && value1 != num2 && lessThan <= num2)
103 {
104 num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 6);
105 if (value0 != num2 && value1 != num2 && lessThan <= num2)
106 {
107 num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 7);
108 if (value0 == num2 || value1 == num2 || lessThan > num2)
109 {
110 break;
111 }
112 intPtr += 8;
113 continue;
114 }
115 return (int)(void*)(intPtr + 6);
116 }
117 return (int)(void*)(intPtr + 5);
118 }
119 return (int)(void*)(intPtr + 4);
120 }
121 goto IL_03b7;
122 }
123 if ((nuint)(void*)intPtr2 >= (nuint)4u)
124 {
125 intPtr2 -= 4;
126 uint num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr);
127 if (value0 == num2 || value1 == num2 || lessThan > num2)
128 {
129 goto IL_0393;
130 }
131 num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 1);
132 if (value0 == num2 || value1 == num2 || lessThan > num2)
133 {
134 goto IL_039b;
135 }
136 num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 2);
137 if (value0 == num2 || value1 == num2 || lessThan > num2)
138 {
139 goto IL_03a9;
140 }
141 num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 3);
142 if (value0 == num2 || value1 == num2 || lessThan > num2)
143 {
144 goto IL_03b7;
145 }
146 intPtr += 4;
147 }
148 while ((void*)intPtr2 != null)
149 {
150 intPtr2 -= 1;
151 uint num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr);
152 if (value0 != num2 && value1 != num2 && lessThan <= num2)
153 {
154 intPtr += 1;
155 continue;
156 }
157 goto IL_0393;
158 }
159 if (Vector.IsHardwareAccelerated && (int)(void*)intPtr < length)
160 {
161 intPtr2 = (IntPtr)((length - (int)(void*)intPtr) & ~(Vector<byte>.Count - 1));
162 Vector<byte> right = new Vector<byte>(value0);
165 for (; (void*)intPtr2 > (void*)intPtr; intPtr += Vector<byte>.Count)
166 {
167 Vector<byte> left = Unsafe.ReadUnaligned<Vector<byte>>(ref Unsafe.AddByteOffset(ref searchSpace, intPtr));
168 Vector<byte> vector = Vector.BitwiseOr(Vector.BitwiseOr(Vector.Equals(left, right), Vector.Equals(left, right2)), Vector.LessThan(left, right3));
169 if (!Vector<byte>.Zero.Equals(vector))
170 {
171 return (int)(void*)intPtr + LocateFirstFoundByte(vector);
172 }
173 }
174 if ((int)(void*)intPtr < length)
175 {
176 intPtr2 = (IntPtr)(length - (int)(void*)intPtr);
177 continue;
178 }
179 }
180 return -1;
181 IL_0393:
182 return (int)(void*)intPtr;
183 IL_039b:
184 return (int)(void*)(intPtr + 1);
185 IL_03b7:
186 return (int)(void*)(intPtr + 3);
187 IL_03a9:
188 return (int)(void*)(intPtr + 2);
189 }
190 return (int)(void*)(intPtr + 7);
191 }
192
193 [MethodImpl(MethodImplOptions.AggressiveInlining)]
195 {
196 Vector<ulong> vector = Vector.AsVectorUInt64(match);
197 ulong num = 0uL;
198 int i;
199 for (i = 0; i < Vector<ulong>.Count; i++)
200 {
201 num = vector[i];
202 if (num != 0L)
203 {
204 break;
205 }
206 }
207 return i * 8 + LocateFirstFoundByte(num);
208 }
209
210 [MethodImpl(MethodImplOptions.AggressiveInlining)]
211 private static int LocateFirstFoundByte(ulong match)
212 {
213 ulong num = match ^ (match - 1);
214 return (int)(num * 283686952306184L >> 57);
215 }
216
218 {
219 int idx = source.IndexOf<byte>(92);
220 Span<byte> span = stackalloc byte[252];
222 span = span.Slice(0, written);
224 {
225 value = value2;
226 return true;
227 }
228 value = default(DateTime);
229 return false;
230 }
231
233 {
234 int idx = source.IndexOf<byte>(92);
235 Span<byte> span = stackalloc byte[252];
237 span = span.Slice(0, written);
239 {
240 value = value2;
241 return true;
242 }
243 value = default(DateTimeOffset);
244 return false;
245 }
246
248 {
249 int idx = source.IndexOf<byte>(92);
250 Span<byte> span = stackalloc byte[216];
252 span = span.Slice(0, written);
253 if (span.Length == 36 && Utf8Parser.TryParse((ReadOnlySpan<byte>)span, out Guid value2, out int _, 'D'))
254 {
255 value = value2;
256 return true;
257 }
258 value = default(Guid);
259 return false;
260 }
261
263 {
264 if (span.Length == 3)
265 {
266 if (span.SequenceEqual(JsonConstants.NaNValue))
267 {
268 value = float.NaN;
269 return true;
270 }
271 }
272 else if (span.Length == 8)
273 {
274 if (span.SequenceEqual(JsonConstants.PositiveInfinityValue))
275 {
276 value = float.PositiveInfinity;
277 return true;
278 }
279 }
280 else if (span.Length == 9 && span.SequenceEqual(JsonConstants.NegativeInfinityValue))
281 {
282 value = float.NegativeInfinity;
283 return true;
284 }
285 value = 0f;
286 return false;
287 }
288
290 {
291 if (span.Length == 3)
292 {
293 if (span.SequenceEqual(JsonConstants.NaNValue))
294 {
295 value = double.NaN;
296 return true;
297 }
298 }
299 else if (span.Length == 8)
300 {
301 if (span.SequenceEqual(JsonConstants.PositiveInfinityValue))
302 {
303 value = double.PositiveInfinity;
304 return true;
305 }
306 }
307 else if (span.Length == 9 && span.SequenceEqual(JsonConstants.NegativeInfinityValue))
308 {
309 value = double.NegativeInfinity;
310 return true;
311 }
312 value = 0.0;
313 return false;
314 }
315
317 {
318 byte[] array = null;
319 Span<byte> span = ((utf8Source.Length > 256) ? ((Span<byte>)(array = ArrayPool<byte>.Shared.Rent(utf8Source.Length))) : stackalloc byte[256]);
322 span2 = span2.Slice(0, written);
323 bool result = TryDecodeBase64InPlace(span2, out bytes);
324 if (array != null)
325 {
326 span2.Clear();
328 }
329 return result;
330 }
331
333 {
334 int length = utf8Source.Length;
335 byte[] array = null;
336 Span<byte> span = ((length > 256) ? ((Span<byte>)(array = ArrayPool<byte>.Shared.Rent(length))) : stackalloc byte[256]);
339 span2 = span2.Slice(0, written);
340 string result = TranscodeHelper(span2);
341 if (array != null)
342 {
343 span2.Clear();
345 }
346 return result;
347 }
348
350 {
351 int length = utf8Source.Length;
352 byte[] array = null;
353 Span<byte> span = ((length > 256) ? ((Span<byte>)(array = ArrayPool<byte>.Shared.Rent(length))) : stackalloc byte[256]);
356 ReadOnlySpan<byte> result = destination.Slice(0, written).ToArray();
357 if (array != null)
358 {
359 new Span<byte>(array, 0, written).Clear();
361 }
362 return result;
363 }
364
366 {
367 byte[] array = null;
368 Span<byte> span = ((utf8Source.Length > 256) ? ((Span<byte>)(array = ArrayPool<byte>.Shared.Rent(utf8Source.Length))) : stackalloc byte[256]);
371 span2 = span2.Slice(0, written);
372 bool result = other.SequenceEqual(span2);
373 if (array != null)
374 {
375 span2.Clear();
377 }
378 return result;
379 }
380
382 {
383 byte[] array = null;
384 byte[] array2 = null;
385 int num = checked((int)utf8Source.Length);
386 Span<byte> span = ((num > 256) ? ((Span<byte>)(array2 = ArrayPool<byte>.Shared.Rent(num))) : stackalloc byte[256]);
388 Span<byte> span3 = ((num > 256) ? ((Span<byte>)(array = ArrayPool<byte>.Shared.Rent(num))) : stackalloc byte[256]);
391 span4 = span4.Slice(0, num);
393 span2 = span2.Slice(0, written);
394 bool result = other.SequenceEqual(span2);
395 if (array2 != null)
396 {
397 span2.Clear();
399 span4.Clear();
401 }
402 return result;
403 }
404
406 {
408 {
409 bytes = null;
410 return false;
411 }
412 bytes = utf8Unescaped.Slice(0, bytesWritten).ToArray();
413 return true;
414 }
415
417 {
418 byte[] array = null;
422 {
423 bytes = null;
424 if (array != null)
425 {
426 bytes2.Clear();
428 }
429 return false;
430 }
431 bytes = bytes2.Slice(0, bytesWritten).ToArray();
432 if (array != null)
433 {
434 bytes2.Clear();
436 }
437 return true;
438 }
439
441 {
442 try
443 {
444 return s_utf8Encoding.GetString(utf8Unescaped);
445 }
447 {
449 }
450 }
451
453 {
454 try
455 {
456 return s_utf8Encoding.GetByteCount(text);
457 }
459 {
461 }
462 }
463
465 {
466 try
467 {
468 return s_utf8Encoding.GetBytes(text, dest);
469 }
471 {
473 }
474 }
475
477 {
478 return s_utf8Encoding.GetString(utf8Text);
479 }
480
482 {
483 source.Slice(0, idx).CopyTo(destination);
484 written = idx;
485 while (idx < source.Length)
486 {
487 byte b = source[idx];
488 if (b == 92)
489 {
490 idx++;
491 switch (source[idx])
492 {
493 case 34:
494 destination[written++] = 34;
495 break;
496 case 110:
497 destination[written++] = 10;
498 break;
499 case 114:
500 destination[written++] = 13;
501 break;
502 case 92:
503 destination[written++] = 92;
504 break;
505 case 47:
506 destination[written++] = 47;
507 break;
508 case 116:
509 destination[written++] = 9;
510 break;
511 case 98:
512 destination[written++] = 8;
513 break;
514 case 102:
515 destination[written++] = 12;
516 break;
517 case 117:
518 {
519 bool flag = Utf8Parser.TryParse(source.Slice(idx + 1, 4), out int value, out int bytesConsumed, 'x');
521 if (JsonHelpers.IsInRangeInclusive((uint)value, 55296u, 57343u))
522 {
523 if (value >= 56320)
524 {
526 }
527 idx += 3;
528 if (source.Length < idx + 4 || source[idx - 2] != 92 || source[idx - 1] != 117)
529 {
531 }
532 flag = Utf8Parser.TryParse(source.Slice(idx, 4), out int value2, out bytesConsumed, 'x');
533 if (!JsonHelpers.IsInRangeInclusive((uint)value2, 56320u, 57343u))
534 {
536 }
537 idx += bytesConsumed - 1;
538 value = 1024 * (value - 55296) + (value2 - 56320) + 65536;
539 }
540 int num = new Rune(value).EncodeToUtf8(destination.Slice(written));
541 written += num;
542 break;
543 }
544 }
545 }
546 else
547 {
548 destination[written++] = b;
549 }
550 idx++;
551 }
552 }
553}
static ArrayPool< T > Shared
Definition ArrayPool.cs:7
static unsafe OperationStatus DecodeFromUtf8InPlace(Span< byte > buffer, out int bytesWritten)
Definition Base64.cs:223
static unsafe OperationStatus DecodeFromUtf8(ReadOnlySpan< byte > utf8, Span< byte > bytes, out int bytesConsumed, out int bytesWritten, bool isFinalBlock=true)
Definition Base64.cs:43
static bool TryParse(ReadOnlySpan< byte > source, out bool value, out int bytesConsumed, char standardFormat='\0')
static bool IsHexChar(int c)
static Vector< int > LessThan(Vector< float > left, Vector< float > right)
Definition Vector.cs:99
static bool IsHardwareAccelerated
Definition Vector.cs:14
static Vector< int > Equals(Vector< float > left, Vector< float > right)
Definition Vector.cs:52
static ReadOnlySpan< byte > PositiveInfinityValue
static ReadOnlySpan< byte > NaNValue
static ReadOnlySpan< byte > NegativeInfinityValue
static bool IsInRangeInclusive(uint value, uint lowerBound, uint upperBound)
static bool TryParseAsISO(ReadOnlySpan< byte > source, out DateTime value)
static unsafe int IndexOfOrLessThan(ref byte searchSpace, byte value0, byte value1, byte lessThan, int length)
static bool TryGetEscapedDateTime(ReadOnlySpan< byte > source, out DateTime value)
static string TranscodeHelper(ReadOnlySpan< byte > utf8Unescaped)
static ReadOnlySpan< byte > GetUnescapedSpan(ReadOnlySpan< byte > utf8Source, int idx)
static JsonValueKind ToValueKind(this JsonTokenType tokenType)
static bool UnescapeAndCompare(ReadOnlySequence< byte > utf8Source, ReadOnlySpan< byte > other)
static string GetUnescapedString(ReadOnlySpan< byte > utf8Source, int idx)
static bool TryGetEscapedDateTimeOffset(ReadOnlySpan< byte > source, out DateTimeOffset value)
static bool UnescapeAndCompare(ReadOnlySpan< byte > utf8Source, ReadOnlySpan< byte > other)
static bool TryGetEscapedGuid(ReadOnlySpan< byte > source, out Guid value)
static int LocateFirstFoundByte(Vector< byte > match)
static int GetUtf8FromText(ReadOnlySpan< char > text, Span< byte > dest)
static bool IsHexDigit(byte nextByte)
static void Unescape(ReadOnlySpan< byte > source, Span< byte > destination, int idx, out int written)
static int LocateFirstFoundByte(ulong match)
static int IndexOfQuoteOrAnyControlOrBackSlash(this ReadOnlySpan< byte > span)
static bool TryGetFloatingPointConstant(ReadOnlySpan< byte > span, out float value)
static bool TryGetUnescapedBase64Bytes(ReadOnlySpan< byte > utf8Source, int idx, [NotNullWhen(true)] out byte[] bytes)
static readonly UTF8Encoding s_utf8Encoding
static string GetTextFromUtf8(ReadOnlySpan< byte > utf8Text)
static bool TryGetFloatingPointConstant(ReadOnlySpan< byte > span, out double value)
static bool IsTokenTypePrimitive(JsonTokenType tokenType)
static bool TryDecodeBase64(ReadOnlySpan< byte > utf8Unescaped, [NotNullWhen(true)] out byte[] bytes)
static int CountNewLines(ReadOnlySpan< byte > data)
static bool TryDecodeBase64InPlace(Span< byte > utf8Unescaped, [NotNullWhen(true)] out byte[] bytes)
static int GetUtf8ByteCount(ReadOnlySpan< char > text)
static InvalidOperationException GetInvalidOperationException_ReadInvalidUTF8(DecoderFallbackException innerException)
static ArgumentException GetArgumentException_ReadInvalidUTF16(EncoderFallbackException innerException)
static void ThrowInvalidOperationException_ReadInvalidUTF16(int charAsInt)
ReadOnlySpan< T > Slice(int start)
void CopyTo(Span< T > destination)
Definition Span.cs:224
unsafe void Clear()
Definition Span.cs:198
int EncodeToUtf8(Span< byte > destination)
Definition Rune.cs:383