<PackageReference Include="System.Configuration.ConfigurationManager" Version="9.0.1" />

XmlUtilWriter

sealed class XmlUtilWriter
using System.IO; using System.Xml; namespace System.Configuration { internal sealed class XmlUtilWriter { private sealed class StreamWriterCheckpoint { internal readonly bool _isLastLineBlank; internal readonly int _lineNumber; internal readonly int _linePosition; internal readonly long _streamLength; internal readonly long _streamPosition; internal StreamWriterCheckpoint(XmlUtilWriter writer) { writer.Flush(); _lineNumber = writer.LineNumber; _linePosition = writer.LinePosition; _isLastLineBlank = writer.IsLastLineBlank; writer._baseStream.Flush(); _streamPosition = writer._baseStream.Position; _streamLength = writer._baseStream.Length; } } private const char Space = ' '; private const string NewLine = "\r\n"; private static readonly string s_spaces8 = new string(' ', 8); private static readonly string s_spaces4 = new string(' ', 4); private static readonly string s_spaces2 = new string(' ', 2); private readonly Stream _baseStream; private object _lineStartCheckpoint; internal TextWriter Writer { get; } internal bool TrackPosition { get; } internal int LineNumber { get; set; } internal int LinePosition { get; set; } internal bool IsLastLineBlank { get; set; } internal XmlUtilWriter(TextWriter writer, bool trackPosition) { Writer = writer; TrackPosition = trackPosition; LineNumber = 1; LinePosition = 1; IsLastLineBlank = true; if (TrackPosition) { _baseStream = ((StreamWriter)Writer).BaseStream; _lineStartCheckpoint = CreateStreamCheckpoint(); } } private void UpdatePosition(char ch) { switch (ch) { case '\r': LineNumber++; LinePosition = 1; IsLastLineBlank = true; break; case '\n': _lineStartCheckpoint = CreateStreamCheckpoint(); break; case '\t': case ' ': LinePosition++; break; default: LinePosition++; IsLastLineBlank = false; break; } } internal int Write(string s) { if (TrackPosition) { foreach (char c in s) { Writer.Write(c); UpdatePosition(c); } } else Writer.Write(s); return s.Length; } internal int Write(char ch) { Writer.Write(ch); if (TrackPosition) UpdatePosition(ch); return 1; } internal void Flush() { Writer.Flush(); } internal int AppendEscapeTextString(string s) { return AppendEscapeXmlString(s, false, 'A'); } internal int AppendEscapeXmlString(string s, bool inAttribute, char quoteChar) { int num = 0; foreach (char c in s) { bool flag = false; string text = null; if ((c < ' ' && c != '\t' && c != '\r' && c != '\n') || c > '�') flag = true; else { switch (c) { case '<': text = "lt"; break; case '>': text = "gt"; break; case '&': text = "amp"; break; case '\'': if (inAttribute && quoteChar == c) text = "apos"; break; case '"': if (inAttribute && quoteChar == c) text = "quot"; break; case '\n': case '\r': flag = inAttribute; break; } } num = ((!flag) ? ((text == null) ? (num + Write(c)) : (num + AppendEntityRef(text))) : (num + AppendCharEntity(c))); } return num; } internal int AppendEntityRef(string entityRef) { Write('&'); Write(entityRef); Write(';'); return entityRef.Length + 2; } internal int AppendCharEntity(char ch) { int num = ch; string text = num.ToString("X"); Write('&'); Write('#'); Write('x'); Write(text); Write(';'); return text.Length + 4; } internal int AppendCData(string cdata) { Write("<![CDATA["); Write(cdata); Write("]]>"); return cdata.Length + 12; } internal int AppendProcessingInstruction(string name, string value) { Write("<?"); Write(name); AppendSpace(); Write(value); Write("?>"); return name.Length + value.Length + 5; } internal int AppendComment(string comment) { Write("<!--"); Write(comment); Write("-->"); return comment.Length + 7; } internal int AppendAttributeValue(XmlTextReader reader) { int num = 0; char c = reader.QuoteChar; if (c != '"' && c != '\'') c = '"'; num += Write(c); while (reader.ReadAttributeValue()) { num = ((reader.NodeType != XmlNodeType.Text) ? (num + AppendEntityRef(reader.Name)) : (num + AppendEscapeXmlString(reader.Value, true, c))); } return num + Write(c); } internal int AppendRequiredWhiteSpace(int fromLineNumber, int fromLinePosition, int toLineNumber, int toLinePosition) { int num = AppendWhiteSpace(fromLineNumber, fromLinePosition, toLineNumber, toLinePosition); if (num == 0) num += AppendSpace(); return num; } internal int AppendWhiteSpace(int fromLineNumber, int fromLinePosition, int toLineNumber, int toLinePosition) { int num = 0; while (fromLineNumber++ < toLineNumber) { num += AppendNewLine(); fromLinePosition = 1; } return num + AppendSpaces(toLinePosition - fromLinePosition); } internal int AppendIndent(int linePosition, int indent, int depth, bool newLine) { int num = 0; if (newLine) num += AppendNewLine(); int count = linePosition - 1 + indent * depth; return num + AppendSpaces(count); } internal int AppendSpacesToLinePosition(int linePosition) { if (linePosition <= 0) return 0; if (linePosition - LinePosition < 0 && IsLastLineBlank) SeekToLineStart(); return AppendSpaces(linePosition - LinePosition); } internal int AppendNewLine() { return Write("\r\n"); } internal int AppendSpaces(int count) { int num = count; while (num > 0) { if (num >= 8) { Write(s_spaces8); num -= 8; } else if (num >= 4) { Write(s_spaces4); num -= 4; } else { if (num < 2) { Write(' '); break; } Write(s_spaces2); num -= 2; } } if (count <= 0) return 0; return count; } internal int AppendSpace() { return Write(' '); } internal void SeekToLineStart() { RestoreStreamCheckpoint(_lineStartCheckpoint); } internal object CreateStreamCheckpoint() { return new StreamWriterCheckpoint(this); } internal void RestoreStreamCheckpoint(object o) { StreamWriterCheckpoint streamWriterCheckpoint = (StreamWriterCheckpoint)o; Flush(); LineNumber = streamWriterCheckpoint._lineNumber; LinePosition = streamWriterCheckpoint._linePosition; IsLastLineBlank = streamWriterCheckpoint._isLastLineBlank; _baseStream.Seek(streamWriterCheckpoint._streamPosition, SeekOrigin.Begin); _baseStream.SetLength(streamWriterCheckpoint._streamLength); _baseStream.Flush(); } } }