XmlUtil
using System.Configuration.Internal;
using System.Globalization;
using System.IO;
using System.Text;
using System.Xml;
namespace System.Configuration
{
internal sealed class XmlUtil : IDisposable, IConfigErrorInfo
{
private const int MaxLineWidth = 60;
private StringWriter _cachedStringWriter;
private int _lastLineNumber;
private int _lastLinePosition;
private Stream _stream;
private static ReadOnlySpan<int> PositionOffset {
get {
object obj = global::<PrivateImplementationDetails>.D523102CC9E2790FF1E8689A2541A70BB5FF2390AB957F902ACD5A04E22404C5_A6;
if (obj == null) {
obj = new int[18] {
0,
1,
-1,
0,
9,
1,
-1,
2,
4,
-1,
10,
-1,
-1,
0,
0,
2,
-1,
2
};
global::<PrivateImplementationDetails>.D523102CC9E2790FF1E8689A2541A70BB5FF2390AB957F902ACD5A04E22404C5_A6 = (int[])obj;
}
return new ReadOnlySpan<int>((int[])obj);
}
}
internal int TrueLinePosition => Reader.get_LinePosition() - GetPositionOffset(Reader.get_NodeType());
internal XmlTextReader Reader { get; set; }
internal ConfigurationSchemaErrors SchemaErrors { get; }
public string Filename { get; }
public int LineNumber => Reader.get_LineNumber();
internal XmlUtil(Stream stream, string name, bool readToFirstElement)
: this(stream, name, readToFirstElement, new ConfigurationSchemaErrors())
{
}
internal XmlUtil(Stream stream, string name, bool readToFirstElement, ConfigurationSchemaErrors schemaErrors)
{
try {
Filename = name;
_stream = stream;
XmlTextReader val = new XmlTextReader(_stream);
val.set_XmlResolver(null);
Reader = val;
SchemaErrors = schemaErrors;
_lastLineNumber = 1;
_lastLinePosition = 1;
if (readToFirstElement) {
Reader.set_WhitespaceHandling(2);
bool flag = false;
while (true) {
if (flag || !Reader.Read())
return;
XmlNodeType nodeType = Reader.get_NodeType();
if ((int)nodeType <= 8) {
if ((int)nodeType != 1) {
if ((int)nodeType != 8)
break;
} else
flag = true;
} else if ((int)nodeType != 10 && (int)nodeType != 17) {
break;
}
}
throw new ConfigurationErrorsException(System.SR.Config_base_unrecognized_element, (IConfigErrorInfo)this);
}
} catch {
ReleaseResources();
throw;
}
}
public void Dispose()
{
ReleaseResources();
}
private static int GetPositionOffset(XmlNodeType nodeType)
{
return PositionOffset[(int)nodeType];
}
private void ReleaseResources()
{
if ((object)Reader != null) {
Reader.Close();
Reader = null;
} else
_stream?.Close();
_stream = null;
if (_cachedStringWriter != null) {
_cachedStringWriter.Close();
_cachedStringWriter = null;
}
}
internal void ReadToNextElement()
{
while (Reader.Read() && (int)Reader.MoveToContent() != 1) {
}
}
internal void SkipToNextElement()
{
Reader.Skip();
Reader.MoveToContent();
while (!Reader.get_EOF() && (int)Reader.get_NodeType() != 1) {
Reader.Read();
Reader.MoveToContent();
}
}
internal void StrictReadToNextElement(ExceptionAction action)
{
while (Reader.Read() && (int)Reader.get_NodeType() != 1) {
VerifyIgnorableNodeType(action);
}
}
internal void StrictSkipToNextElement(ExceptionAction action)
{
Reader.Skip();
while (!Reader.get_EOF() && (int)Reader.get_NodeType() != 1) {
VerifyIgnorableNodeType(action);
Reader.Read();
}
}
internal void StrictSkipToOurParentsEndElement(ExceptionAction action)
{
int depth = Reader.get_Depth();
while (Reader.get_Depth() >= depth) {
Reader.Skip();
}
while (!Reader.get_EOF() && (int)Reader.get_NodeType() != 15) {
VerifyIgnorableNodeType(action);
Reader.Read();
}
}
internal void VerifyIgnorableNodeType(ExceptionAction action)
{
XmlNodeType nodeType = Reader.get_NodeType();
if ((int)nodeType != 8 && (int)nodeType != 15) {
ConfigurationException ce = new ConfigurationErrorsException(System.SR.Config_base_unrecognized_element, (IConfigErrorInfo)this);
SchemaErrors.AddError(ce, action);
}
}
internal void VerifyNoUnrecognizedAttributes(ExceptionAction action)
{
if (Reader.MoveToNextAttribute())
AddErrorUnrecognizedAttribute(action);
}
internal bool VerifyRequiredAttribute(object requiredAttribute, string attrName, ExceptionAction action)
{
if (requiredAttribute == null) {
AddErrorRequiredAttribute(attrName, action);
return false;
}
return true;
}
internal void AddErrorUnrecognizedAttribute(ExceptionAction action)
{
ConfigurationErrorsException ce = new ConfigurationErrorsException(System.SR.Format(System.SR.Config_base_unrecognized_attribute, Reader.get_Name()), (IConfigErrorInfo)this);
SchemaErrors.AddError(ce, action);
}
internal void AddErrorRequiredAttribute(string attrib, ExceptionAction action)
{
ConfigurationErrorsException ce = new ConfigurationErrorsException(System.SR.Format(System.SR.Config_missing_required_attribute, attrib, Reader.get_Name()), (IConfigErrorInfo)this);
SchemaErrors.AddError(ce, action);
}
internal void AddErrorReservedAttribute(ExceptionAction action)
{
ConfigurationErrorsException ce = new ConfigurationErrorsException(System.SR.Format(System.SR.Config_reserved_attribute, Reader.get_Name()), (IConfigErrorInfo)this);
SchemaErrors.AddError(ce, action);
}
internal void AddErrorUnrecognizedElement(ExceptionAction action)
{
ConfigurationErrorsException ce = new ConfigurationErrorsException(System.SR.Config_base_unrecognized_element, (IConfigErrorInfo)this);
SchemaErrors.AddError(ce, action);
}
internal void VerifyAndGetNonEmptyStringAttribute(ExceptionAction action, out string newValue)
{
if (!string.IsNullOrEmpty(Reader.get_Value()))
newValue = Reader.get_Value();
else {
newValue = null;
ConfigurationException ce = new ConfigurationErrorsException(System.SR.Format(System.SR.Empty_attribute, Reader.get_Name()), (IConfigErrorInfo)this);
SchemaErrors.AddError(ce, action);
}
}
internal void VerifyAndGetBooleanAttribute(ExceptionAction action, bool defaultValue, out bool newValue)
{
string value = Reader.get_Value();
if (!(value == "true")) {
if (value == "false")
newValue = false;
else {
newValue = defaultValue;
SchemaErrors.AddError(new ConfigurationErrorsException(System.SR.Format(System.SR.Config_invalid_boolean_attribute, Reader.get_Name()), (IConfigErrorInfo)this), action);
}
} else
newValue = true;
}
internal bool CopyOuterXmlToNextElement(XmlUtilWriter utilWriter, bool limitDepth)
{
CopyElement(utilWriter);
return CopyReaderToNextElement(utilWriter, limitDepth);
}
internal bool SkipChildElementsAndCopyOuterXmlToNextElement(XmlUtilWriter utilWriter)
{
bool isEmptyElement = Reader.get_IsEmptyElement();
int lineNumber = Reader.get_LineNumber();
CopyXmlNode(utilWriter);
if (!isEmptyElement) {
while ((int)Reader.get_NodeType() != 15) {
if ((int)Reader.get_NodeType() == 1) {
Reader.Skip();
if ((int)Reader.get_NodeType() == 13)
Reader.Skip();
} else
CopyXmlNode(utilWriter);
}
if (Reader.get_LineNumber() != lineNumber)
utilWriter.AppendSpacesToLinePosition(TrueLinePosition);
CopyXmlNode(utilWriter);
}
return CopyReaderToNextElement(utilWriter, true);
}
internal bool CopyReaderToNextElement(XmlUtilWriter utilWriter, bool limitDepth)
{
bool flag = true;
int num;
if (limitDepth) {
if ((int)Reader.get_NodeType() == 15)
return true;
num = Reader.get_Depth();
} else
num = 0;
while ((int)Reader.get_NodeType() != 1 && Reader.get_Depth() >= num) {
flag = CopyXmlNode(utilWriter);
if (!flag)
break;
}
return flag;
}
internal bool SkipAndCopyReaderToNextElement(XmlUtilWriter utilWriter, bool limitDepth)
{
if (!utilWriter.IsLastLineBlank) {
Reader.Skip();
return CopyReaderToNextElement(utilWriter, limitDepth);
}
int num = limitDepth ? Reader.get_Depth() : 0;
Reader.Skip();
int lineNumber = Reader.get_LineNumber();
while (!Reader.get_EOF()) {
if ((int)Reader.get_NodeType() != 13) {
if (Reader.get_LineNumber() > lineNumber) {
utilWriter.SeekToLineStart();
utilWriter.AppendWhiteSpace(lineNumber + 1, 1, LineNumber, TrueLinePosition);
}
break;
}
Reader.Read();
}
while (!Reader.get_EOF() && (int)Reader.get_NodeType() != 1 && Reader.get_Depth() >= num) {
CopyXmlNode(utilWriter);
}
return !Reader.get_EOF();
}
private void CopyElement(XmlUtilWriter utilWriter)
{
int depth = Reader.get_Depth();
bool isEmptyElement = Reader.get_IsEmptyElement();
CopyXmlNode(utilWriter);
while (Reader.get_Depth() > depth) {
CopyXmlNode(utilWriter);
}
if (!isEmptyElement)
CopyXmlNode(utilWriter);
}
internal bool CopyXmlNode(XmlUtilWriter utilWriter)
{
string text = null;
int fromLineNumber = -1;
int fromLinePosition = -1;
int num = 0;
int num2 = 0;
int num3 = 0;
int num4 = 0;
if (utilWriter.TrackPosition) {
num = Reader.get_LineNumber();
num2 = Reader.get_LinePosition();
num3 = utilWriter.LineNumber;
num4 = utilWriter.LinePosition;
}
XmlNodeType nodeType = Reader.get_NodeType();
if ((int)nodeType == 13)
utilWriter.Write(Reader.get_Value());
else if ((int)nodeType == 1) {
text = (Reader.get_IsEmptyElement() ? "/>" : ">");
fromLineNumber = Reader.get_LineNumber();
fromLinePosition = Reader.get_LinePosition() + Reader.get_Name().Length;
utilWriter.Write('<');
utilWriter.Write(Reader.get_Name());
while (Reader.MoveToNextAttribute()) {
int lineNumber = Reader.get_LineNumber();
int linePosition = Reader.get_LinePosition();
utilWriter.AppendRequiredWhiteSpace(fromLineNumber, fromLinePosition, lineNumber, linePosition);
int num5 = utilWriter.Write(Reader.get_Name());
num5 += utilWriter.Write('=');
num5 += utilWriter.AppendAttributeValue(Reader);
fromLineNumber = lineNumber;
fromLinePosition = linePosition + num5;
}
} else if ((int)nodeType == 15) {
text = ">";
fromLineNumber = Reader.get_LineNumber();
fromLinePosition = Reader.get_LinePosition() + Reader.get_Name().Length;
utilWriter.Write("</");
utilWriter.Write(Reader.get_Name());
} else if ((int)nodeType == 8) {
utilWriter.AppendComment(Reader.get_Value());
} else if ((int)nodeType == 3) {
utilWriter.AppendEscapeTextString(Reader.get_Value());
} else if ((int)nodeType == 17) {
text = "?>";
fromLineNumber = Reader.get_LineNumber();
fromLinePosition = Reader.get_LinePosition() + 3;
utilWriter.Write("<?xml");
while (Reader.MoveToNextAttribute()) {
int lineNumber2 = Reader.get_LineNumber();
int linePosition2 = Reader.get_LinePosition();
utilWriter.AppendRequiredWhiteSpace(fromLineNumber, fromLinePosition, lineNumber2, linePosition2);
int num6 = utilWriter.Write(Reader.get_Name());
num6 += utilWriter.Write('=');
num6 += utilWriter.AppendAttributeValue(Reader);
fromLineNumber = lineNumber2;
fromLinePosition = linePosition2 + num6;
}
Reader.MoveToElement();
} else if ((int)nodeType == 14) {
utilWriter.Write(Reader.get_Value());
} else if ((int)nodeType == 7) {
utilWriter.AppendProcessingInstruction(Reader.get_Name(), Reader.get_Value());
} else if ((int)nodeType == 5) {
utilWriter.AppendEntityRef(Reader.get_Name());
} else if ((int)nodeType == 4) {
utilWriter.AppendCData(Reader.get_Value());
} else if ((int)nodeType == 10) {
int num7 = utilWriter.Write("<!DOCTYPE");
utilWriter.AppendRequiredWhiteSpace(_lastLineNumber, _lastLinePosition + num7, Reader.get_LineNumber(), Reader.get_LinePosition());
utilWriter.Write(Reader.get_Name());
string text2 = null;
if (Reader.get_HasValue())
text2 = Reader.get_Value();
fromLineNumber = Reader.get_LineNumber();
fromLinePosition = Reader.get_LinePosition() + Reader.get_Name().Length;
if (Reader.MoveToFirstAttribute()) {
utilWriter.AppendRequiredWhiteSpace(fromLineNumber, fromLinePosition, Reader.get_LineNumber(), Reader.get_LinePosition());
string name = Reader.get_Name();
utilWriter.Write(name);
utilWriter.AppendSpace();
utilWriter.AppendAttributeValue(Reader);
Reader.MoveToAttribute(0);
if (name == "PUBLIC") {
Reader.MoveToAttribute(1);
utilWriter.AppendSpace();
utilWriter.AppendAttributeValue(Reader);
Reader.MoveToAttribute(1);
}
}
if (!string.IsNullOrEmpty(text2)) {
utilWriter.Write(" [");
utilWriter.Write(text2);
utilWriter.Write(']');
}
utilWriter.Write('>');
}
bool result = Reader.Read();
nodeType = Reader.get_NodeType();
if (text != null) {
int positionOffset = GetPositionOffset(nodeType);
int lineNumber3 = Reader.get_LineNumber();
int toLinePosition = Reader.get_LinePosition() - positionOffset - text.Length;
utilWriter.AppendWhiteSpace(fromLineNumber, fromLinePosition, lineNumber3, toLinePosition);
utilWriter.Write(text);
}
if (utilWriter.TrackPosition) {
_lastLineNumber = num - num3 + utilWriter.LineNumber;
if (num3 == utilWriter.LineNumber) {
_lastLinePosition = num2 - num4 + utilWriter.LinePosition;
return result;
}
_lastLinePosition = utilWriter.LinePosition;
}
return result;
}
private string RetrieveFullOpenElementTag()
{
StringBuilder stringBuilder = new StringBuilder(64);
stringBuilder.Append('<');
stringBuilder.Append(Reader.get_Name());
while (Reader.MoveToNextAttribute()) {
stringBuilder.Append(' ');
stringBuilder.Append(Reader.get_Name());
stringBuilder.Append('=');
stringBuilder.Append('"');
stringBuilder.Append(Reader.get_Value());
stringBuilder.Append('"');
}
stringBuilder.Append('>');
return stringBuilder.ToString();
}
internal string UpdateStartElement(XmlUtilWriter utilWriter, string updatedStartElement, bool needsChildren, int linePosition, int indent)
{
string result = null;
bool flag = false;
string name = Reader.get_Name();
if (Reader.get_IsEmptyElement()) {
if ((updatedStartElement == null) & needsChildren)
updatedStartElement = RetrieveFullOpenElementTag();
flag = (updatedStartElement != null);
}
if (updatedStartElement == null)
CopyXmlNode(utilWriter);
else {
string str = "</" + name + ">";
string text = FormatXmlElement(updatedStartElement + str, linePosition, indent, true);
int num = text.LastIndexOf('\n') + 1;
string s;
if (flag) {
result = text.Substring(num);
s = text.Substring(0, num);
} else
s = text.Substring(0, num - 2);
utilWriter.Write(s);
Reader.Read();
}
return result;
}
private void ResetCachedStringWriter()
{
if (_cachedStringWriter == null)
_cachedStringWriter = new StringWriter(new StringBuilder(64), CultureInfo.InvariantCulture);
else
_cachedStringWriter.GetStringBuilder().Length = 0;
}
internal string CopySection()
{
ResetCachedStringWriter();
WhitespaceHandling whitespaceHandling = Reader.get_WhitespaceHandling();
Reader.set_WhitespaceHandling(0);
XmlUtilWriter xmlUtilWriter = new XmlUtilWriter(_cachedStringWriter, false);
CopyElement(xmlUtilWriter);
Reader.set_WhitespaceHandling(whitespaceHandling);
if ((int)whitespaceHandling == 2 && (int)Reader.get_NodeType() == 13)
Reader.Read();
xmlUtilWriter.Flush();
return ((StringWriter)xmlUtilWriter.Writer).ToString();
}
internal static string FormatXmlElement(string xmlElement, int linePosition, int indent, bool skipFirstIndent)
{
XmlParserContext val = new XmlParserContext(null, null, (string)null, 1, Encoding.Unicode);
XmlTextReader val2 = new XmlTextReader(xmlElement, 1, val);
XmlUtilWriter xmlUtilWriter = new XmlUtilWriter(new StringWriter(new StringBuilder(64), CultureInfo.InvariantCulture), false);
bool flag = false;
bool flag2 = false;
int num = 0;
while (val2.Read()) {
XmlNodeType nodeType = val2.get_NodeType();
int num2;
if (flag2) {
xmlUtilWriter.Flush();
num2 = num - ((StringWriter)xmlUtilWriter.Writer).GetStringBuilder().Length;
} else
num2 = 0;
if ((int)nodeType <= 4) {
if ((int)nodeType == 1 || (int)nodeType == 4)
goto IL_008a;
} else if ((int)nodeType == 8 || (int)nodeType == 15) {
goto IL_008a;
}
goto IL_00c1;
IL_008a:
if (!skipFirstIndent && !flag2) {
xmlUtilWriter.AppendIndent(linePosition, indent, val2.get_Depth(), flag);
if (flag) {
xmlUtilWriter.Flush();
num = ((StringWriter)xmlUtilWriter.Writer).GetStringBuilder().Length;
}
}
goto IL_00c1;
IL_00c1:
flag2 = false;
switch (nodeType - 1) {
case 13:
xmlUtilWriter.Write(val2.get_Value());
break;
case 3:
xmlUtilWriter.AppendCData(val2.get_Value());
break;
case 6:
xmlUtilWriter.AppendProcessingInstruction(val2.get_Name(), val2.get_Value());
break;
case 7:
xmlUtilWriter.AppendComment(val2.get_Value());
break;
case 2:
xmlUtilWriter.AppendEscapeTextString(val2.get_Value());
flag2 = true;
break;
case 0: {
xmlUtilWriter.Write('<');
xmlUtilWriter.Write(val2.get_Name());
num2 += val2.get_Name().Length + 2;
int attributeCount = val2.get_AttributeCount();
for (int i = 0; i < attributeCount; i++) {
bool flag3;
if (num2 > 60) {
xmlUtilWriter.AppendIndent(linePosition, indent, val2.get_Depth() - 1, true);
num2 = indent;
flag3 = false;
xmlUtilWriter.Flush();
num = ((StringWriter)xmlUtilWriter.Writer).GetStringBuilder().Length;
} else
flag3 = true;
val2.MoveToNextAttribute();
xmlUtilWriter.Flush();
int length = ((StringWriter)xmlUtilWriter.Writer).GetStringBuilder().Length;
if (flag3)
xmlUtilWriter.AppendSpace();
xmlUtilWriter.Write(val2.get_Name());
xmlUtilWriter.Write('=');
xmlUtilWriter.AppendAttributeValue(val2);
xmlUtilWriter.Flush();
num2 += ((StringWriter)xmlUtilWriter.Writer).GetStringBuilder().Length - length;
}
val2.MoveToElement();
if (val2.get_IsEmptyElement())
xmlUtilWriter.Write(" />");
else
xmlUtilWriter.Write('>');
break;
}
case 14:
xmlUtilWriter.Write("</");
xmlUtilWriter.Write(val2.get_Name());
xmlUtilWriter.Write('>');
break;
case 4:
xmlUtilWriter.AppendEntityRef(val2.get_Name());
break;
}
flag = true;
skipFirstIndent = false;
}
xmlUtilWriter.Flush();
return ((StringWriter)xmlUtilWriter.Writer).ToString();
}
}
}