Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
JsonWriterHelper.cs
Go to the documentation of this file.
6
7namespace System.Text.Json;
8
9internal static class JsonWriterHelper
10{
11 private static readonly StandardFormat s_dateTimeStandardFormat = new StandardFormat('O');
12
13 private static readonly StandardFormat s_hexStandardFormat = new StandardFormat('X', 4);
14
15 private static ReadOnlySpan<byte> AllowList => new byte[256]
16 {
17 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
18 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
19 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
20 0, 0, 1, 1, 0, 1, 1, 1, 0, 0,
21 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
22 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
23 0, 1, 0, 1, 1, 1, 1, 1, 1, 1,
24 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
25 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
26 1, 1, 0, 1, 1, 1, 0, 1, 1, 1,
27 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
28 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
29 1, 1, 1, 1, 1, 1, 1, 0, 0, 0,
30 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
32 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
33 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
34 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
35 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
36 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
37 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
38 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
39 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
40 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
41 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
42 0, 0, 0, 0, 0, 0
43 };
44
45 public static void WriteIndentation(Span<byte> buffer, int indent)
46 {
47 if (indent < 8)
48 {
49 int num = 0;
50 while (num < indent)
51 {
52 buffer[num++] = 32;
53 buffer[num++] = 32;
54 }
55 }
56 else
57 {
58 buffer.Slice(0, indent).Fill(32);
59 }
60 }
61
62 [MethodImpl(MethodImplOptions.AggressiveInlining)]
64 {
65 if (propertyName.Length > 166666666)
66 {
68 }
69 }
70
71 [MethodImpl(MethodImplOptions.AggressiveInlining)]
73 {
74 if (value.Length > 166666666)
75 {
77 }
78 }
79
80 [MethodImpl(MethodImplOptions.AggressiveInlining)]
82 {
83 if (bytes.Length > 125000000)
84 {
86 }
87 }
88
89 [MethodImpl(MethodImplOptions.AggressiveInlining)]
90 public static void ValidateDouble(double value)
91 {
93 {
95 }
96 }
97
98 [MethodImpl(MethodImplOptions.AggressiveInlining)]
99 public static void ValidateSingle(float value)
100 {
102 {
104 }
105 }
106
107 [MethodImpl(MethodImplOptions.AggressiveInlining)]
109 {
110 if (propertyName.Length > 166666666)
111 {
113 }
114 }
115
116 [MethodImpl(MethodImplOptions.AggressiveInlining)]
118 {
119 if (value.Length > 166666666)
120 {
122 }
123 }
124
125 [MethodImpl(MethodImplOptions.AggressiveInlining)]
127 {
128 if (propertyName.Length > 166666666 || value.Length > 166666666)
129 {
131 }
132 }
133
134 [MethodImpl(MethodImplOptions.AggressiveInlining)]
136 {
137 if (propertyName.Length > 166666666 || value.Length > 166666666)
138 {
140 }
141 }
142
143 [MethodImpl(MethodImplOptions.AggressiveInlining)]
145 {
146 if (propertyName.Length > 166666666 || value.Length > 166666666)
147 {
149 }
150 }
151
152 [MethodImpl(MethodImplOptions.AggressiveInlining)]
154 {
155 if (propertyName.Length > 166666666 || value.Length > 166666666)
156 {
158 }
159 }
160
161 [MethodImpl(MethodImplOptions.AggressiveInlining)]
163 {
164 if (propertyName.Length > 166666666 || bytes.Length > 125000000)
165 {
167 }
168 }
169
170 [MethodImpl(MethodImplOptions.AggressiveInlining)]
172 {
173 if (propertyName.Length > 166666666 || bytes.Length > 125000000)
174 {
176 }
177 }
178
180 {
181 int i = 0;
182 if (utf8FormattedNumber[i] == 45)
183 {
184 i++;
185 if (utf8FormattedNumber.Length <= i)
186 {
187 throw new ArgumentException(System.SR.RequiredDigitNotFoundEndOfData, "utf8FormattedNumber");
188 }
189 }
190 if (utf8FormattedNumber[i] == 48)
191 {
192 i++;
193 }
194 else
195 {
197 {
198 }
199 }
200 if (i == utf8FormattedNumber.Length)
201 {
202 return;
203 }
204 byte b = utf8FormattedNumber[i];
205 if (b == 46)
206 {
207 i++;
208 if (utf8FormattedNumber.Length <= i)
209 {
210 throw new ArgumentException(System.SR.RequiredDigitNotFoundEndOfData, "utf8FormattedNumber");
211 }
213 {
214 }
215 if (i == utf8FormattedNumber.Length)
216 {
217 return;
218 }
220 }
221 if (b == 101 || b == 69)
222 {
223 i++;
224 if (utf8FormattedNumber.Length <= i)
225 {
226 throw new ArgumentException(System.SR.RequiredDigitNotFoundEndOfData, "utf8FormattedNumber");
227 }
229 if (b == 43 || b == 45)
230 {
231 i++;
232 }
233 if (utf8FormattedNumber.Length <= i)
234 {
235 throw new ArgumentException(System.SR.RequiredDigitNotFoundEndOfData, "utf8FormattedNumber");
236 }
238 {
239 }
240 if (i == utf8FormattedNumber.Length)
241 {
242 return;
243 }
245 }
247 }
248
256
264
266 {
267 if (buffer[26] != 48)
268 {
269 bytesWritten = buffer.Length;
270 return;
271 }
272 int num = ((buffer[25] != 48) ? 26 : ((buffer[24] != 48) ? 25 : ((buffer[23] != 48) ? 24 : ((buffer[22] != 48) ? 23 : ((buffer[21] != 48) ? 22 : ((buffer[20] != 48) ? 21 : 19))))));
273 if (buffer.Length == 27)
274 {
275 bytesWritten = num;
276 }
277 else if (buffer.Length == 33)
278 {
279 buffer[num] = buffer[27];
280 buffer[num + 1] = buffer[28];
281 buffer[num + 2] = buffer[29];
282 buffer[num + 3] = buffer[30];
283 buffer[num + 4] = buffer[31];
284 buffer[num + 5] = buffer[32];
285 bytesWritten = num + 6;
286 }
287 else
288 {
289 buffer[num] = 90;
290 bytesWritten = num + 1;
291 }
292 }
293
294 private static bool NeedsEscaping(byte value)
295 {
296 return AllowList[value] == 0;
297 }
298
299 private static bool NeedsEscapingNoBoundsCheck(char value)
300 {
301 return AllowList[value] == 0;
302 }
303
305 {
306 return (encoder ?? JavaScriptEncoder.Default).FindFirstCharacterToEncodeUtf8(value);
307 }
308
309 public unsafe static int NeedsEscaping(ReadOnlySpan<char> value, JavaScriptEncoder encoder)
310 {
311 if (value.IsEmpty)
312 {
313 return -1;
314 }
315 fixed (char* text = value)
316 {
317 return (encoder ?? JavaScriptEncoder.Default).FindFirstCharacterToEncode(text, value.Length);
318 }
319 }
320
322 {
324 }
325
334
336 {
339 if (encoder != null)
340 {
344 return;
345 }
346 while (indexOfFirstByteToEscape < value.Length)
347 {
349 if (IsAsciiValue(b))
350 {
351 if (NeedsEscaping(b))
352 {
355 }
356 else
357 {
359 written++;
361 }
362 continue;
363 }
367 break;
368 }
369 }
370
371 private static void EscapeNextBytes(byte value, Span<byte> destination, ref int written)
372 {
373 destination[written++] = 92;
374 switch (value)
375 {
376 case 34:
377 destination[written++] = 117;
378 destination[written++] = 48;
379 destination[written++] = 48;
380 destination[written++] = 50;
381 destination[written++] = 50;
382 break;
383 case 10:
384 destination[written++] = 110;
385 break;
386 case 13:
387 destination[written++] = 114;
388 break;
389 case 9:
390 destination[written++] = 116;
391 break;
392 case 92:
393 destination[written++] = 92;
394 break;
395 case 8:
396 destination[written++] = 98;
397 break;
398 case 12:
399 destination[written++] = 102;
400 break;
401 default:
402 {
403 destination[written++] = 117;
404 int bytesWritten;
407 break;
408 }
409 }
410 }
411
412 private static bool IsAsciiValue(byte value)
413 {
414 return value <= 127;
415 }
416
417 private static bool IsAsciiValue(char value)
418 {
419 return value <= '\u007f';
420 }
421
430
432 {
435 if (encoder != null)
436 {
440 return;
441 }
442 while (indexOfFirstByteToEscape < value.Length)
443 {
445 if (IsAsciiValue(c))
446 {
448 {
451 }
452 else
453 {
454 destination[written] = c;
455 written++;
457 }
458 continue;
459 }
463 break;
464 }
465 }
466
467 private static void EscapeNextChars(char value, Span<char> destination, ref int written)
468 {
469 destination[written++] = '\\';
470 switch ((byte)value)
471 {
472 case 34:
473 destination[written++] = 'u';
474 destination[written++] = '0';
475 destination[written++] = '0';
476 destination[written++] = '2';
477 destination[written++] = '2';
478 break;
479 case 10:
480 destination[written++] = 'n';
481 break;
482 case 13:
483 destination[written++] = 'r';
484 break;
485 case 9:
486 destination[written++] = 't';
487 break;
488 case 92:
489 destination[written++] = '\\';
490 break;
491 case 8:
492 destination[written++] = 'b';
493 break;
494 case 12:
495 destination[written++] = 'f';
496 break;
497 default:
498 {
499 destination[written++] = 'u';
500 int num = value;
501 num.TryFormat(destination.Slice(written), out var charsWritten, "X4");
503 break;
504 }
505 }
506 }
507
509 {
510 fixed (byte* ptr = &MemoryMarshal.GetReference(utf16Source))
511 {
512 fixed (byte* ptr3 = &MemoryMarshal.GetReference(utf8Destination))
513 {
514 char* ptr2 = (char*)ptr;
515 byte* ptr4 = ptr3;
516 char* ptr5 = (char*)(ptr + utf16Source.Length);
517 byte* ptr6 = ptr4 + utf8Destination.Length;
518 while (true)
519 {
520 IL_025a:
521 if (ptr5 - ptr2 > 13)
522 {
523 int num = Math.Min(PtrDiff(ptr5, ptr2), PtrDiff(ptr6, ptr4));
524 char* ptr7 = ptr2 + num - 5;
525 if (ptr2 < ptr7)
526 {
527 while (true)
528 {
529 int num2 = *ptr2;
530 ptr2++;
531 if (num2 > 127)
532 {
533 goto IL_0181;
534 }
535 *ptr4 = (byte)num2;
536 ptr4++;
537 if (((uint)(int)ptr2 & 2u) != 0)
538 {
539 num2 = *ptr2;
540 ptr2++;
541 if (num2 > 127)
542 {
543 goto IL_0181;
544 }
545 *ptr4 = (byte)num2;
546 ptr4++;
547 }
548 while (ptr2 < ptr7)
549 {
550 num2 = *(int*)ptr2;
551 int num3 = *(int*)(ptr2 + 2);
552 if (((num2 | num3) & -8323200) == 0)
553 {
555 {
556 *ptr4 = (byte)(num2 >> 16);
557 ptr4[1] = (byte)num2;
558 ptr2 += 4;
559 ptr4[2] = (byte)(num3 >> 16);
560 ptr4[3] = (byte)num3;
561 ptr4 += 4;
562 }
563 else
564 {
565 *ptr4 = (byte)num2;
566 ptr4[1] = (byte)(num2 >> 16);
567 ptr2 += 4;
568 ptr4[2] = (byte)num3;
569 ptr4[3] = (byte)(num3 >> 16);
570 ptr4 += 4;
571 }
572 continue;
573 }
574 goto IL_014f;
575 }
576 goto IL_0251;
577 IL_014f:
578 num2 = (BitConverter.IsLittleEndian ? ((ushort)num2) : (num2 >>> 16));
579 ptr2++;
580 if (num2 > 127)
581 {
582 goto IL_0181;
583 }
584 *ptr4 = (byte)num2;
585 ptr4++;
586 goto IL_0251;
587 IL_0251:
588 if (ptr2 < ptr7)
589 {
590 continue;
591 }
592 goto IL_025a;
593 IL_0181:
594 int num4;
595 if (num2 <= 2047)
596 {
597 num4 = -64 | (num2 >> 6);
598 }
599 else
600 {
601 if (!JsonHelpers.IsInRangeInclusive(num2, 55296, 57343))
602 {
603 num4 = -32 | (num2 >> 12);
604 }
605 else
606 {
607 if (num2 > 56319)
608 {
609 break;
610 }
611 num4 = *ptr2;
612 if (!JsonHelpers.IsInRangeInclusive(num4, 56320, 57343))
613 {
614 break;
615 }
616 ptr2++;
617 num2 = num4 + (num2 << 10) + -56613888;
618 *ptr4 = (byte)(0xFFFFFFF0u | (uint)(num2 >> 18));
619 ptr4++;
620 num4 = -128 | ((num2 >> 12) & 0x3F);
621 }
622 *ptr4 = (byte)num4;
623 ptr7--;
624 ptr4++;
625 num4 = -128 | ((num2 >> 6) & 0x3F);
626 }
627 *ptr4 = (byte)num4;
628 ptr7--;
629 ptr4[1] = (byte)(0xFFFFFF80u | ((uint)num2 & 0x3Fu));
630 ptr4 += 2;
631 goto IL_0251;
632 }
633 break;
634 }
635 }
636 while (true)
637 {
638 int num5;
639 int num6;
640 if (ptr2 < ptr5)
641 {
642 num5 = *ptr2;
643 ptr2++;
644 if (num5 <= 127)
645 {
646 if (ptr6 - ptr4 > 0)
647 {
648 *ptr4 = (byte)num5;
649 ptr4++;
650 continue;
651 }
652 }
653 else if (num5 <= 2047)
654 {
655 if (ptr6 - ptr4 > 1)
656 {
657 num6 = -64 | (num5 >> 6);
658 goto IL_0380;
659 }
660 }
661 else if (!JsonHelpers.IsInRangeInclusive(num5, 55296, 57343))
662 {
663 if (ptr6 - ptr4 > 2)
664 {
665 num6 = -32 | (num5 >> 12);
666 goto IL_0368;
667 }
668 }
669 else if (ptr6 - ptr4 > 3)
670 {
671 if (num5 > 56319)
672 {
673 break;
674 }
675 if (ptr2 < ptr5)
676 {
677 num6 = *ptr2;
678 if (!JsonHelpers.IsInRangeInclusive(num6, 56320, 57343))
679 {
680 break;
681 }
682 ptr2++;
683 num5 = num6 + (num5 << 10) + -56613888;
684 *ptr4 = (byte)(0xFFFFFFF0u | (uint)(num5 >> 18));
685 ptr4++;
686 num6 = -128 | ((num5 >> 12) & 0x3F);
687 goto IL_0368;
688 }
689 bytesConsumed = (int)((byte*)(ptr2 - 1) - ptr);
690 bytesWritten = (int)(ptr4 - ptr3);
691 return OperationStatus.NeedMoreData;
692 }
693 bytesConsumed = (int)((byte*)(ptr2 - 1) - ptr);
694 bytesWritten = (int)(ptr4 - ptr3);
695 return OperationStatus.DestinationTooSmall;
696 }
697 bytesConsumed = (int)((byte*)ptr2 - ptr);
698 bytesWritten = (int)(ptr4 - ptr3);
699 return OperationStatus.Done;
700 IL_0368:
701 *ptr4 = (byte)num6;
702 ptr4++;
703 num6 = -128 | ((num5 >> 6) & 0x3F);
704 goto IL_0380;
705 IL_0380:
706 *ptr4 = (byte)num6;
707 ptr4[1] = (byte)(0xFFFFFF80u | ((uint)num5 & 0x3Fu));
708 ptr4 += 2;
709 }
710 break;
711 }
712 bytesConsumed = (int)((byte*)(ptr2 - 1) - ptr);
713 bytesWritten = (int)(ptr4 - ptr3);
714 return OperationStatus.InvalidData;
715 }
716 }
717 }
718
719 [MethodImpl(MethodImplOptions.AggressiveInlining)]
720 private unsafe static int PtrDiff(char* a, char* b)
721 {
722 return (int)((uint)((byte*)a - (byte*)b) >> 1);
723 }
724
725 [MethodImpl(MethodImplOptions.AggressiveInlining)]
726 private unsafe static int PtrDiff(byte* a, byte* b)
727 {
728 return (int)(a - b);
729 }
730}
static readonly bool IsLittleEndian
static bool TryFormat(bool value, Span< byte > destination, out int bytesWritten, StandardFormat format=default(StandardFormat))
static byte Min(byte val1, byte val2)
Definition Math.cs:912
static string Format(string resourceFormat, object p1)
Definition SR.cs:118
static string RequiredDigitNotFoundEndOfData
Definition SR.cs:122
static string ExpectedEndOfDigitNotFound
Definition SR.cs:50
Definition SR.cs:7
virtual OperationStatus EncodeUtf8(ReadOnlySpan< byte > utf8Source, Span< byte > utf8Destination, out int bytesConsumed, out int bytesWritten, bool isFinalBlock=true)
virtual string Encode(string value)
static bool IsFinite(double value)
static bool IsInRangeInclusive(uint value, uint lowerBound, uint upperBound)
static bool IsDigit(byte value)
static void WriteIndentation(Span< byte > buffer, int indent)
static void EscapeNextChars(char value, Span< char > destination, ref int written)
static unsafe int PtrDiff(byte *a, byte *b)
static void EscapeString(ReadOnlySpan< char > value, Span< char > destination, int indexOfFirstByteToEscape, JavaScriptEncoder encoder, out int written)
static bool NeedsEscapingNoBoundsCheck(char value)
static void ValidateProperty(ReadOnlySpan< char > propertyName)
static bool IsAsciiValue(byte value)
static void WriteDateTimeTrimmed(Span< byte > buffer, DateTime value, out int bytesWritten)
static void EscapeNextBytes(byte value, Span< byte > destination, ref int written)
static void ValidatePropertyAndBytes(ReadOnlySpan< byte > propertyName, ReadOnlySpan< byte > bytes)
static void ValidateBytes(ReadOnlySpan< byte > bytes)
static readonly StandardFormat s_dateTimeStandardFormat
static void TrimDateTimeOffset(Span< byte > buffer, out int bytesWritten)
static void ValidateNumber(ReadOnlySpan< byte > utf8FormattedNumber)
static bool NeedsEscaping(byte value)
static void ValidateSingle(float value)
static void ValidatePropertyAndValue(ReadOnlySpan< char > propertyName, ReadOnlySpan< byte > value)
static void WriteDateTimeOffsetTrimmed(Span< byte > buffer, DateTimeOffset value, out int bytesWritten)
static void ValidateValue(ReadOnlySpan< byte > value)
static unsafe int NeedsEscaping(ReadOnlySpan< char > value, JavaScriptEncoder encoder)
static void ValidatePropertyAndValue(ReadOnlySpan< char > propertyName, ReadOnlySpan< char > value)
static void EscapeString(ReadOnlySpan< char > value, Span< char > destination, JavaScriptEncoder encoder, ref int written)
static void ValidatePropertyAndValue(ReadOnlySpan< byte > propertyName, ReadOnlySpan< char > value)
static void EscapeString(ReadOnlySpan< byte > value, Span< byte > destination, JavaScriptEncoder encoder, ref int written)
static void ValidateProperty(ReadOnlySpan< byte > propertyName)
static bool IsAsciiValue(char value)
static int GetMaxEscapedLength(int textLength, int firstIndexToEscape)
static unsafe OperationStatus ToUtf8(ReadOnlySpan< byte > utf16Source, Span< byte > utf8Destination, out int bytesConsumed, out int bytesWritten)
static unsafe int PtrDiff(char *a, char *b)
static ReadOnlySpan< byte > AllowList
static void ValidateDouble(double value)
static void ValidatePropertyAndBytes(ReadOnlySpan< char > propertyName, ReadOnlySpan< byte > bytes)
static void ValidateValue(ReadOnlySpan< char > value)
static readonly StandardFormat s_hexStandardFormat
static void EscapeString(ReadOnlySpan< byte > value, Span< byte > destination, int indexOfFirstByteToEscape, JavaScriptEncoder encoder, out int written)
static int NeedsEscaping(ReadOnlySpan< byte > value, JavaScriptEncoder encoder)
static void ValidatePropertyAndValue(ReadOnlySpan< byte > propertyName, ReadOnlySpan< byte > value)
static void ThrowArgumentException(string message)
static void ThrowArgumentException_InvalidUTF8(ReadOnlySpan< byte > value)
static void ThrowArgumentException_PropertyNameTooLarge(int tokenLength)
static void ThrowArgumentException_ValueTooLarge(int tokenLength)
static string GetPrintableString(byte value)
static void ThrowArgumentException_InvalidUTF16(int charAsInt)
static void ThrowArgumentException_ValueNotSupported()