Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
EncodingStreamWrapper.cs
Go to the documentation of this file.
2using System.IO;
3using System.Text;
4
5namespace System.Xml;
6
7internal sealed class EncodingStreamWrapper : Stream
8{
9 private enum SupportedEncoding
10 {
11 UTF8,
12 UTF16LE,
13 UTF16BE,
14 None
15 }
16
18
19 private static readonly UnicodeEncoding s_safeUTF16 = new UnicodeEncoding(bigEndian: false, byteOrderMark: false, throwOnInvalidBytes: false);
20
21 private static readonly UnicodeEncoding s_safeBEUTF16 = new UnicodeEncoding(bigEndian: true, byteOrderMark: false, throwOnInvalidBytes: false);
22
24
25 private static readonly UnicodeEncoding s_validatingUTF16 = new UnicodeEncoding(bigEndian: false, byteOrderMark: false, throwOnInvalidBytes: true);
26
27 private static readonly UnicodeEncoding s_validatingBEUTF16 = new UnicodeEncoding(bigEndian: true, byteOrderMark: false, throwOnInvalidBytes: true);
28
29 private const int BufferLength = 128;
30
31 private static readonly byte[] s_encodingAttr = new byte[8] { 101, 110, 99, 111, 100, 105, 110, 103 };
32
33 private static readonly byte[] s_encodingUTF8 = new byte[5] { 117, 116, 102, 45, 56 };
34
35 private static readonly byte[] s_encodingUnicode = new byte[6] { 117, 116, 102, 45, 49, 54 };
36
37 private static readonly byte[] s_encodingUnicodeLE = new byte[8] { 117, 116, 102, 45, 49, 54, 108, 101 };
38
39 private static readonly byte[] s_encodingUnicodeBE = new byte[8] { 117, 116, 102, 45, 49, 54, 98, 101 };
40
42
44
45 private readonly Encoder _enc;
46
47 private readonly Decoder _dec;
48
49 private readonly bool _isReading;
50
51 private readonly Stream _stream;
52
53 private char[] _chars;
54
55 private byte[] _bytes;
56
57 private int _byteOffset;
58
59 private int _byteCount;
60
61 private readonly byte[] _byteBuffer = new byte[1];
62
63 public override bool CanRead
64 {
65 get
66 {
67 if (!_isReading)
68 {
69 return false;
70 }
71 return _stream.CanRead;
72 }
73 }
74
75 public override bool CanSeek => false;
76
77 public override bool CanWrite
78 {
79 get
80 {
81 if (_isReading)
82 {
83 return false;
84 }
85 return _stream.CanWrite;
86 }
87 }
88
89 public override long Position
90 {
91 get
92 {
93 throw new NotSupportedException();
94 }
95 set
96 {
97 throw new NotSupportedException();
98 }
99 }
100
101 public override bool CanTimeout => _stream.CanTimeout;
102
103 public override long Length => _stream.Length;
104
105 public override int ReadTimeout
106 {
107 get
108 {
109 return _stream.ReadTimeout;
110 }
111 set
112 {
114 }
115 }
116
117 public override int WriteTimeout
118 {
119 get
120 {
121 return _stream.WriteTimeout;
122 }
123 set
124 {
126 }
127 }
128
172
173 [MemberNotNull("_encoding")]
175 {
177 _encodingCode = e;
179 }
180
191
202
203 private static string GetEncodingName(SupportedEncoding enc)
204 {
205 return enc switch
206 {
207 SupportedEncoding.UTF8 => "utf-8",
208 SupportedEncoding.UTF16LE => "utf-16LE",
209 SupportedEncoding.UTF16BE => "utf-16BE",
211 };
212 }
213
215 {
216 if (encoding == null)
217 {
218 return SupportedEncoding.None;
219 }
220 if (encoding.WebName == s_validatingUTF8.WebName)
221 {
222 return SupportedEncoding.UTF8;
223 }
224 if (encoding.WebName == s_validatingUTF16.WebName)
225 {
226 return SupportedEncoding.UTF16LE;
227 }
228 if (encoding.WebName == s_validatingBEUTF16.WebName)
229 {
230 return SupportedEncoding.UTF16BE;
231 }
233 }
234
236 {
237 _isReading = false;
238 _encoding = encoding;
239 _stream = stream;
242 {
243 return;
244 }
246 _dec = s_validatingUTF8.GetDecoder();
248 if (emitBOM)
249 {
251 if (preamble.Length > 0)
252 {
254 }
255 }
256 }
257
258 [MemberNotNull("_bytes")]
260 {
261 int num = _stream.ReadByte();
262 int num2 = _stream.ReadByte();
263 int num3 = _stream.ReadByte();
264 int num4 = _stream.ReadByte();
265 if (num4 == -1)
266 {
268 }
269 int preserve;
270 SupportedEncoding result = ReadBOMEncoding((byte)num, (byte)num2, (byte)num3, (byte)num4, notOutOfBand, out preserve);
272 switch (preserve)
273 {
274 case 1:
275 _bytes[0] = (byte)num4;
276 break;
277 case 2:
278 _bytes[0] = (byte)num3;
279 _bytes[1] = (byte)num4;
280 break;
281 case 4:
282 _bytes[0] = (byte)num;
283 _bytes[1] = (byte)num2;
284 _bytes[2] = (byte)num3;
285 _bytes[3] = (byte)num4;
286 break;
287 }
289 return result;
290 }
291
292 private static SupportedEncoding ReadBOMEncoding(byte b1, byte b2, byte b3, byte b4, bool notOutOfBand, out int preserve)
293 {
295 preserve = 0;
296 if (b1 == 60 && b2 != 0)
297 {
298 result = SupportedEncoding.UTF8;
299 preserve = 4;
300 }
301 else if (b1 == byte.MaxValue && b2 == 254)
302 {
303 result = SupportedEncoding.UTF16LE;
304 preserve = 2;
305 }
306 else if (b1 == 254 && b2 == byte.MaxValue)
307 {
308 result = SupportedEncoding.UTF16BE;
309 preserve = 2;
310 }
311 else if (b1 == 0 && b2 == 60)
312 {
313 result = SupportedEncoding.UTF16BE;
314 if (notOutOfBand && (b3 != 0 || b4 != 63))
315 {
317 }
318 preserve = 4;
319 }
320 else if (b1 == 60 && b2 == 0)
321 {
322 result = SupportedEncoding.UTF16LE;
323 if (notOutOfBand && (b3 != 63 || b4 != 0))
324 {
326 }
327 preserve = 4;
328 }
329 else if (b1 == 239 && b2 == 187)
330 {
331 if (notOutOfBand && b3 != 191)
332 {
333 throw new XmlException(System.SR.XmlBadBOM);
334 }
335 preserve = 1;
336 }
337 else
338 {
339 preserve = 4;
340 }
341 return result;
342 }
343
344 private void FillBuffer(int count)
345 {
346 count -= _byteCount;
347 while (count > 0)
348 {
350 if (num != 0)
351 {
352 _byteCount += num;
353 count -= num;
354 continue;
355 }
356 break;
357 }
358 }
359
360 [MemberNotNull("_bytes")]
361 [MemberNotNull("_chars")]
362 private void EnsureBuffers()
363 {
365 if (_chars == null)
366 {
367 _chars = new char[128];
368 }
369 }
370
371 [MemberNotNull("_bytes")]
372 private void EnsureByteBuffer()
373 {
374 if (_bytes == null)
375 {
376 _bytes = new byte[512];
377 _byteOffset = 0;
378 _byteCount = 0;
379 }
380 }
381
383 {
384 byte b = 0;
385 int num = -1;
386 int num2 = offset + Math.Min(count, 128);
387 int num3 = 0;
388 int num4 = 0;
389 for (num3 = offset + 2; num3 < num2; num3++)
390 {
391 if (b != 0)
392 {
393 if (buffer[num3] == b)
394 {
395 b = 0;
396 }
397 }
398 else if (buffer[num3] == 39 || buffer[num3] == 34)
399 {
400 b = buffer[num3];
401 }
402 else if (buffer[num3] == 61)
403 {
404 if (num4 == 1)
405 {
406 num = num3;
407 break;
408 }
409 num4++;
410 }
411 else if (buffer[num3] == 63)
412 {
413 break;
414 }
415 }
416 if (num == -1)
417 {
418 if (e != 0 && expectedEnc == SupportedEncoding.None)
419 {
421 }
422 return;
423 }
424 if (num < 28)
425 {
427 }
428 num3 = num - 1;
429 while (IsWhitespace(buffer[num3]))
430 {
431 num3--;
432 }
433 if (!Compare(s_encodingAttr, buffer, num3 - s_encodingAttr.Length + 1))
434 {
435 if (e == SupportedEncoding.UTF8 || expectedEnc != SupportedEncoding.None)
436 {
437 return;
438 }
440 }
441 for (num3 = num + 1; num3 < num2 && IsWhitespace(buffer[num3]); num3++)
442 {
443 }
444 if (buffer[num3] != 39 && buffer[num3] != 34)
445 {
447 }
448 b = buffer[num3];
449 int num5 = num3++;
450 for (; buffer[num3] != b && num3 < num2; num3++)
451 {
452 }
453 if (buffer[num3] != b)
454 {
456 }
457 int num6 = num5 + 1;
458 int num7 = num3 - num6;
461 {
463 }
465 {
467 }
469 {
471 }
473 {
474 if (e == SupportedEncoding.UTF8)
475 {
477 }
478 }
479 else
480 {
482 }
483 if (e != supportedEncoding)
484 {
486 }
487 }
488
489 private static bool CompareCaseInsensitive(byte[] key, byte[] buffer, int offset)
490 {
491 for (int i = 0; i < key.Length; i++)
492 {
493 if (key[i] != buffer[offset + i] && key[i] != char.ToLowerInvariant((char)buffer[offset + i]))
494 {
495 return false;
496 }
497 }
498 return true;
499 }
500
501 private static bool Compare(byte[] key, byte[] buffer, int offset)
502 {
503 for (int i = 0; i < key.Length; i++)
504 {
505 if (key[i] != buffer[offset + i])
506 {
507 return false;
508 }
509 }
510 return true;
511 }
512
513 private static bool IsWhitespace(byte ch)
514 {
515 if (ch != 32 && ch != 10 && ch != 9)
516 {
517 return ch == 13;
518 }
519 return true;
520 }
521
522 internal static ArraySegment<byte> ProcessBuffer(byte[] buffer, int offset, int count, Encoding encoding)
523 {
524 if (count < 4)
525 {
527 }
528 try
529 {
531 int preserve;
534 {
536 }
537 offset += 4 - preserve;
538 count -= 4 - preserve;
540 {
541 if (buffer[offset + 1] != 63 || buffer[offset] != 60)
542 {
544 }
547 }
549 int byteCount = Math.Min(count, 256);
550 char[] chars = new char[safeEncoding.GetMaxCharCount(byteCount)];
551 int chars2 = safeEncoding.GetChars(buffer, offset, byteCount, chars, 0);
552 byte[] array = new byte[s_validatingUTF8.GetMaxByteCount(chars2)];
553 int bytes = s_validatingUTF8.GetBytes(chars, 0, chars2, array, 0);
554 if (array[1] == 63 && array[0] == 60)
555 {
557 }
558 else if (supportedEncoding == SupportedEncoding.None)
559 {
561 }
563 }
565 {
567 }
568 }
569
574
579
580 private static void ThrowEncodingMismatch(string declEnc, string docEnc)
581 {
583 }
584
585 protected override void Dispose(bool disposing)
586 {
587 if (_stream.CanWrite)
588 {
589 Flush();
590 }
592 base.Dispose(disposing);
593 }
594
595 public override void Flush()
596 {
597 _stream.Flush();
598 }
599
600 public override int ReadByte()
601 {
602 if (_byteCount == 0 && _encodingCode == SupportedEncoding.UTF8)
603 {
604 return _stream.ReadByte();
605 }
606 if (Read(_byteBuffer, 0, 1) == 0)
607 {
608 return -1;
609 }
610 return _byteBuffer[0];
611 }
612
613 public override int Read(byte[] buffer, int offset, int count)
614 {
615 try
616 {
617 if (_byteCount == 0)
618 {
620 {
621 return _stream.Read(buffer, offset, count);
622 }
623 _byteOffset = 0;
624 _byteCount = _stream.Read(_bytes, _byteCount, (_chars.Length - 1) * 2);
625 if (_byteCount == 0)
626 {
627 return 0;
628 }
631 _byteCount = Encoding.UTF8.GetBytes(_chars, 0, chars, _bytes, 0);
632 }
633 if (_byteCount < count)
634 {
636 }
639 _byteCount -= count;
640 return count;
641 }
643 {
645 }
646 }
647
648 private void CleanupCharBreak()
649 {
650 int num = _byteOffset + _byteCount;
651 if (_byteCount % 2 != 0)
652 {
653 int num2 = _stream.ReadByte();
654 if (num2 < 0)
655 {
657 }
658 _bytes[num++] = (byte)num2;
659 _byteCount++;
660 }
661 int num3 = ((_encodingCode != SupportedEncoding.UTF16LE) ? (_bytes[num - 1] + (_bytes[num - 2] << 8)) : (_bytes[num - 2] + (_bytes[num - 1] << 8)));
662 if ((num3 & 0xDC00) != 56320 && num3 >= 55296 && num3 <= 56319)
663 {
664 int num4 = _stream.ReadByte();
665 int num5 = _stream.ReadByte();
666 if (num5 < 0)
667 {
669 }
670 _bytes[num++] = (byte)num4;
671 _bytes[num++] = (byte)num5;
672 _byteCount += 2;
673 }
674 }
675
676 public override long Seek(long offset, SeekOrigin origin)
677 {
678 throw new NotSupportedException();
679 }
680
681 public override void WriteByte(byte b)
682 {
684 {
686 return;
687 }
688 _byteBuffer[0] = b;
689 Write(_byteBuffer, 0, 1);
690 }
691
692 public override void Write(byte[] buffer, int offset, int count)
693 {
695 {
697 return;
698 }
699 while (count > 0)
700 {
701 int num = ((_chars.Length < count) ? _chars.Length : count);
702 int chars = _dec.GetChars(buffer, offset, num, _chars, 0, flush: false);
703 _byteCount = _enc.GetBytes(_chars, 0, chars, _bytes, 0, flush: false);
705 offset += num;
706 count -= num;
707 }
708 }
709
710 public override void SetLength(long value)
711 {
712 throw new NotSupportedException();
713 }
714}
static void BlockCopy(Array src, int srcOffset, Array dst, int dstOffset, int count)
Definition Buffer.cs:102
virtual int ReadByte()
Definition Stream.cs:994
virtual bool CanTimeout
Definition Stream.cs:498
virtual int ReadTimeout
Definition Stream.cs:505
int Read(byte[] buffer, int offset, int count)
void Dispose()
Definition Stream.cs:639
void Write(byte[] buffer, int offset, int count)
virtual void WriteByte(byte value)
Definition Stream.cs:1020
virtual int WriteTimeout
Definition Stream.cs:517
static byte Min(byte val1, byte val2)
Definition Math.cs:912
static string XmlDeclarationRequired
Definition SR.cs:362
static string XmlMalformedDecl
Definition SR.cs:458
static string XmlInvalidBytes
Definition SR.cs:416
static string UnexpectedEndOfFile
Definition SR.cs:292
static string Format(string resourceFormat, object p1)
Definition SR.cs:118
static string XmlEncodingMismatch
Definition SR.cs:380
static string XmlEncodingNotSupported
Definition SR.cs:382
static string XmlDeclMissing
Definition SR.cs:366
static string XmlBadBOM
Definition SR.cs:352
static string XmlExpectedEncoding
Definition SR.cs:388
Definition SR.cs:7
int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex, bool flush)
virtual ReadOnlySpan< byte > Preamble
Definition Encoding.cs:347
static Encoding UTF8
Definition Encoding.cs:526
virtual string WebName
Definition Encoding.cs:386
virtual Encoder GetEncoder()
Definition Encoding.cs:1009
virtual char[] GetChars(byte[] bytes)
Definition Encoding.cs:921
static Encoding GetSafeEncoding(SupportedEncoding e)
static void CheckUTF8DeclarationEncoding(byte[] buffer, int offset, int count, SupportedEncoding e, SupportedEncoding expectedEnc)
static readonly UnicodeEncoding s_safeUTF16
static readonly byte[] s_encodingUnicodeLE
static ArraySegment< byte > ProcessBuffer(byte[] buffer, int offset, int count, Encoding encoding)
static void ThrowExpectedEncodingMismatch(SupportedEncoding expEnc, SupportedEncoding actualEnc)
static bool CompareCaseInsensitive(byte[] key, byte[] buffer, int offset)
override long Seek(long offset, SeekOrigin origin)
static string GetEncodingName(SupportedEncoding enc)
static void ThrowEncodingMismatch(string declEnc, SupportedEncoding enc)
static readonly byte[] s_encodingUnicodeBE
static readonly UnicodeEncoding s_validatingUTF16
SupportedEncoding ReadBOMEncoding(bool notOutOfBand)
static Encoding GetEncoding(SupportedEncoding e)
static readonly UnicodeEncoding s_safeBEUTF16
static bool Compare(byte[] key, byte[] buffer, int offset)
override void Write(byte[] buffer, int offset, int count)
void SetReadDocumentEncoding(SupportedEncoding e)
static readonly UTF8Encoding s_validatingUTF8
static void ThrowEncodingMismatch(string declEnc, string docEnc)
static SupportedEncoding GetSupportedEncoding(Encoding encoding)
static SupportedEncoding ReadBOMEncoding(byte b1, byte b2, byte b3, byte b4, bool notOutOfBand, out int preserve)
override int Read(byte[] buffer, int offset, int count)
EncodingStreamWrapper(Stream stream, Encoding encoding)
override void Dispose(bool disposing)
static readonly UTF8Encoding s_safeUTF8
static readonly UnicodeEncoding s_validatingBEUTF16
EncodingStreamWrapper(Stream stream, Encoding encoding, bool emitBOM)