Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
XmlCanonicalWriter.cs
Go to the documentation of this file.
3using System.IO;
6using System.Text;
7
8namespace System.Xml;
9
10internal sealed class XmlCanonicalWriter
11{
12 private sealed class AttributeSorter : IComparer
13 {
14 private readonly XmlCanonicalWriter _writer;
15
20
21 public void Sort()
22 {
23 object[] array = new object[_writer._attributeCount];
24 for (int i = 0; i < array.Length; i++)
25 {
26 array[i] = i;
27 }
28 Array.Sort(array, this);
30 for (int j = 0; j < array.Length; j++)
31 {
33 }
35 }
36
37 public int Compare(object obj1, object obj2)
38 {
39 int num = (int)obj1;
40 int num2 = (int)obj2;
42 }
43 }
44
45 private struct Scope
46 {
48
49 public int xmlnsOffset;
50 }
51
52 private struct Element
53 {
54 public int prefixOffset;
55
56 public int prefixLength;
57
58 public int localNameOffset;
59
60 public int localNameLength;
61 }
62
63 private struct Attribute
64 {
65 public int prefixOffset;
66
67 public int prefixLength;
68
69 public int localNameOffset;
70
71 public int localNameLength;
72
73 public int nsOffset;
74
75 public int nsLength;
76
77 public int offset;
78
79 public int length;
80 }
81
82 private struct XmlnsAttribute
83 {
84 public int prefixOffset;
85
86 public int prefixLength;
87
88 public int nsOffset;
89
90 public int nsLength;
91
92 public bool referred;
93 }
94
96
98
99 private byte[] _elementBuffer;
100
102
103 private bool _inStartElement;
104
105 private int _depth;
106
107 private Scope[] _scopes;
108
110
112
113 private int _attributeCount;
114
116
118
120
121 private byte[] _xmlnsBuffer;
122
123 private int _xmlnsOffset;
124
125 private const int maxBytesPerChar = 3;
126
127 private int _xmlnsStartOffset;
128
129 private bool _includeComments;
130
131 private string[] _inclusivePrefixes;
132
133 private const string xmlnsNamespace = "http://www.w3.org/2000/xmlns/";
134
135 private static readonly bool[] s_isEscapedAttributeChar = new bool[64]
136 {
137 true, true, true, true, true, true, true, true, true, true,
138 true, true, true, true, true, true, true, true, true, true,
139 true, true, true, true, true, true, true, true, true, true,
140 true, true, false, false, true, false, false, false, true, false,
141 false, false, false, false, false, false, false, false, false, false,
142 false, false, false, false, false, false, false, false, false, false,
143 true, false, false, false
144 };
145
146 private static readonly bool[] s_isEscapedElementChar = new bool[64]
147 {
148 true, true, true, true, true, true, true, true, true, false,
149 false, true, true, true, true, true, true, true, true, true,
150 true, true, true, true, true, true, true, true, true, true,
151 true, true, false, false, false, false, false, false, true, false,
152 false, false, false, false, false, false, false, false, false, false,
153 false, false, false, false, false, false, false, false, false, false,
154 true, false, true, false
155 };
156
158 {
159 if (stream == null)
160 {
162 }
163 if (_writer == null)
164 {
166 }
167 _writer.SetOutput(stream, ownsStream: false, null);
168 if (_elementStream == null)
169 {
171 }
172 if (_elementWriter == null)
173 {
175 }
177 if (_xmlnsAttributes == null)
178 {
180 _xmlnsOffset = 0;
181 WriteXmlnsAttribute("xml", "http://www.w3.org/XML/1998/namespace");
182 WriteXmlnsAttribute("xmlns", "http://www.w3.org/2000/xmlns/");
183 WriteXmlnsAttribute(string.Empty, string.Empty);
185 for (int i = 0; i < 3; i++)
186 {
187 _xmlnsAttributes[i].referred = true;
188 }
189 }
190 else
191 {
194 }
195 _depth = 0;
196 _inStartElement = false;
198 _inclusivePrefixes = null;
199 if (inclusivePrefixes == null)
200 {
201 return;
202 }
203 _inclusivePrefixes = new string[inclusivePrefixes.Length];
204 for (int j = 0; j < inclusivePrefixes.Length; j++)
205 {
206 if (inclusivePrefixes[j] == null)
207 {
209 }
211 }
212 }
213
214 public void Flush()
215 {
217 _writer.Flush();
218 }
219
220 public void Close()
221 {
222 if (_writer != null)
223 {
224 _writer.Close();
225 }
226 if (_elementWriter != null)
227 {
229 }
230 if (_elementStream != null && _elementStream.Length > 512)
231 {
232 _elementStream = null;
233 }
234 _elementBuffer = null;
235 if (_scopes != null && _scopes.Length > 16)
236 {
237 _scopes = null;
238 }
239 if (_attributes != null && _attributes.Length > 16)
240 {
241 _attributes = null;
242 }
243 if (_xmlnsBuffer != null && _xmlnsBuffer.Length > 1024)
244 {
245 _xmlnsAttributes = null;
246 _xmlnsBuffer = null;
247 }
248 _inclusivePrefixes = null;
249 }
250
251 public void WriteDeclaration()
252 {
253 }
254
255 public void WriteComment(string value)
256 {
257 if (value == null)
258 {
260 }
263 {
265 }
266 }
267
268 [MemberNotNull("_scopes")]
269 private void StartElement()
270 {
271 if (_scopes == null)
272 {
273 _scopes = new Scope[4];
274 }
275 else if (_depth == _scopes.Length)
276 {
277 Scope[] array = new Scope[_depth * 2];
279 _scopes = array;
280 }
283 _depth++;
284 _inStartElement = true;
285 _attributeCount = 0;
287 }
288
295
296 public void WriteStartElement(string prefix, string localName)
297 {
298 if (prefix == null)
299 {
301 }
302 if (localName == null)
303 {
305 }
307 bool flag = _depth == 0;
308 StartElement();
312 _element.localNameLength = Encoding.UTF8.GetByteCount(localName);
314 if (!flag || _inclusivePrefixes == null)
315 {
316 return;
317 }
318 for (int i = 0; i < _scopes[0].xmlnsAttributeCount; i++)
319 {
321 {
324 }
325 }
326 }
327
328 public void WriteStartElement(byte[] prefixBuffer, int prefixOffset, int prefixLength, byte[] localNameBuffer, int localNameOffset, int localNameLength)
329 {
330 if (prefixBuffer == null)
331 {
333 }
334 if (prefixOffset < 0)
335 {
337 }
338 if (prefixOffset > prefixBuffer.Length)
339 {
341 }
342 if (prefixLength < 0)
343 {
345 }
346 if (prefixLength > prefixBuffer.Length - prefixOffset)
347 {
349 }
350 if (localNameBuffer == null)
351 {
353 }
354 if (localNameOffset < 0)
355 {
357 }
358 if (localNameOffset > localNameBuffer.Length)
359 {
361 }
362 if (localNameLength < 0)
363 {
365 }
366 if (localNameLength > localNameBuffer.Length - localNameOffset)
367 {
369 }
371 bool flag = _depth == 0;
372 StartElement();
374 _element.prefixLength = prefixLength;
375 _element.localNameOffset = _element.prefixOffset + prefixLength + ((prefixLength != 0) ? 1 : 0);
376 _element.localNameLength = localNameLength;
377 _elementWriter.WriteStartElement(prefixBuffer, prefixOffset, prefixLength, localNameBuffer, localNameOffset, localNameLength);
378 if (!flag || _inclusivePrefixes == null)
379 {
380 return;
381 }
382 for (int i = 0; i < _scopes[0].xmlnsAttributeCount; i++)
383 {
385 {
388 }
389 }
390 }
391
393 {
394 for (int i = 0; i < _inclusivePrefixes.Length; i++)
395 {
396 if (_inclusivePrefixes[i].Length == xmlnsAttribute.prefixLength && string.Equals(Encoding.UTF8.GetString(_xmlnsBuffer, xmlnsAttribute.prefixOffset, xmlnsAttribute.prefixLength), _inclusivePrefixes[i], StringComparison.Ordinal))
397 {
398 return true;
399 }
400 }
401 return false;
402 }
403
405 {
409 _inStartElement = false;
412 for (int i = _scopes[_depth - 1].xmlnsAttributeCount; i < _xmlnsAttributeCount; i++)
413 {
414 int num = i - 1;
415 bool flag = false;
416 while (num >= 0)
417 {
418 if (Equals(_xmlnsBuffer, _xmlnsAttributes[i].prefixOffset, _xmlnsAttributes[i].prefixLength, _xmlnsBuffer, _xmlnsAttributes[num].prefixOffset, _xmlnsAttributes[num].prefixLength))
419 {
420 if (!Equals(_xmlnsBuffer, _xmlnsAttributes[i].nsOffset, _xmlnsAttributes[i].nsLength, _xmlnsBuffer, _xmlnsAttributes[num].nsOffset, _xmlnsAttributes[num].nsLength))
421 {
422 break;
423 }
424 if (_xmlnsAttributes[num].referred)
425 {
426 flag = true;
427 break;
428 }
429 }
430 num--;
431 }
432 if (!flag)
433 {
435 }
436 }
437 if (_attributeCount > 0)
438 {
439 if (_attributeCount > 1)
440 {
442 }
443 for (int j = 0; j < _attributeCount; j++)
444 {
446 }
447 }
449 if (isEmpty)
450 {
452 EndElement();
453 }
454 _elementBuffer = null;
455 }
456
457 public void WriteEndElement(string prefix, string localName)
458 {
459 if (prefix == null)
460 {
462 }
463 if (localName == null)
464 {
466 }
468 _writer.WriteEndElement(prefix, localName);
469 EndElement();
470 }
471
472 [MemberNotNull("_xmlnsBuffer")]
473 private void EnsureXmlnsBuffer(int byteCount)
474 {
475 if (_xmlnsBuffer == null)
476 {
477 _xmlnsBuffer = new byte[Math.Max(byteCount, 128)];
478 }
479 else if (_xmlnsOffset + byteCount > _xmlnsBuffer.Length)
480 {
481 byte[] array = new byte[Math.Max(_xmlnsOffset + byteCount, _xmlnsBuffer.Length * 2)];
484 }
485 }
486
487 [MemberNotNull("_xmlnsAttributes")]
488 public void WriteXmlnsAttribute(string prefix, string ns)
489 {
490 if (prefix == null)
491 {
493 }
494 if (ns == null)
495 {
497 }
499 if (prefix.Length > int.MaxValue - ns.Length)
500 {
502 }
503 int num = prefix.Length + ns.Length;
504 if (num > 715827882)
505 {
507 }
508 EnsureXmlnsBuffer(num * 3);
512 _xmlnsOffset += xmlnsAttribute.prefixLength;
514 xmlnsAttribute.nsLength = Encoding.UTF8.GetBytes(ns, 0, ns.Length, _xmlnsBuffer, _xmlnsOffset);
515 _xmlnsOffset += xmlnsAttribute.nsLength;
518 }
519
520 [MemberNotNull("_xmlnsAttributes")]
521 public void WriteXmlnsAttribute(byte[] prefixBuffer, int prefixOffset, int prefixLength, byte[] nsBuffer, int nsOffset, int nsLength)
522 {
523 if (prefixBuffer == null)
524 {
526 }
527 if (prefixOffset < 0)
528 {
530 }
531 if (prefixOffset > prefixBuffer.Length)
532 {
534 }
535 if (prefixLength < 0)
536 {
538 }
539 if (prefixLength > prefixBuffer.Length - prefixOffset)
540 {
542 }
543 if (nsBuffer == null)
544 {
546 }
547 if (nsOffset < 0)
548 {
550 }
551 if (nsOffset > nsBuffer.Length)
552 {
554 }
555 if (nsLength < 0)
556 {
558 }
559 if (nsLength > nsBuffer.Length - nsOffset)
560 {
562 }
564 if (prefixLength > int.MaxValue - nsLength)
565 {
567 }
568 EnsureXmlnsBuffer(prefixLength + nsLength);
571 xmlnsAttribute.prefixLength = prefixLength;
572 Buffer.BlockCopy(prefixBuffer, prefixOffset, _xmlnsBuffer, _xmlnsOffset, prefixLength);
573 _xmlnsOffset += prefixLength;
575 xmlnsAttribute.nsLength = nsLength;
576 Buffer.BlockCopy(nsBuffer, nsOffset, _xmlnsBuffer, _xmlnsOffset, nsLength);
577 _xmlnsOffset += nsLength;
580 }
581
582 public void WriteStartAttribute(string prefix, string localName)
583 {
584 if (prefix == null)
585 {
587 }
588 if (localName == null)
589 {
591 }
598 _attribute.localNameLength = Encoding.UTF8.GetByteCount(localName);
602 }
603
604 public void WriteStartAttribute(byte[] prefixBuffer, int prefixOffset, int prefixLength, byte[] localNameBuffer, int localNameOffset, int localNameLength)
605 {
606 if (prefixBuffer == null)
607 {
609 }
610 if (prefixOffset < 0)
611 {
613 }
614 if (prefixOffset > prefixBuffer.Length)
615 {
617 }
618 if (prefixLength < 0)
619 {
621 }
622 if (prefixLength > prefixBuffer.Length - prefixOffset)
623 {
625 }
626 if (localNameBuffer == null)
627 {
629 }
630 if (localNameOffset < 0)
631 {
633 }
634 if (localNameOffset > localNameBuffer.Length)
635 {
637 }
638 if (localNameLength < 0)
639 {
641 }
642 if (localNameLength > localNameBuffer.Length - localNameOffset)
643 {
645 }
650 _attribute.prefixLength = prefixLength;
651 _attribute.localNameOffset = _attribute.prefixOffset + prefixLength + ((prefixLength != 0) ? 1 : 0);
652 _attribute.localNameLength = localNameLength;
655 _elementWriter.WriteStartAttribute(prefixBuffer, prefixOffset, prefixLength, localNameBuffer, localNameOffset, localNameLength);
656 }
657
665
666 public void WriteCharEntity(int ch)
667 {
669 if (ch <= 65535)
670 {
671 char[] chars = new char[1] { (char)ch };
672 WriteEscapedText(chars, 0, 1);
673 }
674 else
675 {
676 WriteText(ch);
677 }
678 }
679
680 public void WriteEscapedText(string value)
681 {
682 if (value == null)
683 {
685 }
687 if (_depth > 0)
688 {
689 if (_inStartElement)
690 {
692 }
693 else
694 {
696 }
697 }
698 }
699
735
736 public void WriteEscapedText(char[] chars, int offset, int count)
737 {
739 if (_depth > 0)
740 {
741 if (_inStartElement)
742 {
744 }
745 else
746 {
748 }
749 }
750 }
751
752 public void WriteText(int ch)
753 {
755 if (_inStartElement)
756 {
758 }
759 else
760 {
762 }
763 }
764
797
798 public void WriteText(string value)
799 {
800 if (value == null)
801 {
803 }
804 if (value.Length > 0)
805 {
806 if (_inStartElement)
807 {
809 }
810 else
811 {
813 }
814 }
815 }
816
849
850 private void ThrowIfClosed()
851 {
852 if (_writer == null)
853 {
854 ThrowClosed();
855 }
856 }
857
862
864 {
865 if (xmlnsAttribute.referred)
866 {
868 }
869 }
870
871 private void SortAttributes()
872 {
873 if (_attributeCount < 16)
874 {
875 for (int i = 0; i < _attributeCount - 1; i++)
876 {
877 int num = i;
878 for (int j = i + 1; j < _attributeCount; j++)
879 {
880 if (Compare(ref _attributes[j], ref _attributes[num]) < 0)
881 {
882 num = j;
883 }
884 }
885 if (num != i)
886 {
888 _attributes[i] = _attributes[num];
889 _attributes[num] = attribute;
890 }
891 }
892 }
893 else
894 {
895 new AttributeSorter(this).Sort();
896 }
897 }
898
900 {
901 if (_attributes == null)
902 {
903 _attributes = new Attribute[4];
904 }
905 else if (_attributeCount == _attributes.Length)
906 {
910 }
913 }
914
915 [MemberNotNull("_xmlnsAttributes")]
917 {
918 if (_xmlnsAttributes == null)
919 {
921 }
922 else if (_xmlnsAttributes.Length == _xmlnsAttributeCount)
923 {
927 }
929 {
931 }
932 if (_depth == 0)
933 {
935 return;
936 }
938 bool flag = true;
939 for (; i < _xmlnsAttributeCount; i++)
940 {
942 if (num <= 0)
943 {
944 if (num == 0)
945 {
947 flag = false;
948 }
949 break;
950 }
951 }
952 if (flag)
953 {
957 }
958 }
959
960 private void ResolvePrefix(int prefixOffset, int prefixLength, out int nsOffset, out int nsLength)
961 {
962 int xmlnsAttributeCount = _scopes[_depth - 1].xmlnsAttributeCount;
963 int num = _xmlnsAttributeCount - 1;
964 while (!Equals(_elementBuffer, prefixOffset, prefixLength, _xmlnsBuffer, _xmlnsAttributes[num].prefixOffset, _xmlnsAttributes[num].prefixLength))
965 {
966 num--;
967 }
968 nsOffset = _xmlnsAttributes[num].nsOffset;
969 nsLength = _xmlnsAttributes[num].nsLength;
970 if (num < xmlnsAttributeCount)
971 {
972 if (!_xmlnsAttributes[num].referred)
973 {
977 }
978 }
979 else
980 {
981 _xmlnsAttributes[num].referred = true;
982 }
983 }
984
986 {
987 if (attribute.prefixLength != 0)
988 {
989 ResolvePrefix(attribute.prefixOffset, attribute.prefixLength, out attribute.nsOffset, out attribute.nsLength);
990 }
991 }
992
993 private void ResolvePrefixes()
994 {
996 for (int i = 0; i < _attributeCount; i++)
997 {
999 }
1000 }
1001
1003 {
1004 return Compare(_xmlnsBuffer, xmlnsAttribute1.prefixOffset, xmlnsAttribute1.prefixLength, xmlnsAttribute2.prefixOffset, xmlnsAttribute2.prefixLength);
1005 }
1006
1008 {
1009 int num = Compare(_xmlnsBuffer, attribute1.nsOffset, attribute1.nsLength, attribute2.nsOffset, attribute2.nsLength);
1010 if (num == 0)
1011 {
1012 num = Compare(_elementBuffer, attribute1.localNameOffset, attribute1.localNameLength, attribute2.localNameOffset, attribute2.localNameLength);
1013 }
1014 return num;
1015 }
1016
1017 private int Compare(byte[] buffer, int offset1, int length1, int offset2, int length2)
1018 {
1019 if (offset1 == offset2)
1020 {
1021 return length1 - length2;
1022 }
1024 }
1025
1026 private int Compare(byte[] buffer1, int offset1, int length1, byte[] buffer2, int offset2, int length2)
1027 {
1028 int num = Math.Min(length1, length2);
1029 int num2 = 0;
1030 for (int i = 0; i < num; i++)
1031 {
1032 if (num2 != 0)
1033 {
1034 break;
1035 }
1036 num2 = buffer1[offset1 + i] - buffer2[offset2 + i];
1037 }
1038 if (num2 == 0)
1039 {
1040 num2 = length1 - length2;
1041 }
1042 return num2;
1043 }
1044
1045 private bool Equals(byte[] buffer1, int offset1, int length1, byte[] buffer2, int offset2, int length2)
1046 {
1047 if (length1 != length2)
1048 {
1049 return false;
1050 }
1051 for (int i = 0; i < length1; i++)
1052 {
1053 if (buffer1[offset1 + i] != buffer2[offset2 + i])
1054 {
1055 return false;
1056 }
1057 }
1058 return true;
1059 }
1060}
static void Sort(Array array)
Definition Array.cs:2329
static unsafe void Copy(Array sourceArray, Array destinationArray, int length)
Definition Array.cs:624
static void BlockCopy(Array src, int srcOffset, Array dst, int dstOffset, int count)
Definition Buffer.cs:102
virtual byte[] GetBuffer()
static byte Min(byte val1, byte val2)
Definition Math.cs:912
static byte Max(byte val1, byte val2)
Definition Math.cs:738
static string Format(string resourceFormat, object p1)
Definition SR.cs:118
static string ValueMustBeNonNegative
Definition SR.cs:296
static string CombinedPrefixNSLength
Definition SR.cs:702
static string SizeExceedsRemainingBufferSpace
Definition SR.cs:324
static string OffsetExceedsBufferSize
Definition SR.cs:322
static string InvalidInclusivePrefixListCollection
Definition SR.cs:704
Definition SR.cs:7
static Encoding UTF8
Definition Encoding.cs:526
static readonly bool[] s_isEscapedAttributeChar
bool Equals(byte[] buffer1, int offset1, int length1, byte[] buffer2, int offset2, int length2)
void SetOutput(Stream stream, bool includeComments, string[] inclusivePrefixes)
int Compare(byte[] buffer1, int offset1, int length1, byte[] buffer2, int offset2, int length2)
void EnsureXmlnsBuffer(int byteCount)
void AddXmlnsAttribute(ref XmlnsAttribute xmlnsAttribute)
void ResolvePrefix(int prefixOffset, int prefixLength, out int nsOffset, out int nsLength)
void WriteStartElement(byte[] prefixBuffer, int prefixOffset, int prefixLength, byte[] localNameBuffer, int localNameOffset, int localNameLength)
int Compare(ref Attribute attribute1, ref Attribute attribute2)
void WriteStartElement(string prefix, string localName)
void WriteStartAttribute(byte[] prefixBuffer, int prefixOffset, int prefixLength, byte[] localNameBuffer, int localNameOffset, int localNameLength)
void WriteText(byte[] chars, int offset, int count)
void WriteEscapedText(byte[] chars, int offset, int count)
void WriteEscapedText(char[] chars, int offset, int count)
void WriteXmlnsAttribute(byte[] prefixBuffer, int prefixOffset, int prefixLength, byte[] nsBuffer, int nsOffset, int nsLength)
void WriteXmlnsAttribute(string prefix, string ns)
void WriteEndElement(string prefix, string localName)
int Compare(byte[] buffer, int offset1, int length1, int offset2, int length2)
void WriteText(char[] chars, int offset, int count)
int Compare(ref XmlnsAttribute xmlnsAttribute1, ref XmlnsAttribute xmlnsAttribute2)
void WriteXmlnsAttribute(ref XmlnsAttribute xmlnsAttribute)
void AddAttribute(ref Attribute attribute)
void ResolvePrefix(ref Attribute attribute)
bool IsInclusivePrefix(ref XmlnsAttribute xmlnsAttribute)
static readonly bool[] s_isEscapedElementChar
void WriteStartAttribute(string prefix, string localName)
void WriteEndStartElement(bool isEmpty)
override void WriteEndStartElement(bool isEmpty)
override void WriteEscapedText(XmlDictionaryString s)
override void WriteComment(string text)
new void SetOutput(Stream stream, bool ownsStream, Encoding encoding)
override void WriteStartElement(string prefix, string localName)
override void WriteStartAttribute(string prefix, string localName)
override void WriteEndElement(string prefix, string localName)
override void WriteXmlnsAttribute(string prefix, string ns)