Terraria v1.4.4.9
Terraria source code documentation
All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties Events Macros
XmlTextWriter.cs
Go to the documentation of this file.
4using System.IO;
5using System.Text;
6
7namespace System.Xml;
8
11{
19
20 private struct TagInfo
21 {
22 internal string name;
23
24 internal string prefix;
25
26 internal string defaultNs;
27
29
31
32 internal string xmlLang;
33
34 internal int prevNsTop;
35
36 internal int prefixCount;
37
38 internal bool mixed;
39
40 internal void Init(int nsTop)
41 {
42 name = null;
43 defaultNs = string.Empty;
44 defaultNsState = NamespaceState.Uninitialized;
45 xmlSpace = XmlSpace.None;
46 xmlLang = null;
48 prefixCount = 0;
49 mixed = false;
50 }
51 }
52
53 private struct Namespace
54 {
55 internal string prefix;
56
57 internal string ns;
58
59 internal bool declared;
60
61 internal int prevNsIndex;
62
63 internal void Set(string prefix, string ns, bool declared)
64 {
66 this.ns = ns;
68 prevNsIndex = -1;
69 }
70 }
71
72 private enum SpecialAttr
73 {
74 None,
76 XmlLang,
77 XmlNs
78 }
79
80 private enum State
81 {
82 Start,
83 Prolog,
84 PostDTD,
85 Element,
87 Content,
89 Epilog,
90 Error,
91 Closed
92 }
93
94 private enum Token
95 {
96 PI,
97 Doctype,
98 Comment,
99 CData,
105 Content,
106 Base64,
107 RawData,
109 Empty
110 }
111
112 private readonly TextWriter _textWriter;
113
114 private readonly XmlTextEncoder _xmlEncoder;
115
116 private readonly Encoding _encoding;
117
119
120 private bool _indented;
121
122 private int _indentation;
123
124 private char[] _indentChars;
125
126 private static readonly char[] s_defaultIndentChars = CreateDefaultIndentChars();
127
128 private TagInfo[] _stack;
129
130 private int _top;
131
133
135
137
139
140 private char _quoteChar;
141
142 private char _curQuoteChar;
143
144 private bool _namespaces;
145
147
148 private string _prefixForXmlNs;
149
150 private bool _flush;
151
153
154 private int _nsTop;
155
157
158 private bool _useNsHashtable;
159
160 private static readonly string[] s_stateName = new string[10] { "Start", "Prolog", "PostDTD", "Element", "Attribute", "Content", "AttrOnly", "Epilog", "Error", "Closed" };
161
162 private static readonly string[] s_tokenName = new string[14]
163 {
164 "PI", "Doctype", "Comment", "CData", "StartElement", "EndElement", "LongEndElement", "StartAttribute", "EndAttribute", "Content",
165 "Base64", "RawData", "Whitespace", "Empty"
166 };
167
168 private static readonly State[] s_stateTableDefault = new State[104]
169 {
170 State.Prolog,
171 State.Prolog,
172 State.PostDTD,
173 State.Content,
174 State.Content,
175 State.Content,
176 State.Error,
177 State.Epilog,
178 State.PostDTD,
179 State.PostDTD,
180 State.Error,
181 State.Error,
182 State.Error,
183 State.Error,
184 State.Error,
185 State.Error,
186 State.Prolog,
187 State.Prolog,
188 State.PostDTD,
189 State.Content,
190 State.Content,
191 State.Content,
192 State.Error,
193 State.Epilog,
194 State.Content,
195 State.Content,
196 State.Error,
197 State.Content,
198 State.Content,
199 State.Content,
200 State.Error,
201 State.Epilog,
202 State.Element,
203 State.Element,
204 State.Element,
205 State.Element,
206 State.Element,
207 State.Element,
208 State.Error,
209 State.Element,
210 State.Error,
211 State.Error,
212 State.Error,
213 State.Content,
214 State.Content,
215 State.Content,
216 State.Error,
217 State.Error,
218 State.Error,
219 State.Error,
220 State.Error,
221 State.Content,
222 State.Content,
223 State.Content,
224 State.Error,
225 State.Error,
226 State.AttrOnly,
227 State.Error,
228 State.Error,
229 State.Attribute,
230 State.Attribute,
231 State.Error,
232 State.Error,
233 State.Error,
234 State.Error,
235 State.Error,
236 State.Error,
237 State.Error,
238 State.Element,
239 State.Error,
240 State.Epilog,
241 State.Error,
242 State.Content,
243 State.Content,
244 State.Error,
245 State.Content,
246 State.Attribute,
247 State.Content,
248 State.Attribute,
249 State.Epilog,
250 State.Content,
251 State.Content,
252 State.Error,
253 State.Content,
254 State.Attribute,
255 State.Content,
256 State.Attribute,
257 State.Epilog,
258 State.Prolog,
259 State.Prolog,
260 State.PostDTD,
261 State.Content,
262 State.Attribute,
263 State.Content,
264 State.Attribute,
265 State.Epilog,
266 State.Prolog,
267 State.Prolog,
268 State.PostDTD,
269 State.Content,
270 State.Attribute,
271 State.Content,
272 State.Attribute,
274 };
275
276 private static readonly State[] s_stateTableDocument = new State[104]
277 {
278 State.Error,
279 State.Prolog,
280 State.PostDTD,
281 State.Content,
282 State.Content,
283 State.Content,
284 State.Error,
285 State.Epilog,
286 State.Error,
287 State.PostDTD,
288 State.Error,
289 State.Error,
290 State.Error,
291 State.Error,
292 State.Error,
293 State.Error,
294 State.Error,
295 State.Prolog,
296 State.PostDTD,
297 State.Content,
298 State.Content,
299 State.Content,
300 State.Error,
301 State.Epilog,
302 State.Error,
303 State.Error,
304 State.Error,
305 State.Content,
306 State.Content,
307 State.Content,
308 State.Error,
309 State.Error,
310 State.Error,
311 State.Element,
312 State.Element,
313 State.Element,
314 State.Element,
315 State.Element,
316 State.Error,
317 State.Error,
318 State.Error,
319 State.Error,
320 State.Error,
321 State.Content,
322 State.Content,
323 State.Content,
324 State.Error,
325 State.Error,
326 State.Error,
327 State.Error,
328 State.Error,
329 State.Content,
330 State.Content,
331 State.Content,
332 State.Error,
333 State.Error,
334 State.Error,
335 State.Error,
336 State.Error,
337 State.Attribute,
338 State.Attribute,
339 State.Error,
340 State.Error,
341 State.Error,
342 State.Error,
343 State.Error,
344 State.Error,
345 State.Error,
346 State.Element,
347 State.Error,
348 State.Error,
349 State.Error,
350 State.Error,
351 State.Error,
352 State.Error,
353 State.Content,
354 State.Attribute,
355 State.Content,
356 State.Error,
357 State.Error,
358 State.Error,
359 State.Error,
360 State.Error,
361 State.Content,
362 State.Attribute,
363 State.Content,
364 State.Error,
365 State.Error,
366 State.Error,
367 State.Prolog,
368 State.PostDTD,
369 State.Content,
370 State.Attribute,
371 State.Content,
372 State.Error,
373 State.Epilog,
374 State.Error,
375 State.Prolog,
376 State.PostDTD,
377 State.Content,
378 State.Attribute,
379 State.Content,
380 State.Error,
382 };
383
384 private static readonly char[] s_selfClosingTagOpen = new char[2] { '<', '/' };
385
386 private static readonly char[] s_closeTagEnd = new char[3] { ' ', '/', '>' };
387
389 {
390 get
391 {
393 {
394 return streamWriter.BaseStream;
395 }
396 return null;
397 }
398 }
399
400 public bool Namespaces
401 {
402 get
403 {
404 return _namespaces;
405 }
406 set
407 {
408 if (_currentState != 0)
409 {
411 }
413 }
414 }
415
417 {
418 get
419 {
420 return _formatting;
421 }
422 set
423 {
425 _indented = value == Formatting.Indented;
426 }
427 }
428
429 public int Indentation
430 {
431 get
432 {
433 return _indentation;
434 }
435 set
436 {
437 if (value < 0)
438 {
440 }
442 }
443 }
444
445 public char IndentChar
446 {
447 get
448 {
449 return _indentChars[0];
450 }
451 set
452 {
453 if (value == ' ')
454 {
456 return;
457 }
459 {
460 _indentChars = new char[64];
461 }
462 for (int i = 0; i < 64; i++)
463 {
464 _indentChars[i] = value;
465 }
466 }
467 }
468
469 public char QuoteChar
470 {
471 get
472 {
473 return _quoteChar;
474 }
475 set
476 {
477 if (value != '"' && value != '\'')
478 {
480 }
483 }
484 }
485
486 public override WriteState WriteState
487 {
488 get
489 {
490 switch (_currentState)
491 {
492 case State.Start:
493 return WriteState.Start;
494 case State.Prolog:
495 case State.PostDTD:
496 return WriteState.Prolog;
497 case State.Element:
498 return WriteState.Element;
499 case State.Attribute:
500 case State.AttrOnly:
501 return WriteState.Attribute;
502 case State.Content:
503 case State.Epilog:
504 return WriteState.Content;
505 case State.Error:
506 return WriteState.Error;
507 case State.Closed:
508 return WriteState.Closed;
509 default:
510 return WriteState.Error;
511 }
512 }
513 }
514
515 public override XmlSpace XmlSpace
516 {
517 get
518 {
519 for (int num = _top; num > 0; num--)
520 {
521 XmlSpace xmlSpace = _stack[num].xmlSpace;
522 if (xmlSpace != 0)
523 {
524 return xmlSpace;
525 }
526 }
527 return XmlSpace.None;
528 }
529 }
530
531 public override string? XmlLang
532 {
533 get
534 {
535 for (int num = _top; num > 0; num--)
536 {
537 string xmlLang = _stack[num].xmlLang;
538 if (xmlLang != null)
539 {
540 return xmlLang;
541 }
542 }
543 return null;
544 }
545 }
546
547 private static char[] CreateDefaultIndentChars()
548 {
549 char[] array = new char[64];
550 Array.Fill(array, ' ');
551 return array;
552 }
553
554 private XmlTextWriter()
555 {
556 _namespaces = true;
557 _formatting = Formatting.None;
558 _indentation = 2;
560 _nsStack = new Namespace[8];
561 _nsTop = -1;
562 _stack = new TagInfo[10];
563 _top = 0;
564 _stack[_top].Init(-1);
565 _quoteChar = '"';
567 _currentState = State.Start;
568 _lastToken = Token.Empty;
569 }
570
571 public XmlTextWriter(Stream w, Encoding? encoding)
572 : this()
573 {
574 _encoding = encoding;
575 if (encoding != null)
576 {
577 _textWriter = new StreamWriter(w, encoding);
578 }
579 else
580 {
582 }
583 _xmlEncoder = new XmlTextEncoder(_textWriter);
585 }
586
587 public XmlTextWriter(string filename, Encoding? encoding)
589 {
590 }
591
592 public XmlTextWriter(TextWriter w)
593 : this()
594 {
595 _textWriter = w;
596 _encoding = w.Encoding;
597 _xmlEncoder = new XmlTextEncoder(w);
599 }
600
601 public override void WriteStartDocument()
602 {
603 StartDocument(-1);
604 }
605
606 public override void WriteStartDocument(bool standalone)
607 {
608 StartDocument(standalone ? 1 : 0);
609 }
610
611 public override void WriteEndDocument()
612 {
613 try
614 {
616 if (_currentState != State.Epilog)
617 {
618 if (_currentState == State.Closed)
619 {
621 }
623 }
625 _currentState = State.Start;
626 _lastToken = Token.Empty;
627 }
628 catch
629 {
630 _currentState = State.Error;
631 throw;
632 }
633 }
634
635 public override void WriteDocType(string name, string? pubid, string? sysid, string? subset)
636 {
637 try
638 {
639 ValidateName(name, isNCName: false);
640 AutoComplete(Token.Doctype);
641 _textWriter.Write("<!DOCTYPE ");
642 _textWriter.Write(name);
643 if (pubid != null)
644 {
645 _textWriter.Write(" PUBLIC " + _quoteChar);
650 }
651 else if (sysid != null)
652 {
653 _textWriter.Write(" SYSTEM " + _quoteChar);
656 }
657 if (subset != null)
658 {
659 _textWriter.Write("[");
661 _textWriter.Write("]");
662 }
663 _textWriter.Write('>');
664 }
665 catch
666 {
667 _currentState = State.Error;
668 throw;
669 }
670 }
671
672 public override void WriteStartElement(string? prefix, string localName, string? ns)
673 {
674 try
675 {
676 AutoComplete(Token.StartElement);
677 PushStack();
678 _textWriter.Write('<');
679 if (_namespaces)
680 {
682 if (_stack[_top - 1].defaultNsState != 0)
683 {
684 _stack[_top].defaultNsState = NamespaceState.NotDeclaredButInScope;
685 }
687 if (ns == null)
688 {
689 if (prefix != null && prefix.Length != 0 && LookupNamespace(prefix) == -1)
690 {
692 }
693 }
694 else if (prefix == null)
695 {
696 string text = FindPrefix(ns);
697 if (text != null)
698 {
699 prefix = text;
700 }
701 else
702 {
703 PushNamespace(null, ns, declared: false);
704 }
705 }
706 else if (prefix.Length == 0)
707 {
708 PushNamespace(null, ns, declared: false);
709 }
710 else
711 {
712 if (ns.Length == 0)
713 {
714 prefix = null;
715 }
717 PushNamespace(prefix, ns, declared: false);
718 }
719 _stack[_top].prefix = null;
720 if (prefix != null && prefix.Length != 0)
721 {
724 _textWriter.Write(':');
725 }
726 }
727 else if ((ns != null && ns.Length != 0) || (prefix != null && prefix.Length != 0))
728 {
730 }
731 _stack[_top].name = localName;
732 _textWriter.Write(localName);
733 }
734 catch
735 {
736 _currentState = State.Error;
737 throw;
738 }
739 }
740
741 public override void WriteEndElement()
742 {
744 }
745
746 public override void WriteFullEndElement()
747 {
749 }
750
751 public override void WriteStartAttribute(string? prefix, string localName, string? ns)
752 {
753 try
754 {
755 AutoComplete(Token.StartAttribute);
756 _specialAttr = SpecialAttr.None;
757 if (_namespaces)
758 {
759 if (prefix != null && prefix.Length == 0)
760 {
761 prefix = null;
762 }
763 if (ns == "http://www.w3.org/2000/xmlns/" && prefix == null && localName != "xmlns")
764 {
765 prefix = "xmlns";
766 }
767 if (prefix == "xml")
768 {
769 if (localName == "lang")
770 {
771 _specialAttr = SpecialAttr.XmlLang;
772 }
773 else if (localName == "space")
774 {
775 _specialAttr = SpecialAttr.XmlSpace;
776 }
777 }
778 else if (prefix == "xmlns")
779 {
780 if ("http://www.w3.org/2000/xmlns/" != ns && ns != null)
781 {
783 }
784 if (localName == null || localName.Length == 0)
785 {
786 localName = prefix;
787 prefix = null;
788 _prefixForXmlNs = null;
789 }
790 else
791 {
792 _prefixForXmlNs = localName;
793 }
794 _specialAttr = SpecialAttr.XmlNs;
795 }
796 else if (prefix == null && localName == "xmlns")
797 {
798 if ("http://www.w3.org/2000/xmlns/" != ns && ns != null)
799 {
801 }
802 _specialAttr = SpecialAttr.XmlNs;
803 _prefixForXmlNs = null;
804 }
805 else if (ns == null)
806 {
807 if (prefix != null && LookupNamespace(prefix) == -1)
808 {
810 }
811 }
812 else if (ns.Length == 0)
813 {
814 prefix = string.Empty;
815 }
816 else
817 {
819 if (prefix != null && LookupNamespaceInCurrentScope(prefix) != -1)
820 {
821 prefix = null;
822 }
823 string text = FindPrefix(ns);
824 if (text != null && (prefix == null || prefix == text))
825 {
826 prefix = text;
827 }
828 else
829 {
830 if (prefix == null)
831 {
832 prefix = GeneratePrefix();
833 }
834 PushNamespace(prefix, ns, declared: false);
835 }
836 }
837 if (prefix != null && prefix.Length != 0)
838 {
840 _textWriter.Write(':');
841 }
842 }
843 else
844 {
845 if ((ns != null && ns.Length != 0) || (prefix != null && prefix.Length != 0))
846 {
848 }
849 if (localName == "xml:lang")
850 {
851 _specialAttr = SpecialAttr.XmlLang;
852 }
853 else if (localName == "xml:space")
854 {
855 _specialAttr = SpecialAttr.XmlSpace;
856 }
857 }
858 _xmlEncoder.StartAttribute(_specialAttr != SpecialAttr.None);
859 _textWriter.Write(localName);
860 _textWriter.Write('=');
862 {
865 }
867 }
868 catch
869 {
870 _currentState = State.Error;
871 throw;
872 }
873 }
874
875 public override void WriteEndAttribute()
876 {
877 try
878 {
879 AutoComplete(Token.EndAttribute);
880 }
881 catch
882 {
883 _currentState = State.Error;
884 throw;
885 }
886 }
887
888 public override void WriteCData(string? text)
889 {
890 try
891 {
892 AutoComplete(Token.CData);
893 if (text != null && text.Contains("]]>"))
894 {
896 }
897 _textWriter.Write("<![CDATA[");
898 if (text != null)
899 {
901 }
902 _textWriter.Write("]]>");
903 }
904 catch
905 {
906 _currentState = State.Error;
907 throw;
908 }
909 }
910
911 public override void WriteComment(string? text)
912 {
913 try
914 {
915 if (text != null && (text.Contains("--") || (text.Length != 0 && text[text.Length - 1] == '-')))
916 {
918 }
919 AutoComplete(Token.Comment);
920 _textWriter.Write("<!--");
921 if (text != null)
922 {
924 }
925 _textWriter.Write("-->");
926 }
927 catch
928 {
929 _currentState = State.Error;
930 throw;
931 }
932 }
933
934 public override void WriteProcessingInstruction(string name, string? text)
935 {
936 try
937 {
938 if (text != null && text.Contains("?>"))
939 {
941 }
942 if (string.Equals(name, "xml", StringComparison.OrdinalIgnoreCase) && _stateTable == s_stateTableDocument)
943 {
945 }
946 AutoComplete(Token.PI);
948 }
949 catch
950 {
951 _currentState = State.Error;
952 throw;
953 }
954 }
955
956 public override void WriteEntityRef(string name)
957 {
958 try
959 {
960 ValidateName(name, isNCName: false);
961 AutoComplete(Token.Content);
963 }
964 catch
965 {
966 _currentState = State.Error;
967 throw;
968 }
969 }
970
971 public override void WriteCharEntity(char ch)
972 {
973 try
974 {
975 AutoComplete(Token.Content);
977 }
978 catch
979 {
980 _currentState = State.Error;
981 throw;
982 }
983 }
984
985 public override void WriteWhitespace(string? ws)
986 {
987 try
988 {
989 if (ws == null)
990 {
991 ws = string.Empty;
992 }
993 if (!XmlCharType.IsOnlyWhitespace(ws))
994 {
996 }
997 AutoComplete(Token.Whitespace);
999 }
1000 catch
1001 {
1002 _currentState = State.Error;
1003 throw;
1004 }
1005 }
1006
1007 public override void WriteString(string? text)
1008 {
1009 try
1010 {
1011 if (text != null && text.Length != 0)
1012 {
1013 AutoComplete(Token.Content);
1015 }
1016 }
1017 catch
1018 {
1019 _currentState = State.Error;
1020 throw;
1021 }
1022 }
1023
1024 public override void WriteSurrogateCharEntity(char lowChar, char highChar)
1025 {
1026 try
1027 {
1028 AutoComplete(Token.Content);
1030 }
1031 catch
1032 {
1033 _currentState = State.Error;
1034 throw;
1035 }
1036 }
1037
1038 public override void WriteChars(char[] buffer, int index, int count)
1039 {
1040 try
1041 {
1042 AutoComplete(Token.Content);
1044 }
1045 catch
1046 {
1047 _currentState = State.Error;
1048 throw;
1049 }
1050 }
1051
1052 public override void WriteRaw(char[] buffer, int index, int count)
1053 {
1054 try
1055 {
1056 AutoComplete(Token.RawData);
1058 }
1059 catch
1060 {
1061 _currentState = State.Error;
1062 throw;
1063 }
1064 }
1065
1066 public override void WriteRaw(string data)
1067 {
1068 try
1069 {
1070 AutoComplete(Token.RawData);
1072 }
1073 catch
1074 {
1075 _currentState = State.Error;
1076 throw;
1077 }
1078 }
1079
1080 public override void WriteBase64(byte[] buffer, int index, int count)
1081 {
1082 try
1083 {
1084 if (!_flush)
1085 {
1086 AutoComplete(Token.Base64);
1087 }
1088 _flush = true;
1089 if (_base64Encoder == null)
1090 {
1091 _base64Encoder = new XmlTextWriterBase64Encoder(_xmlEncoder);
1092 }
1094 }
1095 catch
1096 {
1097 _currentState = State.Error;
1098 throw;
1099 }
1100 }
1101
1102 public override void WriteBinHex(byte[] buffer, int index, int count)
1103 {
1104 try
1105 {
1106 AutoComplete(Token.Content);
1107 BinHexEncoder.Encode(buffer, index, count, this);
1108 }
1109 catch
1110 {
1111 _currentState = State.Error;
1112 throw;
1113 }
1114 }
1115
1116 public override void Close()
1117 {
1118 try
1119 {
1121 }
1122 catch
1123 {
1124 }
1125 finally
1126 {
1127 _currentState = State.Closed;
1129 }
1130 }
1131
1132 public override void Flush()
1133 {
1135 }
1136
1137 public override void WriteName(string name)
1138 {
1139 try
1140 {
1141 AutoComplete(Token.Content);
1143 }
1144 catch
1145 {
1146 _currentState = State.Error;
1147 throw;
1148 }
1149 }
1150
1151 public override void WriteQualifiedName(string localName, string? ns)
1152 {
1153 try
1154 {
1155 AutoComplete(Token.Content);
1156 if (_namespaces)
1157 {
1158 if (ns != null && ns.Length != 0 && ns != _stack[_top].defaultNs)
1159 {
1160 string text = FindPrefix(ns);
1161 if (text == null)
1162 {
1163 if (_currentState != State.Attribute)
1164 {
1166 }
1167 text = GeneratePrefix();
1168 PushNamespace(text, ns, declared: false);
1169 }
1170 if (text.Length != 0)
1171 {
1173 _textWriter.Write(':');
1174 }
1175 }
1176 }
1177 else if (ns != null && ns.Length != 0)
1178 {
1180 }
1181 InternalWriteName(localName, isNCName: true);
1182 }
1183 catch
1184 {
1185 _currentState = State.Error;
1186 throw;
1187 }
1188 }
1189
1190 public override string? LookupPrefix(string ns)
1191 {
1192 if (ns == null || ns.Length == 0)
1193 {
1195 }
1196 string text = FindPrefix(ns);
1197 if (text == null && ns == _stack[_top].defaultNs)
1198 {
1199 text = string.Empty;
1200 }
1201 return text;
1202 }
1203
1204 public override void WriteNmToken(string name)
1205 {
1206 try
1207 {
1208 AutoComplete(Token.Content);
1209 if (name == null || name.Length == 0)
1210 {
1212 }
1213 if (!ValidateNames.IsNmtokenNoNamespaces(name))
1214 {
1216 }
1217 _textWriter.Write(name);
1218 }
1219 catch
1220 {
1221 _currentState = State.Error;
1222 throw;
1223 }
1224 }
1225
1226 private void StartDocument(int standalone)
1227 {
1228 try
1229 {
1230 if (_currentState != 0)
1231 {
1233 }
1235 _currentState = State.Prolog;
1239 handler.AppendLiteral("version=");
1240 handler.AppendFormatted(_quoteChar);
1241 handler.AppendLiteral("1.0");
1242 handler.AppendFormatted(_quoteChar);
1243 stringBuilder2.Append(ref handler);
1244 if (_encoding != null)
1245 {
1246 stringBuilder.Append(" encoding=");
1247 stringBuilder.Append(_quoteChar);
1249 stringBuilder.Append(_quoteChar);
1250 }
1251 if (standalone >= 0)
1252 {
1253 stringBuilder.Append(" standalone=");
1254 stringBuilder.Append(_quoteChar);
1255 stringBuilder.Append((standalone == 0) ? "no" : "yes");
1256 stringBuilder.Append(_quoteChar);
1257 }
1259 }
1260 catch
1261 {
1262 _currentState = State.Error;
1263 throw;
1264 }
1265 }
1266
1267 private void AutoComplete(Token token)
1268 {
1269 if (_currentState == State.Closed)
1270 {
1272 }
1273 if (_currentState == State.Error)
1274 {
1276 }
1277 State state = _stateTable[(int)((int)token * 8 + _currentState)];
1278 if (state == State.Error)
1279 {
1281 }
1282 switch (token)
1283 {
1284 case Token.Doctype:
1285 if (_indented && _currentState != 0)
1286 {
1287 Indent(beforeEndElement: false);
1288 }
1289 break;
1290 case Token.PI:
1291 case Token.Comment:
1292 case Token.CData:
1293 case Token.StartElement:
1294 if (_currentState == State.Attribute)
1295 {
1298 }
1299 else if (_currentState == State.Element)
1300 {
1302 }
1303 if (token == Token.CData)
1304 {
1305 _stack[_top].mixed = true;
1306 }
1307 else if (_indented && _currentState != 0)
1308 {
1309 Indent(beforeEndElement: false);
1310 }
1311 break;
1312 case Token.EndElement:
1313 case Token.LongEndElement:
1314 if (_flush)
1315 {
1316 FlushEncoders();
1317 }
1318 if (_currentState == State.Attribute)
1319 {
1321 }
1322 if (_currentState == State.Content)
1323 {
1324 token = Token.LongEndElement;
1325 }
1326 else
1327 {
1328 WriteEndStartTag(token == Token.EndElement);
1329 }
1330 if (s_stateTableDocument == _stateTable && _top == 1)
1331 {
1332 state = State.Epilog;
1333 }
1334 break;
1335 case Token.StartAttribute:
1336 if (_flush)
1337 {
1338 FlushEncoders();
1339 }
1340 if (_currentState == State.Attribute)
1341 {
1343 _textWriter.Write(' ');
1344 }
1345 else if (_currentState == State.Element)
1346 {
1347 _textWriter.Write(' ');
1348 }
1349 break;
1350 case Token.EndAttribute:
1351 if (_flush)
1352 {
1353 FlushEncoders();
1354 }
1356 break;
1357 case Token.Content:
1358 case Token.RawData:
1359 case Token.Whitespace:
1360 if (_flush)
1361 {
1362 FlushEncoders();
1363 }
1364 goto case Token.Base64;
1365 case Token.Base64:
1366 if (_currentState == State.Element && _lastToken != Token.Content)
1367 {
1369 }
1370 if (state == State.Content)
1371 {
1372 _stack[_top].mixed = true;
1373 }
1374 break;
1375 default:
1377 }
1379 _lastToken = token;
1380 }
1381
1382 private void AutoCompleteAll()
1383 {
1384 if (_flush)
1385 {
1386 FlushEncoders();
1387 }
1388 while (_top > 0)
1389 {
1391 }
1392 }
1393
1394 private void InternalWriteEndElement(bool longFormat)
1395 {
1396 try
1397 {
1398 if (_top <= 0)
1399 {
1401 }
1402 AutoComplete(longFormat ? Token.LongEndElement : Token.EndElement);
1403 if (_lastToken == Token.LongEndElement)
1404 {
1405 if (_indented)
1406 {
1407 Indent(beforeEndElement: true);
1408 }
1410 if (_namespaces && _stack[_top].prefix != null)
1411 {
1413 _textWriter.Write(':');
1414 }
1416 _textWriter.Write('>');
1417 }
1418 int prevNsTop = _stack[_top].prevNsTop;
1419 if (_useNsHashtable && prevNsTop < _nsTop)
1420 {
1421 PopNamespaces(prevNsTop + 1, _nsTop);
1422 }
1423 _nsTop = prevNsTop;
1424 _top--;
1425 }
1426 catch
1427 {
1428 _currentState = State.Error;
1429 throw;
1430 }
1431 }
1432
1433 private void WriteEndStartTag(bool empty)
1434 {
1436 for (int num = _nsTop; num > _stack[_top].prevNsTop; num--)
1437 {
1438 if (!_nsStack[num].declared)
1439 {
1440 _textWriter.Write(" xmlns:");
1442 _textWriter.Write('=');
1444 _xmlEncoder.Write(_nsStack[num].ns);
1446 }
1447 }
1448 if (_stack[_top].defaultNs != _stack[_top - 1].defaultNs && _stack[_top].defaultNsState == NamespaceState.DeclaredButNotWrittenOut)
1449 {
1450 _textWriter.Write(" xmlns=");
1452 _xmlEncoder.Write(_stack[_top].defaultNs);
1454 _stack[_top].defaultNsState = NamespaceState.DeclaredAndWrittenOut;
1455 }
1457 if (empty)
1458 {
1460 }
1461 else
1462 {
1463 _textWriter.Write('>');
1464 }
1465 }
1466
1467 private void WriteEndAttributeQuote()
1468 {
1469 if (_specialAttr != 0)
1470 {
1472 }
1475 }
1476
1477 private void Indent(bool beforeEndElement)
1478 {
1479 if (_top == 0)
1480 {
1482 }
1483 else
1484 {
1485 if (_stack[_top].mixed)
1486 {
1487 return;
1488 }
1490 int num = (beforeEndElement ? (_top - 1) : _top) * _indentation;
1491 if (num <= _indentChars.Length)
1492 {
1494 return;
1495 }
1496 while (num > 0)
1497 {
1499 num -= _indentChars.Length;
1500 }
1501 }
1502 }
1503
1504 private void PushNamespace(string prefix, string ns, bool declared)
1505 {
1506 if ("http://www.w3.org/2000/xmlns/" == ns)
1507 {
1509 }
1510 if (prefix == null)
1511 {
1512 switch (_stack[_top].defaultNsState)
1513 {
1514 default:
1515 return;
1516 case NamespaceState.Uninitialized:
1517 case NamespaceState.NotDeclaredButInScope:
1518 _stack[_top].defaultNs = ns;
1519 break;
1520 case NamespaceState.DeclaredButNotWrittenOut:
1521 break;
1522 }
1523 _stack[_top].defaultNsState = (declared ? NamespaceState.DeclaredAndWrittenOut : NamespaceState.DeclaredButNotWrittenOut);
1524 return;
1525 }
1526 if (prefix.Length != 0 && ns.Length == 0)
1527 {
1529 }
1530 int num = LookupNamespace(prefix);
1531 if (num != -1 && _nsStack[num].ns == ns)
1532 {
1533 if (declared)
1534 {
1535 _nsStack[num].declared = true;
1536 }
1537 return;
1538 }
1539 if (declared && num != -1 && num > _stack[_top].prevNsTop)
1540 {
1541 _nsStack[num].declared = true;
1542 }
1543 AddNamespace(prefix, ns, declared);
1544 }
1545
1546 private void AddNamespace(string prefix, string ns, bool declared)
1547 {
1548 int num = ++_nsTop;
1549 if (num == _nsStack.Length)
1550 {
1551 Namespace[] array = new Namespace[num * 2];
1552 Array.Copy(_nsStack, array, num);
1553 _nsStack = array;
1554 }
1555 _nsStack[num].Set(prefix, ns, declared);
1556 if (_useNsHashtable)
1557 {
1558 AddToNamespaceHashtable(num);
1559 }
1560 else if (num == 16)
1561 {
1563 _useNsHashtable = true;
1564 for (int i = 0; i <= num; i++)
1565 {
1566 AddToNamespaceHashtable(i);
1567 }
1568 }
1569 }
1570
1571 private void AddToNamespaceHashtable(int namespaceIndex)
1572 {
1575 {
1577 }
1579 }
1580
1581 private void PopNamespaces(int indexFrom, int indexTo)
1582 {
1583 for (int num = indexTo; num >= indexFrom; num--)
1584 {
1585 if (_nsStack[num].prevNsIndex == -1)
1586 {
1588 }
1589 else
1590 {
1592 }
1593 }
1594 }
1595
1596 private string GeneratePrefix()
1597 {
1598 return string.Concat(str3: (_stack[_top].prefixCount++ + 1).ToString("d", CultureInfo.InvariantCulture), str0: "d", str1: _top.ToString("d", CultureInfo.InvariantCulture), str2: "p");
1599 }
1600
1601 private void InternalWriteProcessingInstruction(string name, string text)
1602 {
1603 _textWriter.Write("<?");
1604 ValidateName(name, isNCName: false);
1605 _textWriter.Write(name);
1606 _textWriter.Write(' ');
1607 if (text != null)
1608 {
1610 }
1611 _textWriter.Write("?>");
1612 }
1613
1614 private int LookupNamespace(string prefix)
1615 {
1616 if (_useNsHashtable)
1617 {
1619 {
1620 return value;
1621 }
1622 }
1623 else
1624 {
1625 for (int num = _nsTop; num >= 0; num--)
1626 {
1627 if (_nsStack[num].prefix == prefix)
1628 {
1629 return num;
1630 }
1631 }
1632 }
1633 return -1;
1634 }
1635
1636 private int LookupNamespaceInCurrentScope(string prefix)
1637 {
1638 if (_useNsHashtable)
1639 {
1641 {
1642 return value;
1643 }
1644 }
1645 else
1646 {
1647 for (int num = _nsTop; num > _stack[_top].prevNsTop; num--)
1648 {
1649 if (_nsStack[num].prefix == prefix)
1650 {
1651 return num;
1652 }
1653 }
1654 }
1655 return -1;
1656 }
1657
1658 private string FindPrefix(string ns)
1659 {
1660 for (int num = _nsTop; num >= 0; num--)
1661 {
1662 if (_nsStack[num].ns == ns && LookupNamespace(_nsStack[num].prefix) == num)
1663 {
1664 return _nsStack[num].prefix;
1665 }
1666 }
1667 return null;
1668 }
1669
1670 private void InternalWriteName(string name, bool isNCName)
1671 {
1672 ValidateName(name, isNCName);
1673 _textWriter.Write(name);
1674 }
1675
1676 private void ValidateName(string name, bool isNCName)
1677 {
1678 if (name == null || name.Length == 0)
1679 {
1681 }
1682 int length = name.Length;
1683 if (_namespaces)
1684 {
1685 int num = -1;
1686 int num2 = ValidateNames.ParseNCName(name);
1687 while (true)
1688 {
1689 if (num2 == length)
1690 {
1691 return;
1692 }
1693 if (name[num2] != ':' || isNCName || num != -1 || num2 <= 0 || num2 + 1 >= length)
1694 {
1695 break;
1696 }
1697 num = num2;
1698 num2++;
1699 num2 += ValidateNames.ParseNmtoken(name, num2);
1700 }
1701 }
1702 else if (ValidateNames.IsNameNoNamespaces(name))
1703 {
1704 return;
1705 }
1707 }
1708
1709 private void HandleSpecialAttribute()
1710 {
1712 switch (_specialAttr)
1713 {
1714 case SpecialAttr.XmlLang:
1716 break;
1717 case SpecialAttr.XmlSpace:
1718 attributeValue = XmlConvert.TrimString(attributeValue);
1719 if (attributeValue == "default")
1720 {
1721 _stack[_top].xmlSpace = XmlSpace.Default;
1722 break;
1723 }
1724 if (attributeValue == "preserve")
1725 {
1726 _stack[_top].xmlSpace = XmlSpace.Preserve;
1727 break;
1728 }
1730 case SpecialAttr.XmlNs:
1732 PushNamespace(_prefixForXmlNs, attributeValue, declared: true);
1733 break;
1734 }
1735 }
1736
1737 private void VerifyPrefixXml(string prefix, string ns)
1738 {
1739 if (prefix != null && prefix.Length == 3 && (prefix[0] == 'x' || prefix[0] == 'X') && (prefix[1] == 'm' || prefix[1] == 'M') && (prefix[2] == 'l' || prefix[2] == 'L') && "http://www.w3.org/XML/1998/namespace" != ns)
1740 {
1742 }
1743 }
1744
1745 private void PushStack()
1746 {
1747 if (_top == _stack.Length - 1)
1748 {
1749 TagInfo[] array = new TagInfo[_stack.Length + 10];
1750 if (_top > 0)
1751 {
1752 Array.Copy(_stack, array, _top + 1);
1753 }
1754 _stack = array;
1755 }
1756 _top++;
1758 }
1759
1760 private void FlushEncoders()
1761 {
1762 if (_base64Encoder != null)
1763 {
1765 }
1766 _flush = false;
1767 }
1768}
static unsafe void Copy(Array sourceArray, Array destinationArray, int length)
Definition Array.cs:624
bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value)
bool ICollection< KeyValuePair< TKey, TValue > >. Remove(KeyValuePair< TKey, TValue > keyValuePair)
virtual void Dispose(bool disposing)
virtual void Write(char value)
virtual void Flush()
virtual void WriteLine()
static byte Min(byte val1, byte val2)
Definition Math.cs:912
static string Xml_InvalidPiChars
Definition SR.cs:348
static string Xml_InvalidXmlSpace
Definition SR.cs:92
static string Xml_InvalidNameChars
Definition SR.cs:350
static string Xml_PrefixForEmptyNs
Definition SR.cs:286
static string Xml_InvalidPrefix
Definition SR.cs:354
static string Xml_NotInWriteState
Definition SR.cs:358
static string Xml_InvalidCommentChars
Definition SR.cs:288
static string Xml_EmptyName
Definition SR.cs:292
static string Xml_ClosedOrError
Definition SR.cs:300
static string Xml_CanNotBindToReservedNamespace
Definition SR.cs:108
static string Xml_NoNamespaces
Definition SR.cs:342
static string Xml_NotTheFirst
Definition SR.cs:346
static string Xml_NoStartTag
Definition SR.cs:298
static string Xml_Closed
Definition SR.cs:352
static string Xml_WrongToken
Definition SR.cs:302
static string Format(string resourceFormat, object p1)
Definition SR.cs:118
static string Xml_DupXmlDecl
Definition SR.cs:312
static string Xml_XmlnsBelongsToReservedNs
Definition SR.cs:212
static string Xml_InvalidQuote
Definition SR.cs:338
static string Xml_UndefNamespace
Definition SR.cs:290
static string Xml_InvalidCDataChars
Definition SR.cs:344
static string Xml_NoRoot
Definition SR.cs:316
static string Xml_UndefPrefix
Definition SR.cs:340
static string Xml_NonWhitespace
Definition SR.cs:310
static string Xml_InvalidOperation
Definition SR.cs:18
static string Xml_InvalidIndentation
Definition SR.cs:356
Definition SR.cs:7
virtual string WebName
Definition Encoding.cs:386
void Encode(byte[] buffer, int index, int count)
void StartAttribute(bool cacheAttrValue)
void WriteRawWithSurrogateChecking(string text)
void WriteEntityRef(string name)
void Write(char[] array, int offset, int count)
void WriteSurrogateCharEntity(char lowChar, char highChar)
void WriteRaw(char[] array, int offset, int count)
XmlTextWriterBase64Encoder _base64Encoder
readonly TextWriter _textWriter
static readonly string[] s_tokenName
Dictionary< string, int > _nsHashtable
static readonly char[] s_selfClosingTagOpen
static readonly State[] s_stateTableDefault
readonly XmlTextEncoder _xmlEncoder
static readonly char[] s_closeTagEnd
readonly Encoding _encoding
static readonly char[] s_defaultIndentChars
static readonly State[] s_stateTableDocument
static readonly string[] s_stateName
virtual void WriteName(string name)
Definition XmlWriter.cs:127
void WriteCData(string? text)
void WriteComment(string? text)
void WriteProcessingInstruction(string name, string? text)
virtual void WriteNmToken(string name)
Definition XmlWriter.cs:118
virtual void Close()
Definition XmlWriter.cs:110
void WriteSurrogateCharEntity(char lowChar, char highChar)
void WriteEntityRef(string name)
void WriteString(string? text)
string? LookupPrefix(string ns)
void WriteChars(char[] buffer, int index, int count)
void WriteBase64(byte[] buffer, int index, int count)
void WriteCharEntity(char ch)
virtual void WriteQualifiedName(string localName, string? ns)
Definition XmlWriter.cs:132
void WriteRaw(char[] buffer, int index, int count)
void WriteStartAttribute(string localName, string? ns)
Definition XmlWriter.cs:67
virtual void WriteBinHex(byte[] buffer, int index, int count)
Definition XmlWriter.cs:105
void WriteWhitespace(string? ws)
void WriteDocType(string name, string? pubid, string? sysid, string? subset)
void WriteStartElement(string localName, string? ns)
Definition XmlWriter.cs:30
void Set(string prefix, string ns, bool declared)