// // Copy or replace an element node. // If the element is an empty element, replace it with a formatted start element if either: // * The contents of the start element string need updating. // * The element needs to contain child elements. // // If the element is empty and is replaced with a start/end element pair, return a // end element string with whitespace formatting; otherwise return null. // internal string UpdateStartElement(XmlUtilWriter utilWriter, string updatedStartElement, bool needsChildren, int linePosition, int indent) { Debug.Assert(Reader.NodeType == XmlNodeType.Element, "_reader.NodeType == NodeType.Element"); string endElement = null; bool needsEndElement = false; string elementName = Reader.Name; // If the element is empty, determine if a new end element is needed. if (Reader.IsEmptyElement) { if ((updatedStartElement == null) && needsChildren) { updatedStartElement = RetrieveFullOpenElementTag(); } needsEndElement = updatedStartElement != null; } if (updatedStartElement == null) { // If no changes to the start element are required, just copy it. CopyXmlNode(utilWriter); } else { // Format a new start element/end element pair string updatedEndElement = "</" + elementName + ">"; string updatedElement = updatedStartElement + updatedEndElement; string formattedElement = FormatXmlElement(updatedElement, linePosition, indent, true); // Get the start and end element strings from the formatted element. int iEndElement = formattedElement.LastIndexOf('\n') + 1; string startElement; if (needsEndElement) { endElement = formattedElement.Substring(iEndElement); // Include a newline in the start element as we are expanding an empty element. startElement = formattedElement.Substring(0, iEndElement); } else { // Omit the newline from the start element. startElement = formattedElement.Substring(0, iEndElement - 2); } // Write the new start element. utilWriter.Write(startElement); // Skip over the existing start element. Reader.Read(); } return(endElement); }
internal string UpdateStartElement(XmlUtilWriter utilWriter, string updatedStartElement, bool needsChildren, int linePosition, int indent) { string str = null; string str6; bool flag = false; string name = this._reader.Name; if (this._reader.IsEmptyElement) { if ((updatedStartElement == null) && needsChildren) { updatedStartElement = this.RetrieveFullOpenElementTag(); } flag = updatedStartElement != null; } if (updatedStartElement == null) { this.CopyXmlNode(utilWriter); return(str); } string str5 = FormatXmlElement(updatedStartElement + ("</" + name + ">"), linePosition, indent, true); int startIndex = str5.LastIndexOf('\n') + 1; if (flag) { str = str5.Substring(startIndex); str6 = str5.Substring(0, startIndex); } else { str6 = str5.Substring(0, startIndex - 2); } utilWriter.Write(str6); this._reader.Read(); return(str); }
private bool CopyConfigDeclarationsRecursive( SectionUpdates declarationUpdates, XmlUtil xmlUtil, XmlUtilWriter utilWriter, string group, int parentLinePosition, int parentIndent) { bool wroteASection = false; XmlTextReader reader = xmlUtil.Reader; int linePosition; int indent; int startingLinePosition; indent = UpdateIndent(parentIndent, xmlUtil, utilWriter, parentLinePosition); if (reader.NodeType == XmlNodeType.Element) { linePosition = xmlUtil.TrueLinePosition; startingLinePosition = linePosition; } else if (reader.NodeType == XmlNodeType.EndElement) { linePosition = parentLinePosition + indent; if (utilWriter.IsLastLineBlank) { startingLinePosition = xmlUtil.TrueLinePosition; } else { startingLinePosition = parentLinePosition; } } else { linePosition = parentLinePosition + indent; startingLinePosition = 0; } // // Write any new section declarations that apply to this group // if (declarationUpdates != null) { string[] movedSectionNames = declarationUpdates.GetMovedSectionNames(); if (movedSectionNames != null) { if (!utilWriter.IsLastLineBlank) { utilWriter.AppendNewLine(); } foreach (string configKey in movedSectionNames) { DeclarationUpdate sectionUpdate = declarationUpdates.GetDeclarationUpdate(configKey); Debug.Assert(!IsImplicitSection(configKey), "We should never write out an implicit section"); // Write the one line section declaration. utilWriter.AppendSpacesToLinePosition(linePosition); utilWriter.Write(sectionUpdate.UpdatedXml); utilWriter.AppendNewLine(); wroteASection = true; } // Restore the whitespace we used for the first element, which is either a start or an end element. utilWriter.AppendSpacesToLinePosition(startingLinePosition); } } if (reader.NodeType == XmlNodeType.Element) { // // For each element at this depth, either: // - Write the element verbatim and recurse due to a group hierarchy element. // - Write the element verbatim because it is unchanged // - Write the updated XML for the section. // - Skip it because the section has been removed. // int depth = reader.Depth; while (reader.Depth == depth) { bool recurse = false; DeclarationUpdate sectionUpdate = null; DeclarationUpdate groupUpdate = null; SectionUpdates declarationUpdatesChild = null; SectionUpdates recurseDeclarationUpdates = declarationUpdates; string recurseGroup = group; // update the lineposition and indent for each element indent = UpdateIndent(indent, xmlUtil, utilWriter, parentLinePosition); linePosition = xmlUtil.TrueLinePosition; string directive = reader.Name; string name = reader.GetAttribute(KEYWORD_SECTIONGROUP_NAME); string configKey = CombineConfigKey(group, name); if (directive == KEYWORD_SECTIONGROUP) { // it's a group - get the updates for children declarationUpdatesChild = declarationUpdates.GetSectionUpdatesForGroup(name); if (declarationUpdatesChild != null) { // get the group update groupUpdate = declarationUpdatesChild.GetSectionGroupUpdate(); // recurse if there are more sections to copy if (declarationUpdatesChild.HasUnretrievedSections()) { recurse = true; recurseGroup = configKey; recurseDeclarationUpdates = declarationUpdatesChild; } } } else { // it is a section - get the update Debug.Assert(!IsImplicitSection(configKey), "We should never write out an implicit section"); sectionUpdate = declarationUpdates.GetDeclarationUpdate(configKey); } bool writeGroupUpdate = (groupUpdate != null && groupUpdate.UpdatedXml != null); if (recurse) { #if DBG string startElementName = reader.Name; #endif // create a checkpoint that we can revert to if no children are written object checkpoint = utilWriter.CreateStreamCheckpoint(); string closingElement = null; // Copy this element node and up to the first subelement if (writeGroupUpdate) { // replace the element with the updated xml utilWriter.Write(groupUpdate.UpdatedXml); // skip over the start element reader.Read(); } else { closingElement= xmlUtil.UpdateStartElement(utilWriter, null, true, linePosition, indent); } if (closingElement == null) { // Only if there is a closing element should // we move to it xmlUtil.CopyReaderToNextElement(utilWriter, true); } // Recurse bool recurseWroteASection = CopyConfigDeclarationsRecursive( recurseDeclarationUpdates, xmlUtil, utilWriter, recurseGroup, linePosition, indent); if (closingElement != null) { utilWriter.AppendSpacesToLinePosition(linePosition); utilWriter.Write(closingElement); // Since we already got to </configSections> in reader, lets // indent so we can copy the element in the right place utilWriter.AppendSpacesToLinePosition(parentLinePosition); } else { // Copy the end element xmlUtil.CopyXmlNode(utilWriter); } if (recurseWroteASection || writeGroupUpdate) { wroteASection = true; } else { // back out the change utilWriter.RestoreStreamCheckpoint(checkpoint); } // Copy up to the next element, or exit this level. xmlUtil.CopyReaderToNextElement(utilWriter, true); } else { bool skip; bool skipChildElements = false; if (sectionUpdate == null) { skip = true; if (writeGroupUpdate) { // Insert an empty <sectionGroup type="typename" > node, to introduce the type wroteASection = true; utilWriter.Write(groupUpdate.UpdatedXml); utilWriter.AppendNewLine(); utilWriter.AppendSpacesToLinePosition(linePosition); utilWriter.Write(FORMAT_SECTIONGROUP_ENDELEMENT); utilWriter.AppendNewLine(); utilWriter.AppendSpacesToLinePosition(linePosition); } else if (groupUpdate != null) { // VSWhidbey 522450 // If groupUpdate exists, that means we've decided in GetConfigDeclarationUpdates // that the section group should stay in the file. Debug.Assert(groupUpdate.UpdatedXml == null, "groupUpdate.UpdatedXml == null"); Debug.Assert(!declarationUpdatesChild.HasUnretrievedSections(), "If the group has any unretrieved section, we should have chosen the recursive code path above."); wroteASection = true; skip = false; // We should skip all the child sections. If we indeed need to keep any child // section, we should have chosen the recursive code path above. skipChildElements = true; } } else { wroteASection = true; if (sectionUpdate.UpdatedXml == null) { skip = false; } else { skip = true; // Write the updated XML on a single line utilWriter.Write(sectionUpdate.UpdatedXml); } } if (skip) { // // Skip over the existing element, then // copy up to the next element, or exit this level. // xmlUtil.SkipAndCopyReaderToNextElement(utilWriter, true); } else { if (skipChildElements) { xmlUtil.SkipChildElementsAndCopyOuterXmlToNextElement(utilWriter); } else { // Copy this entire contents of this element and then to the next element, or exit this level. xmlUtil.CopyOuterXmlToNextElement(utilWriter, true); } } } } } return wroteASection; }
private void CopyConfigSource(XmlUtilWriter utilWriter, string updatedXml, string configSourceStreamName, byte[] buffer) { // only copy the byte order mark if it exists in the current web.config byte[] preamble; using (Stream stream = new MemoryStream(buffer)) { using (XmlUtil xmlUtil = new XmlUtil(stream, configSourceStreamName, true)) { preamble = ConfigStreamInfo.StreamEncoding.GetPreamble(); } } CheckPreamble(preamble, utilWriter, buffer); using (Stream stream = new MemoryStream(buffer)) { using (XmlUtil xmlUtil = new XmlUtil(stream, configSourceStreamName, false)) { XmlTextReader reader = xmlUtil.Reader; // copy up to the first element reader.WhitespaceHandling = WhitespaceHandling.All; reader.Read(); // determine the indent to use for the element int indent = DEFAULT_INDENT; int linePosition = 1; bool hasElement = xmlUtil.CopyReaderToNextElement(utilWriter, false); if (hasElement) { // find the indent of the first attribute, if any int lineNumber = reader.LineNumber; linePosition = reader.LinePosition - 1; int attributeIndent = 0; while (reader.MoveToNextAttribute()) { if (reader.LineNumber > lineNumber) { attributeIndent = reader.LinePosition - linePosition; break; } } // find the indent of the first sub element, if any int elementIndent = 0; reader.Read(); while (reader.Depth >= 1) { if (reader.NodeType == XmlNodeType.Element) { elementIndent = (reader.LinePosition - 1) - linePosition; break; } reader.Read(); } if (elementIndent > 0) { indent = elementIndent; } else if (attributeIndent > 0) { indent = attributeIndent; } } // Write the config source string formattedXml = XmlUtil.FormatXmlElement(updatedXml, linePosition, indent, true); utilWriter.Write(formattedXml); // Copy remaining contents if (hasElement) { // Skip over the existing element while (reader.Depth > 0) { reader.Read(); } if (reader.IsEmptyElement || reader.NodeType == XmlNodeType.EndElement) { reader.Read(); } // Copy remainder of file while (xmlUtil.CopyXmlNode(utilWriter)) { } } } } }
private void WriteUnwrittenConfigDeclarationsRecursive(SectionUpdates declarationUpdates, XmlUtilWriter utilWriter, int linePosition, int indent, bool skipFirstIndent) { string[] unretrievedSectionNames = declarationUpdates.GetUnretrievedSectionNames(); if (unretrievedSectionNames != null) { foreach (string str in unretrievedSectionNames) { if (!skipFirstIndent) { utilWriter.AppendSpacesToLinePosition(linePosition); } skipFirstIndent = false; DeclarationUpdate declarationUpdate = declarationUpdates.GetDeclarationUpdate(str); if ((declarationUpdate != null) && !string.IsNullOrEmpty(declarationUpdate.UpdatedXml)) { utilWriter.Write(declarationUpdate.UpdatedXml); utilWriter.AppendNewLine(); } } } string[] unretrievedGroupNames = declarationUpdates.GetUnretrievedGroupNames(); if (unretrievedGroupNames != null) { foreach (string str2 in unretrievedGroupNames) { if (base.TargetFramework != null) { ConfigurationSectionGroup sectionGroup = this.GetSectionGroup(str2); if ((sectionGroup != null) && !sectionGroup.ShouldSerializeSectionGroupInTargetVersion(base.TargetFramework)) { declarationUpdates.MarkGroupAsRetrieved(str2); continue; } } if (!skipFirstIndent) { utilWriter.AppendSpacesToLinePosition(linePosition); } skipFirstIndent = false; SectionUpdates sectionUpdatesForGroup = declarationUpdates.GetSectionUpdatesForGroup(str2); DeclarationUpdate sectionGroupUpdate = sectionUpdatesForGroup.GetSectionGroupUpdate(); if (sectionGroupUpdate == null) { utilWriter.Write("<sectionGroup name=\"" + str2 + "\">"); } else { utilWriter.Write(sectionGroupUpdate.UpdatedXml); } utilWriter.AppendNewLine(); this.WriteUnwrittenConfigDeclarationsRecursive(sectionUpdatesForGroup, utilWriter, linePosition + indent, indent, false); utilWriter.AppendSpacesToLinePosition(linePosition); utilWriter.Write("</sectionGroup>\r\n"); } } }
private void CheckPreamble(byte[] preamble, XmlUtilWriter utilWriter, byte[] buffer) { bool hasByteOrderMark = false; using (Stream preambleStream = new MemoryStream(buffer)) { byte[] streamStart = new byte[preamble.Length]; if (preambleStream.Read(streamStart, 0, streamStart.Length) == streamStart.Length) { hasByteOrderMark = true; for (int i = 0; i < streamStart.Length; i++) { if (streamStart[i] != preamble[i]) { hasByteOrderMark = false; break; } } } } if (!hasByteOrderMark) { // Force the writer to emit byte order mark, then reset the stream // so that it is written over. object checkpoint = utilWriter.CreateStreamCheckpoint(); utilWriter.Write('x'); utilWriter.RestoreStreamCheckpoint(checkpoint); } }
// Format an Xml element to be written to the config file. // Params: // xmlElement - the element // linePosition - start position of the element // indent - indent for each depth // skipFirstIndent - skip indent for the first element? // static internal string FormatXmlElement(string xmlElement, int linePosition, int indent, bool skipFirstIndent) { XmlParserContext context = new XmlParserContext(null, null, null, XmlSpace.Default, Encoding.Unicode); XmlTextReader reader = new XmlTextReader(xmlElement, XmlNodeType.Element, context); StringWriter stringWriter = new StringWriter(new StringBuilder(64), CultureInfo.InvariantCulture); XmlUtilWriter utilWriter = new XmlUtilWriter(stringWriter, false); // append newline before indent? bool newLine = false; // last node visited was text? bool lastWasText = false; // width of line from end of indentation int lineWidth; // length of the stringbuilder after last indent with newline int sbLengthLastNewLine = 0; while (reader.Read()) { XmlNodeType nodeType = reader.NodeType; if (lastWasText) { utilWriter.Flush(); lineWidth = sbLengthLastNewLine - ((StringWriter)utilWriter.Writer).GetStringBuilder().Length; } else { lineWidth = 0; } switch (nodeType) { case XmlNodeType.CDATA: case XmlNodeType.Element: case XmlNodeType.EndElement: case XmlNodeType.Comment: // Do not indent if the last node was text - doing so would add whitespace // that is included as part of the text. if (!skipFirstIndent && !lastWasText) { utilWriter.AppendIndent(linePosition, indent, reader.Depth, newLine); if (newLine) { utilWriter.Flush(); sbLengthLastNewLine = ((StringWriter)utilWriter.Writer).GetStringBuilder().Length; } } break; default: break; } lastWasText = false; switch (nodeType) { case XmlNodeType.Whitespace: break; case XmlNodeType.SignificantWhitespace: utilWriter.Write(reader.Value); break; case XmlNodeType.CDATA: utilWriter.AppendCData(reader.Value); break; case XmlNodeType.ProcessingInstruction: utilWriter.AppendProcessingInstruction(reader.Name, reader.Value); break; case XmlNodeType.Comment: utilWriter.AppendComment(reader.Value); break; case XmlNodeType.Text: utilWriter.AppendEscapeTextString(reader.Value); lastWasText = true; break; case XmlNodeType.Element: { // Write "<elem" utilWriter.Write('<'); utilWriter.Write(reader.Name); lineWidth += reader.Name.Length + 2; int c = reader.AttributeCount; for (int i = 0; i < c; i++) { // Add new line if we've exceeded the line width bool writeSpace; if (lineWidth > MAX_LINE_WIDTH) { utilWriter.AppendIndent(linePosition, indent, reader.Depth - 1, true); lineWidth = indent; writeSpace = false; utilWriter.Flush(); sbLengthLastNewLine = ((StringWriter)utilWriter.Writer).GetStringBuilder().Length; } else { writeSpace = true; } // Write the attribute reader.MoveToNextAttribute(); utilWriter.Flush(); int startLength = ((StringWriter)utilWriter.Writer).GetStringBuilder().Length; if (writeSpace) { utilWriter.AppendSpace(); } utilWriter.Write(reader.Name); utilWriter.Write('='); utilWriter.AppendAttributeValue(reader); utilWriter.Flush(); lineWidth += ((StringWriter)utilWriter.Writer).GetStringBuilder().Length - startLength; } } // position reader back on element reader.MoveToElement(); // write closing tag if (reader.IsEmptyElement) { utilWriter.Write(" />"); } else { utilWriter.Write('>'); } break; case XmlNodeType.EndElement: utilWriter.Write("</"); utilWriter.Write(reader.Name); utilWriter.Write('>'); break; case XmlNodeType.EntityReference: utilWriter.AppendEntityRef(reader.Name); break; // Ignore <?xml and <!DOCTYPE nodes case XmlNodeType.XmlDeclaration: case XmlNodeType.DocumentType: default: break; } // put each new element on a new line newLine = true; // do not skip any more indents skipFirstIndent = false; } utilWriter.Flush(); string s = ((StringWriter)utilWriter.Writer).ToString(); return s; }
// // Copy or replace an element node. // If the element is an empty element, replace it with a formatted start element if either: // * The contents of the start element string need updating. // * The element needs to contain child elements. // // If the element is empty and is replaced with a start/end element pair, return a // end element string with whitespace formatting; otherwise return null. // internal string UpdateStartElement(XmlUtilWriter utilWriter, string updatedStartElement, bool needsChildren, int linePosition, int indent) { Debug.Assert(_reader.NodeType == XmlNodeType.Element, "_reader.NodeType == NodeType.Element"); string endElement = null; bool needsEndElement = false; string elementName; elementName = _reader.Name; // If the element is empty, determine if a new end element is needed. if (_reader.IsEmptyElement) { if (updatedStartElement == null && needsChildren) { updatedStartElement = RetrieveFullOpenElementTag(); } needsEndElement = (updatedStartElement != null); } if (updatedStartElement == null) { // // If no changes to the start element are required, just copy it. // CopyXmlNode(utilWriter); } else { // // Format a new start element/end element pair // string updatedEndElement = "</" + elementName + ">"; string updatedElement = updatedStartElement + updatedEndElement; string formattedElement = FormatXmlElement(updatedElement, linePosition, indent, true); // // Get the start and end element strings from the formatted element. // int iEndElement = formattedElement.LastIndexOf('\n') + 1; string startElement; if (needsEndElement) { endElement = formattedElement.Substring(iEndElement); // Include a newline in the start element as we are expanding an empty element. startElement = formattedElement.Substring(0, iEndElement); } else { // Omit the newline from the start element. startElement = formattedElement.Substring(0, iEndElement - 2); } // Write the new start element. utilWriter.Write(startElement); // Skip over the existing start element. _reader.Read(); } return endElement; }
private void CreateNewConfigSource(XmlUtilWriter utilWriter, string updatedXml, int indent) { string str = XmlUtil.FormatXmlElement(updatedXml, 0, indent, true); utilWriter.Write(string.Format(CultureInfo.InvariantCulture, "<?xml version=\"1.0\" encoding=\"{0}\"?>\r\n", new object[] { base.ConfigStreamInfo.StreamEncoding.WebName })); utilWriter.Write(str + "\r\n"); }
// Format an Xml element to be written to the config file. // Params: // xmlElement - the element // linePosition - start position of the element // indent - indent for each depth // skipFirstIndent - skip indent for the first element? // static internal string FormatXmlElement(string xmlElement, int linePosition, int indent, bool skipFirstIndent) { XmlParserContext context = new XmlParserContext(null, null, null, XmlSpace.Default, Encoding.Unicode); XmlTextReader reader = new XmlTextReader(xmlElement, XmlNodeType.Element, context); StringWriter stringWriter = new StringWriter(new StringBuilder(64), CultureInfo.InvariantCulture); XmlUtilWriter utilWriter = new XmlUtilWriter(stringWriter, false); // append newline before indent? bool newLine = false; // last node visited was text? bool lastWasText = false; // width of line from end of indentation int lineWidth; // length of the stringbuilder after last indent with newline int sbLengthLastNewLine = 0; while (reader.Read()) { XmlNodeType nodeType = reader.NodeType; if (lastWasText) { utilWriter.Flush(); lineWidth = sbLengthLastNewLine - ((StringWriter)utilWriter.Writer).GetStringBuilder().Length; } else { lineWidth = 0; } switch (nodeType) { case XmlNodeType.CDATA: case XmlNodeType.Element: case XmlNodeType.EndElement: case XmlNodeType.Comment: // Do not indent if the last node was text - doing so would add whitespace // that is included as part of the text. if (!skipFirstIndent && !lastWasText) { utilWriter.AppendIndent(linePosition, indent, reader.Depth, newLine); if (newLine) { utilWriter.Flush(); sbLengthLastNewLine = ((StringWriter)utilWriter.Writer).GetStringBuilder().Length; } } break; default: break; } lastWasText = false; switch (nodeType) { case XmlNodeType.Whitespace: break; case XmlNodeType.SignificantWhitespace: utilWriter.Write(reader.Value); break; case XmlNodeType.CDATA: utilWriter.AppendCData(reader.Value); break; case XmlNodeType.ProcessingInstruction: utilWriter.AppendProcessingInstruction(reader.Name, reader.Value); break; case XmlNodeType.Comment: utilWriter.AppendComment(reader.Value); break; case XmlNodeType.Text: utilWriter.AppendEscapeTextString(reader.Value); lastWasText = true; break; case XmlNodeType.Element: { // Write "<elem" utilWriter.Write('<'); utilWriter.Write(reader.Name); lineWidth += reader.Name.Length + 2; int c = reader.AttributeCount; for (int i = 0; i < c; i++) { // Add new line if we've exceeded the line width bool writeSpace; if (lineWidth > MAX_LINE_WIDTH) { utilWriter.AppendIndent(linePosition, indent, reader.Depth - 1, true); lineWidth = indent; writeSpace = false; utilWriter.Flush(); sbLengthLastNewLine = ((StringWriter)utilWriter.Writer).GetStringBuilder().Length; } else { writeSpace = true; } // Write the attribute reader.MoveToNextAttribute(); utilWriter.Flush(); int startLength = ((StringWriter)utilWriter.Writer).GetStringBuilder().Length; if (writeSpace) { utilWriter.AppendSpace(); } utilWriter.Write(reader.Name); utilWriter.Write('='); utilWriter.AppendAttributeValue(reader); utilWriter.Flush(); lineWidth += ((StringWriter)utilWriter.Writer).GetStringBuilder().Length - startLength; } } // position reader back on element reader.MoveToElement(); // write closing tag if (reader.IsEmptyElement) { utilWriter.Write(" />"); } else { utilWriter.Write('>'); } break; case XmlNodeType.EndElement: utilWriter.Write("</"); utilWriter.Write(reader.Name); utilWriter.Write('>'); break; case XmlNodeType.EntityReference: utilWriter.AppendEntityRef(reader.Name); break; // Ignore <?xml and <!DOCTYPE nodes case XmlNodeType.XmlDeclaration: case XmlNodeType.DocumentType: default: break; } // put each new element on a new line newLine = true; // do not skip any more indents skipFirstIndent = false; } utilWriter.Flush(); string s = ((StringWriter)utilWriter.Writer).ToString(); return(s); }
private void CopyConfigSource(XmlUtilWriter utilWriter, string updatedXml, string configSourceStreamName, byte[] buffer) { byte[] preamble; using (Stream stream = new MemoryStream(buffer)) { using (new XmlUtil(stream, configSourceStreamName, true)) { preamble = base.ConfigStreamInfo.StreamEncoding.GetPreamble(); } } this.CheckPreamble(preamble, utilWriter, buffer); using (Stream stream2 = new MemoryStream(buffer)) { using (XmlUtil util2 = new XmlUtil(stream2, configSourceStreamName, false)) { XmlTextReader reader = util2.Reader; reader.WhitespaceHandling = WhitespaceHandling.All; reader.Read(); int indent = 4; int linePosition = 1; bool flag = util2.CopyReaderToNextElement(utilWriter, false); if (flag) { int lineNumber = reader.LineNumber; linePosition = reader.LinePosition - 1; int num4 = 0; while (reader.MoveToNextAttribute()) { if (reader.LineNumber > lineNumber) { num4 = reader.LinePosition - linePosition; break; } } int num5 = 0; reader.Read(); while (reader.Depth >= 1) { if (reader.NodeType == XmlNodeType.Element) { num5 = (reader.LinePosition - 1) - linePosition; break; } reader.Read(); } if (num5 > 0) { indent = num5; } else if (num4 > 0) { indent = num4; } } string s = XmlUtil.FormatXmlElement(updatedXml, linePosition, indent, true); utilWriter.Write(s); if (flag) { while (reader.Depth > 0) { reader.Read(); } if (reader.IsEmptyElement || (reader.NodeType == XmlNodeType.EndElement)) { reader.Read(); } while (util2.CopyXmlNode(utilWriter)) { } } } } }
private void CreateNewConfig(SectionUpdates declarationUpdates, ConfigDefinitionUpdates definitionUpdates, NamespaceChange namespaceChange, XmlUtilWriter utilWriter) { int linePosition = 5; int indent = 4; utilWriter.Write(string.Format(CultureInfo.InvariantCulture, "<?xml version=\"1.0\" encoding=\"{0}\"?>\r\n", new object[] { base.ConfigStreamInfo.StreamEncoding.WebName })); if (namespaceChange == NamespaceChange.Add) { utilWriter.Write(string.Format(CultureInfo.InvariantCulture, "<configuration xmlns=\"{0}\">\r\n", new object[] { "http://schemas.microsoft.com/.NetConfiguration/v2.0" })); } else { utilWriter.Write("<configuration>\r\n"); } if (declarationUpdates != null) { this.WriteNewConfigDeclarations(declarationUpdates, utilWriter, linePosition, indent, false); } this.WriteNewConfigDefinitions(definitionUpdates, utilWriter, linePosition, indent); utilWriter.Write("</configuration>"); }
private bool CopyConfigDeclarationsRecursive(SectionUpdates declarationUpdates, XmlUtil xmlUtil, XmlUtilWriter utilWriter, string group, int parentLinePosition, int parentIndent) { int trueLinePosition; int num3; bool flag = false; XmlTextReader reader = xmlUtil.Reader; int oldIndent = this.UpdateIndent(parentIndent, xmlUtil, utilWriter, parentLinePosition); if (reader.NodeType == XmlNodeType.Element) { trueLinePosition = xmlUtil.TrueLinePosition; num3 = trueLinePosition; } else if (reader.NodeType == XmlNodeType.EndElement) { trueLinePosition = parentLinePosition + oldIndent; if (utilWriter.IsLastLineBlank) { num3 = xmlUtil.TrueLinePosition; } else { num3 = parentLinePosition; } } else { trueLinePosition = parentLinePosition + oldIndent; num3 = 0; } if (declarationUpdates != null) { string[] movedSectionNames = declarationUpdates.GetMovedSectionNames(); if (movedSectionNames != null) { if (!utilWriter.IsLastLineBlank) { utilWriter.AppendNewLine(); } foreach (string str in movedSectionNames) { DeclarationUpdate declarationUpdate = declarationUpdates.GetDeclarationUpdate(str); utilWriter.AppendSpacesToLinePosition(trueLinePosition); utilWriter.Write(declarationUpdate.UpdatedXml); utilWriter.AppendNewLine(); flag = true; } utilWriter.AppendSpacesToLinePosition(num3); } } if (reader.NodeType == XmlNodeType.Element) { int depth = reader.Depth; while (reader.Depth == depth) { bool flag2 = false; DeclarationUpdate update2 = null; DeclarationUpdate sectionGroupUpdate = null; SectionUpdates sectionUpdatesForGroup = null; SectionUpdates updates2 = declarationUpdates; string str2 = group; oldIndent = this.UpdateIndent(oldIndent, xmlUtil, utilWriter, parentLinePosition); trueLinePosition = xmlUtil.TrueLinePosition; string name = reader.Name; string attribute = reader.GetAttribute("name"); string configKey = BaseConfigurationRecord.CombineConfigKey(group, attribute); if (name == "sectionGroup") { sectionUpdatesForGroup = declarationUpdates.GetSectionUpdatesForGroup(attribute); if (sectionUpdatesForGroup != null) { sectionGroupUpdate = sectionUpdatesForGroup.GetSectionGroupUpdate(); if (sectionUpdatesForGroup.HasUnretrievedSections()) { flag2 = true; str2 = configKey; updates2 = sectionUpdatesForGroup; } } } else { update2 = declarationUpdates.GetDeclarationUpdate(configKey); } bool flag3 = (sectionGroupUpdate != null) && (sectionGroupUpdate.UpdatedXml != null); if (flag2) { object o = utilWriter.CreateStreamCheckpoint(); string s = null; if (flag3) { utilWriter.Write(sectionGroupUpdate.UpdatedXml); reader.Read(); } else { s = xmlUtil.UpdateStartElement(utilWriter, null, true, trueLinePosition, oldIndent); } if (s == null) { xmlUtil.CopyReaderToNextElement(utilWriter, true); } bool flag4 = this.CopyConfigDeclarationsRecursive(updates2, xmlUtil, utilWriter, str2, trueLinePosition, oldIndent); if (s != null) { utilWriter.AppendSpacesToLinePosition(trueLinePosition); utilWriter.Write(s); utilWriter.AppendSpacesToLinePosition(parentLinePosition); } else { xmlUtil.CopyXmlNode(utilWriter); } if (flag4 || flag3) { flag = true; } else { utilWriter.RestoreStreamCheckpoint(o); } xmlUtil.CopyReaderToNextElement(utilWriter, true); } else { bool flag5; bool flag6 = false; if (update2 == null) { flag5 = true; if (flag3) { flag = true; utilWriter.Write(sectionGroupUpdate.UpdatedXml); utilWriter.AppendNewLine(); utilWriter.AppendSpacesToLinePosition(trueLinePosition); utilWriter.Write("</sectionGroup>"); utilWriter.AppendNewLine(); utilWriter.AppendSpacesToLinePosition(trueLinePosition); } else if (sectionGroupUpdate != null) { flag = true; flag5 = false; flag6 = true; } } else { flag = true; if (update2.UpdatedXml == null) { flag5 = false; } else { flag5 = true; utilWriter.Write(update2.UpdatedXml); } } if (flag5) { xmlUtil.SkipAndCopyReaderToNextElement(utilWriter, true); } else { if (flag6) { xmlUtil.SkipChildElementsAndCopyOuterXmlToNextElement(utilWriter); continue; } xmlUtil.CopyOuterXmlToNextElement(utilWriter, true); } } } } return flag; }
private void CopyConfig(SectionUpdates declarationUpdates, ConfigDefinitionUpdates definitionUpdates, byte[] buffer, string filename, NamespaceChange namespaceChange, XmlUtilWriter utilWriter) { this.CheckPreamble(base.ConfigStreamInfo.StreamEncoding.GetPreamble(), utilWriter, buffer); using (Stream stream = new MemoryStream(buffer)) { using (XmlUtil util = new XmlUtil(stream, filename, false)) { string str; XmlTextReader reader = util.Reader; reader.WhitespaceHandling = WhitespaceHandling.All; reader.Read(); util.CopyReaderToNextElement(utilWriter, false); int indent = 4; int trueLinePosition = util.TrueLinePosition; bool isEmptyElement = reader.IsEmptyElement; if (namespaceChange == NamespaceChange.Add) { str = string.Format(CultureInfo.InvariantCulture, "<configuration xmlns=\"{0}\">\r\n", new object[] { "http://schemas.microsoft.com/.NetConfiguration/v2.0" }); } else if (namespaceChange == NamespaceChange.Remove) { str = "<configuration>\r\n"; } else { str = null; } bool needsChildren = (declarationUpdates != null) || (definitionUpdates != null); string s = util.UpdateStartElement(utilWriter, str, needsChildren, trueLinePosition, indent); bool flag3 = false; if (!isEmptyElement) { util.CopyReaderToNextElement(utilWriter, true); indent = this.UpdateIndent(indent, util, utilWriter, trueLinePosition); if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "configSections")) { flag3 = true; int linePosition = util.TrueLinePosition; bool flag4 = reader.IsEmptyElement; if (declarationUpdates == null) { util.CopyOuterXmlToNextElement(utilWriter, true); } else { string str3 = util.UpdateStartElement(utilWriter, null, true, linePosition, indent); if (!flag4) { util.CopyReaderToNextElement(utilWriter, true); this.CopyConfigDeclarationsRecursive(declarationUpdates, util, utilWriter, string.Empty, linePosition, indent); } if (declarationUpdates.HasUnretrievedSections()) { int num4 = 0; if (str3 == null) { num4 = util.TrueLinePosition; } if (!utilWriter.IsLastLineBlank) { utilWriter.AppendNewLine(); } this.WriteUnwrittenConfigDeclarations(declarationUpdates, utilWriter, linePosition + indent, indent, false); if (str3 == null) { utilWriter.AppendSpacesToLinePosition(num4); } } if (str3 == null) { util.CopyXmlNode(utilWriter); } else { utilWriter.Write(str3); } util.CopyReaderToNextElement(utilWriter, true); } } } if (!flag3 && (declarationUpdates != null)) { int num5; bool skipFirstIndent = (reader.Depth > 0) && (reader.NodeType == XmlNodeType.Element); if (skipFirstIndent) { num5 = util.TrueLinePosition; } else { num5 = trueLinePosition + indent; } this.WriteNewConfigDeclarations(declarationUpdates, utilWriter, num5, indent, skipFirstIndent); } if (definitionUpdates != null) { bool locationPathApplies = false; LocationUpdates locationUpdates = null; SectionUpdates sectionUpdates = null; if (!base.IsLocationConfig) { locationPathApplies = true; locationUpdates = definitionUpdates.FindLocationUpdates(OverrideModeSetting.LocationDefault, true); if (locationUpdates != null) { sectionUpdates = locationUpdates.SectionUpdates; } } this.CopyConfigDefinitionsRecursive(definitionUpdates, util, utilWriter, locationPathApplies, locationUpdates, sectionUpdates, true, string.Empty, trueLinePosition, indent); this.WriteNewConfigDefinitions(definitionUpdates, utilWriter, trueLinePosition + indent, indent); } if (s != null) { if (!utilWriter.IsLastLineBlank) { utilWriter.AppendNewLine(); } utilWriter.Write(s); } while (util.CopyXmlNode(utilWriter)) { } } } }
private void CheckPreamble(byte[] preamble, XmlUtilWriter utilWriter, byte[] buffer) { bool flag = false; using (Stream stream = new MemoryStream(buffer)) { byte[] buffer2 = new byte[preamble.Length]; if (stream.Read(buffer2, 0, buffer2.Length) == buffer2.Length) { flag = true; for (int i = 0; i < buffer2.Length; i++) { if (buffer2[i] != preamble[i]) { flag = false; goto Label_004A; } } } } Label_004A: if (!flag) { object o = utilWriter.CreateStreamCheckpoint(); utilWriter.Write('x'); utilWriter.RestoreStreamCheckpoint(o); } }
private bool WriteNewConfigDefinitionsRecursive(XmlUtilWriter utilWriter, SectionUpdates sectionUpdates, int linePosition, int indent, bool skipFirstIndent) { bool flag = false; string[] movedSectionNames = sectionUpdates.GetMovedSectionNames(); if (movedSectionNames != null) { flag = true; foreach (string str in movedSectionNames) { DefinitionUpdate definitionUpdate = sectionUpdates.GetDefinitionUpdate(str); this.WriteSectionUpdate(utilWriter, definitionUpdate, linePosition, indent, skipFirstIndent); utilWriter.AppendNewLine(); skipFirstIndent = false; } } string[] newGroupNames = sectionUpdates.GetNewGroupNames(); if (newGroupNames != null) { foreach (string str2 in newGroupNames) { if (base.TargetFramework != null) { ConfigurationSectionGroup sectionGroup = this.GetSectionGroup(str2); if ((sectionGroup != null) && !sectionGroup.ShouldSerializeSectionGroupInTargetVersion(base.TargetFramework)) { sectionUpdates.MarkGroupAsRetrieved(str2); continue; } } if (!skipFirstIndent) { utilWriter.AppendSpacesToLinePosition(linePosition); } skipFirstIndent = false; utilWriter.Write("<" + str2 + ">\r\n"); if (this.WriteNewConfigDefinitionsRecursive(utilWriter, sectionUpdates.GetSectionUpdatesForGroup(str2), linePosition + indent, indent, false)) { flag = true; } utilWriter.AppendSpacesToLinePosition(linePosition); utilWriter.Write("</" + str2 + ">\r\n"); } } sectionUpdates.IsNew = false; return flag; }
internal bool CopyXmlNode(XmlUtilWriter utilWriter) { string s = null; int fromLineNumber = -1; int fromLinePosition = -1; int lineNumber = 0; int linePosition = 0; int num5 = 0; int num6 = 0; if (utilWriter.TrackPosition) { lineNumber = this._reader.LineNumber; linePosition = this._reader.LinePosition; num5 = utilWriter.LineNumber; num6 = utilWriter.LinePosition; } XmlNodeType nodeType = this._reader.NodeType; switch (nodeType) { case XmlNodeType.Whitespace: utilWriter.Write(this._reader.Value); break; case XmlNodeType.Element: s = this._reader.IsEmptyElement ? "/>" : ">"; fromLineNumber = this._reader.LineNumber; fromLinePosition = this._reader.LinePosition + this._reader.Name.Length; utilWriter.Write('<'); utilWriter.Write(this._reader.Name); while (this._reader.MoveToNextAttribute()) { int toLineNumber = this._reader.LineNumber; int toLinePosition = this._reader.LinePosition; utilWriter.AppendRequiredWhiteSpace(fromLineNumber, fromLinePosition, toLineNumber, toLinePosition); int num9 = utilWriter.Write(this._reader.Name) + utilWriter.Write('='); num9 += utilWriter.AppendAttributeValue(this._reader); fromLineNumber = toLineNumber; fromLinePosition = toLinePosition + num9; } break; case XmlNodeType.EndElement: s = ">"; fromLineNumber = this._reader.LineNumber; fromLinePosition = this._reader.LinePosition + this._reader.Name.Length; utilWriter.Write("</"); utilWriter.Write(this._reader.Name); break; case XmlNodeType.Comment: utilWriter.AppendComment(this._reader.Value); break; case XmlNodeType.Text: utilWriter.AppendEscapeTextString(this._reader.Value); break; case XmlNodeType.XmlDeclaration: s = "?>"; fromLineNumber = this._reader.LineNumber; fromLinePosition = this._reader.LinePosition + 3; utilWriter.Write("<?xml"); while (this._reader.MoveToNextAttribute()) { int num10 = this._reader.LineNumber; int num11 = this._reader.LinePosition; utilWriter.AppendRequiredWhiteSpace(fromLineNumber, fromLinePosition, num10, num11); int num12 = utilWriter.Write(this._reader.Name) + utilWriter.Write('='); num12 += utilWriter.AppendAttributeValue(this._reader); fromLineNumber = num10; fromLinePosition = num11 + num12; } this._reader.MoveToElement(); break; case XmlNodeType.SignificantWhitespace: utilWriter.Write(this._reader.Value); break; case XmlNodeType.ProcessingInstruction: utilWriter.AppendProcessingInstruction(this._reader.Name, this._reader.Value); break; case XmlNodeType.EntityReference: utilWriter.AppendEntityRef(this._reader.Name); break; case XmlNodeType.CDATA: utilWriter.AppendCData(this._reader.Value); break; default: if (nodeType == XmlNodeType.DocumentType) { int num13 = utilWriter.Write("<!DOCTYPE"); utilWriter.AppendRequiredWhiteSpace(this._lastLineNumber, this._lastLinePosition + num13, this._reader.LineNumber, this._reader.LinePosition); utilWriter.Write(this._reader.Name); string str2 = null; if (this._reader.HasValue) { str2 = this._reader.Value; } fromLineNumber = this._reader.LineNumber; fromLinePosition = this._reader.LinePosition + this._reader.Name.Length; if (this._reader.MoveToFirstAttribute()) { utilWriter.AppendRequiredWhiteSpace(fromLineNumber, fromLinePosition, this._reader.LineNumber, this._reader.LinePosition); string name = this._reader.Name; utilWriter.Write(name); utilWriter.AppendSpace(); utilWriter.AppendAttributeValue(this._reader); this._reader.MoveToAttribute(0); if (name == "PUBLIC") { this._reader.MoveToAttribute(1); utilWriter.AppendSpace(); utilWriter.AppendAttributeValue(this._reader); this._reader.MoveToAttribute(1); } } if ((str2 != null) && (str2.Length > 0)) { utilWriter.Write(" ["); utilWriter.Write(str2); utilWriter.Write(']'); } utilWriter.Write('>'); } break; } bool flag = this._reader.Read(); nodeType = this._reader.NodeType; if (s != null) { int positionOffset = GetPositionOffset(nodeType); int num15 = this._reader.LineNumber; int num16 = (this._reader.LinePosition - positionOffset) - s.Length; utilWriter.AppendWhiteSpace(fromLineNumber, fromLinePosition, num15, num16); utilWriter.Write(s); } if (utilWriter.TrackPosition) { this._lastLineNumber = (lineNumber - num5) + utilWriter.LineNumber; if (num5 == utilWriter.LineNumber) { this._lastLinePosition = (linePosition - num6) + utilWriter.LinePosition; return(flag); } this._lastLinePosition = utilWriter.LinePosition; } return(flag); }
private void CreateNewConfigSource(XmlUtilWriter utilWriter, string updatedXml, int indent) { string formattedXml = XmlUtil.FormatXmlElement(updatedXml, 0, indent, true); utilWriter.Write(string.Format(CultureInfo.InvariantCulture, FormatConfigsourceFile, ConfigStreamInfo.StreamEncoding.WebName)); utilWriter.Write(formattedXml + NewLine); }
internal static string FormatXmlElement(string xmlElement, int linePosition, int indent, bool skipFirstIndent) { XmlParserContext context = new XmlParserContext(null, null, null, XmlSpace.Default, Encoding.Unicode); XmlTextReader reader = new XmlTextReader(xmlElement, XmlNodeType.Element, context); StringWriter writer = new StringWriter(new StringBuilder(0x40), CultureInfo.InvariantCulture); XmlUtilWriter writer2 = new XmlUtilWriter(writer, false); bool newLine = false; bool flag2 = false; int num2 = 0; while (reader.Read()) { int num; int attributeCount; int num4; bool flag3; XmlNodeType nodeType = reader.NodeType; if (flag2) { writer2.Flush(); num = num2 - ((StringWriter)writer2.Writer).GetStringBuilder().Length; } else { num = 0; } XmlNodeType type2 = nodeType; if (type2 <= XmlNodeType.CDATA) { switch (type2) { case XmlNodeType.Element: case XmlNodeType.CDATA: goto Label_0091; } goto Label_00CA; } if ((type2 != XmlNodeType.Comment) && (type2 != XmlNodeType.EndElement)) { goto Label_00CA; } Label_0091: if (!skipFirstIndent && !flag2) { writer2.AppendIndent(linePosition, indent, reader.Depth, newLine); if (newLine) { writer2.Flush(); num2 = ((StringWriter)writer2.Writer).GetStringBuilder().Length; } } Label_00CA: flag2 = false; switch (nodeType) { case XmlNodeType.Element: writer2.Write('<'); writer2.Write(reader.Name); num += reader.Name.Length + 2; attributeCount = reader.AttributeCount; num4 = 0; goto Label_0274; case XmlNodeType.Text: writer2.AppendEscapeTextString(reader.Value); flag2 = true; goto Label_02D6; case XmlNodeType.CDATA: writer2.AppendCData(reader.Value); goto Label_02D6; case XmlNodeType.EntityReference: writer2.AppendEntityRef(reader.Name); goto Label_02D6; case XmlNodeType.ProcessingInstruction: writer2.AppendProcessingInstruction(reader.Name, reader.Value); goto Label_02D6; case XmlNodeType.Comment: writer2.AppendComment(reader.Value); goto Label_02D6; case XmlNodeType.SignificantWhitespace: writer2.Write(reader.Value); goto Label_02D6; case XmlNodeType.EndElement: writer2.Write("</"); writer2.Write(reader.Name); writer2.Write('>'); goto Label_02D6; default: goto Label_02D6; } Label_01BE: if (num > 60) { writer2.AppendIndent(linePosition, indent, reader.Depth - 1, true); num = indent; flag3 = false; writer2.Flush(); num2 = ((StringWriter)writer2.Writer).GetStringBuilder().Length; } else { flag3 = true; } reader.MoveToNextAttribute(); writer2.Flush(); int length = ((StringWriter)writer2.Writer).GetStringBuilder().Length; if (flag3) { writer2.AppendSpace(); } writer2.Write(reader.Name); writer2.Write('='); writer2.AppendAttributeValue(reader); writer2.Flush(); num += ((StringWriter)writer2.Writer).GetStringBuilder().Length - length; num4++; Label_0274: if (num4 < attributeCount) { goto Label_01BE; } reader.MoveToElement(); if (reader.IsEmptyElement) { writer2.Write(" />"); } else { writer2.Write('>'); } Label_02D6: newLine = true; skipFirstIndent = false; } writer2.Flush(); return(((StringWriter)writer2.Writer).ToString()); }
// // Copy a single XML node, attempting to preserve whitespace. // A side effect of this method is to advance the reader to the next node. // // PERFORMANCE NOTE: this function is used at runtime to copy a configuration section, // and at designtime to copy an entire XML document. // // At designtime, this function needs to be able to copy a <!DOCTYPE declaration. // Copying a <!DOCTYPE declaration is expensive, because due to limitations of the // XmlReader API, we must track the position of the writer to accurately format it. // Tracking the position of the writer is expensive, as it requires examining every // character that is written for newline characters, and maintaining the seek position // of the underlying stream at each new line, which in turn requires a stream flush. // // This function must NEVER require tracking the writer position to copy the Xml nodes // that are used in a configuration section. // internal bool CopyXmlNode(XmlUtilWriter utilWriter) { // // For nodes that have a closing string, such as "<element >" // the XmlReader API does not give us the location of the closing string, e.g. ">". // To correctly determine the location of the closing part, we advance the reader, // determine the position of the next node, then work backwards to add whitespace // and add the closing string. // string close = null; int lineNumber = -1; int linePosition = -1; int readerLineNumber = 0; int readerLinePosition = 0; int writerLineNumber = 0; int writerLinePosition = 0; if (utilWriter.TrackPosition) { readerLineNumber = _reader.LineNumber; readerLinePosition = _reader.LinePosition; writerLineNumber = utilWriter.LineNumber; writerLinePosition = utilWriter.LinePosition; } // We test the node type in the likely order of decreasing occurrence. XmlNodeType nodeType = _reader.NodeType; if (nodeType == XmlNodeType.Whitespace) { utilWriter.Write(_reader.Value); } else if (nodeType == XmlNodeType.Element) { close = (_reader.IsEmptyElement) ? "/>" : ">"; // get the line position after the element declaration: // <element attr="value" // ^ // linePosition // lineNumber = _reader.LineNumber; linePosition = _reader.LinePosition + _reader.Name.Length; utilWriter.Write('<'); utilWriter.Write(_reader.Name); // // Note that there is no way to get spacing between attribute name and value // For example: // // <elem attr="value" /> // // is reported with the same position as // // <elem attr = "value" /> // // The first example has no spaces around '=', the second example does. // while (_reader.MoveToNextAttribute()) { // get line position of the attribute declaration // <element attr="value" // ^ // attrLinePosition // int attrLineNumber = _reader.LineNumber; int attrLinePosition = _reader.LinePosition; // Write the whitespace before the attribute utilWriter.AppendRequiredWhiteSpace(lineNumber, linePosition, attrLineNumber, attrLinePosition); // Write the attribute and value int charactersWritten = utilWriter.Write(_reader.Name); charactersWritten += utilWriter.Write('='); charactersWritten += utilWriter.AppendAttributeValue(_reader); // Update position. Note that the attribute value is escaped to always be on a single line. lineNumber = attrLineNumber; linePosition = attrLinePosition + charactersWritten; } } else if (nodeType == XmlNodeType.EndElement) { close = ">"; // get line position after the end element declaration: // </element > // ^ // linePosition // lineNumber = _reader.LineNumber; linePosition = _reader.LinePosition + _reader.Name.Length; utilWriter.Write("</"); utilWriter.Write(_reader.Name); } else if (nodeType == XmlNodeType.Comment) { utilWriter.AppendComment(_reader.Value); } else if (nodeType == XmlNodeType.Text) { utilWriter.AppendEscapeTextString(_reader.Value); } else if (nodeType == XmlNodeType.XmlDeclaration) { close = "?>"; // get line position after the xml declaration: // <?xml version="1.0" // ^ // linePosition // lineNumber = _reader.LineNumber; linePosition = _reader.LinePosition + 3; utilWriter.Write("<?xml"); // // Note that there is no way to get spacing between attribute name and value // For example: // // <?xml attr="value" ?> // // is reported with the same position as // // <?xml attr = "value" ?> // // The first example has no spaces around '=', the second example does. // while (_reader.MoveToNextAttribute()) { // get line position of the attribute declaration // <?xml version="1.0" // ^ // attrLinePosition // int attrLineNumber = _reader.LineNumber; int attrLinePosition = _reader.LinePosition; // Write the whitespace before the attribute utilWriter.AppendRequiredWhiteSpace(lineNumber, linePosition, attrLineNumber, attrLinePosition); // Write the attribute and value int charactersWritten = utilWriter.Write(_reader.Name); charactersWritten += utilWriter.Write('='); charactersWritten += utilWriter.AppendAttributeValue(_reader); // Update position. Note that the attribute value is escaped to always be on a single line. lineNumber = attrLineNumber; linePosition = attrLinePosition + charactersWritten; } // Position reader at beginning of node _reader.MoveToElement(); } else if (nodeType == XmlNodeType.SignificantWhitespace) { utilWriter.Write(_reader.Value); } else if (nodeType == XmlNodeType.ProcessingInstruction) { // // Note that there is no way to get spacing between attribute name and value // For example: // // <?pi "value" ?> // // is reported with the same position as // // <?pi "value" ?> // // The first example has one space between 'pi' and "value", the second has multiple spaces. // utilWriter.AppendProcessingInstruction(_reader.Name, _reader.Value); } else if (nodeType == XmlNodeType.EntityReference) { utilWriter.AppendEntityRef(_reader.Name); } else if (nodeType == XmlNodeType.CDATA) { utilWriter.AppendCData(_reader.Value); } else if (nodeType == XmlNodeType.DocumentType) { // // XmlNodeType.DocumentType has the following format: // // <!DOCTYPE rootElementName {(SYSTEM uriRef)|(PUBLIC id uriRef)} {[ dtdDecls ]} > // // The reader only gives us the position of 'rootElementName', so we must track what was // written before "<!DOCTYPE" in order to correctly determine the position of the // <!DOCTYPE tag // Debug.Assert(utilWriter.TrackPosition, "utilWriter.TrackPosition"); int c = utilWriter.Write("<!DOCTYPE"); // Write the space between <!DOCTYPE and the rootElementName utilWriter.AppendRequiredWhiteSpace(_lastLineNumber, _lastLinePosition + c, _reader.LineNumber, _reader.LinePosition); // Write the rootElementName utilWriter.Write(_reader.Name); // Get the dtd declarations, if any string dtdValue = null; if (_reader.HasValue) { dtdValue = _reader.Value; } // get line position after the !DOCTYPE declaration: // <!DOCTYPE rootElement SYSTEM rootElementDtdUri > // ^ // linePosition lineNumber = _reader.LineNumber; linePosition = _reader.LinePosition + _reader.Name.Length; // Note that there is no way to get the spacing after PUBLIC or SYSTEM attributes and their values if (_reader.MoveToFirstAttribute()) { // Write the space before SYSTEM or PUBLIC utilWriter.AppendRequiredWhiteSpace(lineNumber, linePosition, _reader.LineNumber, _reader.LinePosition); // Write SYSTEM or PUBLIC and the 1st value of the attribute string attrName = _reader.Name; utilWriter.Write(attrName); utilWriter.AppendSpace(); utilWriter.AppendAttributeValue(_reader); _reader.MoveToAttribute(0); // If PUBLIC, write the second value of the attribute if (attrName == "PUBLIC") { _reader.MoveToAttribute(1); utilWriter.AppendSpace(); utilWriter.AppendAttributeValue(_reader); _reader.MoveToAttribute(1); } } // If there is a dtd, write it if (dtdValue != null && dtdValue.Length > 0) { utilWriter.Write(" ["); utilWriter.Write(dtdValue); utilWriter.Write(']'); } utilWriter.Write('>'); } // Advance the _reader so we can get the position of the next node. bool moreToRead = _reader.Read(); nodeType = _reader.NodeType; // Close the node we are copying. if (close != null) { // // Find the position of the close string, for example: // // <element > <subElement /> // ^ // closeLinePosition // int startOffset = GetPositionOffset(nodeType); int closeLineNumber = _reader.LineNumber; int closeLinePosition = _reader.LinePosition - startOffset - close.Length; // Add whitespace up to the position of the close string utilWriter.AppendWhiteSpace(lineNumber, linePosition, closeLineNumber, closeLinePosition); // Write the close string utilWriter.Write(close); } // // Track the position of the reader based on the position of the reader // before we copied this node and what we have written in copying the node. // This allows us to determine the position of the <!DOCTYPE tag. // if (utilWriter.TrackPosition) { _lastLineNumber = (readerLineNumber - writerLineNumber) + utilWriter.LineNumber; if (writerLineNumber == utilWriter.LineNumber) { _lastLinePosition = (readerLinePosition - writerLinePosition) + utilWriter.LinePosition; } else { _lastLinePosition = utilWriter.LinePosition; } } return(moreToRead); }
private void WriteNewConfigDeclarations(SectionUpdates declarationUpdates, XmlUtilWriter utilWriter, int linePosition, int indent, bool skipFirstIndent) { if (!skipFirstIndent) { utilWriter.AppendSpacesToLinePosition(linePosition); } utilWriter.Write("<configSections>\r\n"); WriteUnwrittenConfigDeclarations(declarationUpdates, utilWriter, linePosition + indent, indent, false); utilWriter.AppendSpacesToLinePosition(linePosition); utilWriter.Write("</configSections>\r\n"); if (skipFirstIndent) { utilWriter.AppendSpacesToLinePosition(linePosition); } }
// // Copy a single XML node, attempting to preserve whitespace. // A side effect of this method is to advance the reader to the next node. // // PERFORMANCE NOTE: this function is used at runtime to copy a configuration section, // and at designtime to copy an entire XML document. // // At designtime, this function needs to be able to copy a <!DOCTYPE declaration. // Copying a <!DOCTYPE declaration is expensive, because due to limitations of the // XmlReader API, we must track the position of the writer to accurately format it. // Tracking the position of the writer is expensive, as it requires examining every // character that is written for newline characters, and maintaining the seek position // of the underlying stream at each new line, which in turn requires a stream flush. // // This function must NEVER require tracking the writer position to copy the Xml nodes // that are used in a configuration section. // internal bool CopyXmlNode(XmlUtilWriter utilWriter) { // // For nodes that have a closing string, such as "<element >" // the XmlReader API does not give us the location of the closing string, e.g. ">". // To correctly determine the location of the closing part, we advance the reader, // determine the position of the next node, then work backwards to add whitespace // and add the closing string. // string close = null; int lineNumber = -1; int linePosition = -1; int readerLineNumber = 0; int readerLinePosition = 0; int writerLineNumber = 0; int writerLinePosition = 0; if (utilWriter.TrackPosition) { readerLineNumber = _reader.LineNumber; readerLinePosition = _reader.LinePosition; writerLineNumber = utilWriter.LineNumber; writerLinePosition = utilWriter.LinePosition; } // We test the node type in the likely order of decreasing occurrence. XmlNodeType nodeType = _reader.NodeType; if (nodeType == XmlNodeType.Whitespace) { utilWriter.Write(_reader.Value); } else if (nodeType == XmlNodeType.Element) { close = (_reader.IsEmptyElement) ? "/>" : ">"; // get the line position after the element declaration: // <element attr="value" // ^ // linePosition // lineNumber = _reader.LineNumber; linePosition = _reader.LinePosition + _reader.Name.Length; utilWriter.Write('<'); utilWriter.Write(_reader.Name); // // Note that there is no way to get spacing between attribute name and value // For example: // // <elem attr="value" /> // // is reported with the same position as // // <elem attr = "value" /> // // The first example has no spaces around '=', the second example does. // while (_reader.MoveToNextAttribute()) { // get line position of the attribute declaration // <element attr="value" // ^ // attrLinePosition // int attrLineNumber = _reader.LineNumber; int attrLinePosition = _reader.LinePosition; // Write the whitespace before the attribute utilWriter.AppendRequiredWhiteSpace(lineNumber, linePosition, attrLineNumber, attrLinePosition); // Write the attribute and value int charactersWritten = utilWriter.Write(_reader.Name); charactersWritten += utilWriter.Write('='); charactersWritten += utilWriter.AppendAttributeValue(_reader); // Update position. Note that the attribute value is escaped to always be on a single line. lineNumber = attrLineNumber; linePosition = attrLinePosition + charactersWritten; } } else if (nodeType == XmlNodeType.EndElement) { close = ">"; // get line position after the end element declaration: // </element > // ^ // linePosition // lineNumber = _reader.LineNumber; linePosition = _reader.LinePosition + _reader.Name.Length; utilWriter.Write("</"); utilWriter.Write(_reader.Name); } else if (nodeType == XmlNodeType.Comment) { utilWriter.AppendComment(_reader.Value); } else if (nodeType == XmlNodeType.Text) { utilWriter.AppendEscapeTextString(_reader.Value); } else if (nodeType == XmlNodeType.XmlDeclaration) { close = "?>"; // get line position after the xml declaration: // <?xml version="1.0" // ^ // linePosition // lineNumber = _reader.LineNumber; linePosition = _reader.LinePosition + 3; utilWriter.Write("<?xml"); // // Note that there is no way to get spacing between attribute name and value // For example: // // <?xml attr="value" ?> // // is reported with the same position as // // <?xml attr = "value" ?> // // The first example has no spaces around '=', the second example does. // while (_reader.MoveToNextAttribute()) { // get line position of the attribute declaration // <?xml version="1.0" // ^ // attrLinePosition // int attrLineNumber = _reader.LineNumber; int attrLinePosition = _reader.LinePosition; // Write the whitespace before the attribute utilWriter.AppendRequiredWhiteSpace(lineNumber, linePosition, attrLineNumber, attrLinePosition); // Write the attribute and value int charactersWritten = utilWriter.Write(_reader.Name); charactersWritten += utilWriter.Write('='); charactersWritten += utilWriter.AppendAttributeValue(_reader); // Update position. Note that the attribute value is escaped to always be on a single line. lineNumber = attrLineNumber; linePosition = attrLinePosition + charactersWritten; } // Position reader at beginning of node _reader.MoveToElement(); } else if (nodeType == XmlNodeType.SignificantWhitespace) { utilWriter.Write(_reader.Value); } else if (nodeType == XmlNodeType.ProcessingInstruction) { // // Note that there is no way to get spacing between attribute name and value // For example: // // <?pi "value" ?> // // is reported with the same position as // // <?pi "value" ?> // // The first example has one space between 'pi' and "value", the second has multiple spaces. // utilWriter.AppendProcessingInstruction(_reader.Name, _reader.Value); } else if (nodeType == XmlNodeType.EntityReference) { utilWriter.AppendEntityRef(_reader.Name); } else if (nodeType == XmlNodeType.CDATA) { utilWriter.AppendCData(_reader.Value); } else if (nodeType == XmlNodeType.DocumentType) { // // XmlNodeType.DocumentType has the following format: // // <!DOCTYPE rootElementName {(SYSTEM uriRef)|(PUBLIC id uriRef)} {[ dtdDecls ]} > // // The reader only gives us the position of 'rootElementName', so we must track what was // written before "<!DOCTYPE" in order to correctly determine the position of the // <!DOCTYPE tag // Debug.Assert(utilWriter.TrackPosition, "utilWriter.TrackPosition"); int c = utilWriter.Write("<!DOCTYPE"); // Write the space between <!DOCTYPE and the rootElementName utilWriter.AppendRequiredWhiteSpace(_lastLineNumber, _lastLinePosition + c, _reader.LineNumber, _reader.LinePosition); // Write the rootElementName utilWriter.Write(_reader.Name); // Get the dtd declarations, if any string dtdValue = null; if (_reader.HasValue) { dtdValue = _reader.Value; } // get line position after the !DOCTYPE declaration: // <!DOCTYPE rootElement SYSTEM rootElementDtdUri > // ^ // linePosition lineNumber = _reader.LineNumber; linePosition = _reader.LinePosition + _reader.Name.Length; // Note that there is no way to get the spacing after PUBLIC or SYSTEM attributes and their values if (_reader.MoveToFirstAttribute()) { // Write the space before SYSTEM or PUBLIC utilWriter.AppendRequiredWhiteSpace(lineNumber, linePosition, _reader.LineNumber, _reader.LinePosition); // Write SYSTEM or PUBLIC and the 1st value of the attribute string attrName = _reader.Name; utilWriter.Write(attrName); utilWriter.AppendSpace(); utilWriter.AppendAttributeValue(_reader); _reader.MoveToAttribute(0); // If PUBLIC, write the second value of the attribute if (attrName == "PUBLIC") { _reader.MoveToAttribute(1); utilWriter.AppendSpace(); utilWriter.AppendAttributeValue(_reader); _reader.MoveToAttribute(1); } } // If there is a dtd, write it if (dtdValue != null && dtdValue.Length > 0) { utilWriter.Write(" ["); utilWriter.Write(dtdValue); utilWriter.Write(']'); } utilWriter.Write('>'); } // Advance the _reader so we can get the position of the next node. bool moreToRead = _reader.Read(); nodeType = _reader.NodeType; // Close the node we are copying. if (close != null) { // // Find the position of the close string, for example: // // <element > <subElement /> // ^ // closeLinePosition // int startOffset = GetPositionOffset(nodeType); int closeLineNumber = _reader.LineNumber; int closeLinePosition = _reader.LinePosition - startOffset - close.Length; // Add whitespace up to the position of the close string utilWriter.AppendWhiteSpace(lineNumber, linePosition, closeLineNumber, closeLinePosition); // Write the close string utilWriter.Write(close); } // // Track the position of the reader based on the position of the reader // before we copied this node and what we have written in copying the node. // This allows us to determine the position of the <!DOCTYPE tag. // if (utilWriter.TrackPosition) { _lastLineNumber = (readerLineNumber - writerLineNumber) + utilWriter.LineNumber; if (writerLineNumber == utilWriter.LineNumber) { _lastLinePosition = (readerLinePosition - writerLinePosition) + utilWriter.LinePosition; } else { _lastLinePosition = utilWriter.LinePosition; } } return moreToRead; }
private void WriteNewConfigDefinitions(ConfigDefinitionUpdates configDefinitionUpdates, XmlUtilWriter utilWriter, int linePosition, int indent) { if (configDefinitionUpdates == null) return; foreach (LocationUpdates locationUpdates in configDefinitionUpdates.LocationUpdatesList) { SectionUpdates sectionUpdates = locationUpdates.SectionUpdates; if (sectionUpdates.IsEmpty || !sectionUpdates.IsNew) continue; configDefinitionUpdates.FlagLocationWritten(); bool writeLocationTag = _locationSubPath != null || !locationUpdates.IsDefault; int recurseLinePosition = linePosition; utilWriter.AppendSpacesToLinePosition(linePosition); if (writeLocationTag) { // write the <location> start tag if (_locationSubPath == null) { utilWriter.Write(String.Format(CultureInfo.InvariantCulture, FORMAT_LOCATION_NOPATH, locationUpdates.OverrideMode.LocationTagXmlString, BoolToString(locationUpdates.InheritInChildApps))); } else { utilWriter.Write(String.Format(CultureInfo.InvariantCulture, FORMAT_LOCATION_PATH, locationUpdates.OverrideMode.LocationTagXmlString, BoolToString(locationUpdates.InheritInChildApps), _locationSubPath)); } recurseLinePosition += indent; utilWriter.AppendSpacesToLinePosition(recurseLinePosition); } // Invoke the recursive write. WriteNewConfigDefinitionsRecursive(utilWriter, locationUpdates.SectionUpdates, recurseLinePosition, indent, true); if (writeLocationTag) { // Write the location end tag utilWriter.AppendSpacesToLinePosition(linePosition); utilWriter.Write(FORMAT_LOCATION_ENDELEMENT); utilWriter.AppendNewLine(); } } if (configDefinitionUpdates.RequireLocation) { Debug.Assert(IsLocationConfig, "IsLocationConfig"); // If we still require this to be written, then we must write it out now configDefinitionUpdates.FlagLocationWritten(); utilWriter.AppendSpacesToLinePosition(linePosition); utilWriter.Write(String.Format(CultureInfo.InvariantCulture, FORMAT_LOCATION_PATH, OverrideModeSetting.LocationDefault.LocationTagXmlString, KEYWORD_TRUE, _locationSubPath)); utilWriter.AppendSpacesToLinePosition(linePosition); utilWriter.Write(FORMAT_LOCATION_ENDELEMENT); utilWriter.AppendNewLine(); } }
// Create a new config file. private void CreateNewConfig( SectionUpdates declarationUpdates, ConfigDefinitionUpdates definitionUpdates, NamespaceChange namespaceChange, XmlUtilWriter utilWriter) { int linePosition = DEFAULT_INDENT + 1; int indent = DEFAULT_INDENT; // Write Header utilWriter.Write(string.Format(CultureInfo.InvariantCulture, FORMAT_NEWCONFIGFILE, ConfigStreamInfo.StreamEncoding.WebName)); // Write <configuration> tag if (namespaceChange == NamespaceChange.Add) { utilWriter.Write(string.Format(CultureInfo.InvariantCulture, FORMAT_CONFIGURATION_NAMESPACE, KEYWORD_CONFIGURATION_NAMESPACE)); } else { utilWriter.Write(FORMAT_CONFIGURATION); } if (declarationUpdates != null) { WriteNewConfigDeclarations(declarationUpdates, utilWriter, linePosition, indent, false); } WriteNewConfigDefinitions(definitionUpdates, utilWriter, linePosition, indent); utilWriter.Write(FORMAT_CONFIGURATION_ENDELEMENT); }
private void WriteSectionUpdate(XmlUtilWriter utilWriter, DefinitionUpdate update, int linePosition, int indent, bool skipFirstIndent) { string updatedXml; ConfigurationSection result = (ConfigurationSection) update.SectionRecord.Result; if (!string.IsNullOrEmpty(result.SectionInformation.ConfigSource)) { updatedXml = string.Format(CultureInfo.InvariantCulture, "<{0} configSource=\"{1}\" />", new object[] { result.SectionInformation.Name, result.SectionInformation.ConfigSource }); } else { updatedXml = update.UpdatedXml; } string s = XmlUtil.FormatXmlElement(updatedXml, linePosition, indent, skipFirstIndent); utilWriter.Write(s); }
private void WriteUnwrittenConfigDeclarationsRecursive(SectionUpdates declarationUpdates, XmlUtilWriter utilWriter, int linePosition, int indent, bool skipFirstIndent) { string[] unretrievedSectionNames = declarationUpdates.GetUnretrievedSectionNames(); if (unretrievedSectionNames != null) { foreach (string configKey in unretrievedSectionNames) { Debug.Assert(!IsImplicitSection(configKey), "We should never write out an implicit section"); if (!skipFirstIndent) { utilWriter.AppendSpacesToLinePosition(linePosition); } skipFirstIndent = false; DeclarationUpdate update = declarationUpdates.GetDeclarationUpdate(configKey); if (update != null && !string.IsNullOrEmpty(update.UpdatedXml)) { utilWriter.Write(update.UpdatedXml); utilWriter.AppendNewLine(); } } } string[] unretrievedGroupNames = declarationUpdates.GetUnretrievedGroupNames(); if (unretrievedGroupNames != null) { foreach (string group in unretrievedGroupNames) { if (TargetFramework != null) { ConfigurationSectionGroup g = GetSectionGroup(group); if (g != null && !g.ShouldSerializeSectionGroupInTargetVersion(TargetFramework)){ declarationUpdates.MarkGroupAsRetrieved(group); continue; } } if (!skipFirstIndent) { utilWriter.AppendSpacesToLinePosition(linePosition); } skipFirstIndent = false; SectionUpdates declarationUpdatesChild = declarationUpdates.GetSectionUpdatesForGroup(group); DeclarationUpdate groupUpdate = declarationUpdatesChild.GetSectionGroupUpdate(); if (groupUpdate == null) { utilWriter.Write("<sectionGroup name=\"" + group + "\">"); } else { utilWriter.Write(groupUpdate.UpdatedXml); } utilWriter.AppendNewLine(); WriteUnwrittenConfigDeclarationsRecursive(declarationUpdatesChild, utilWriter, linePosition + indent, indent, false); utilWriter.AppendSpacesToLinePosition(linePosition); utilWriter.Write("</sectionGroup>\r\n"); } } }
internal bool CopyXmlNode(XmlUtilWriter utilWriter) { string s = null; int fromLineNumber = -1; int fromLinePosition = -1; int lineNumber = 0; int linePosition = 0; int num5 = 0; int num6 = 0; if (utilWriter.TrackPosition) { lineNumber = this._reader.LineNumber; linePosition = this._reader.LinePosition; num5 = utilWriter.LineNumber; num6 = utilWriter.LinePosition; } XmlNodeType nodeType = this._reader.NodeType; switch (nodeType) { case XmlNodeType.Whitespace: utilWriter.Write(this._reader.Value); break; case XmlNodeType.Element: s = this._reader.IsEmptyElement ? "/>" : ">"; fromLineNumber = this._reader.LineNumber; fromLinePosition = this._reader.LinePosition + this._reader.Name.Length; utilWriter.Write('<'); utilWriter.Write(this._reader.Name); while (this._reader.MoveToNextAttribute()) { int toLineNumber = this._reader.LineNumber; int toLinePosition = this._reader.LinePosition; utilWriter.AppendRequiredWhiteSpace(fromLineNumber, fromLinePosition, toLineNumber, toLinePosition); int num9 = utilWriter.Write(this._reader.Name) + utilWriter.Write('='); num9 += utilWriter.AppendAttributeValue(this._reader); fromLineNumber = toLineNumber; fromLinePosition = toLinePosition + num9; } break; case XmlNodeType.EndElement: s = ">"; fromLineNumber = this._reader.LineNumber; fromLinePosition = this._reader.LinePosition + this._reader.Name.Length; utilWriter.Write("</"); utilWriter.Write(this._reader.Name); break; case XmlNodeType.Comment: utilWriter.AppendComment(this._reader.Value); break; case XmlNodeType.Text: utilWriter.AppendEscapeTextString(this._reader.Value); break; case XmlNodeType.XmlDeclaration: s = "?>"; fromLineNumber = this._reader.LineNumber; fromLinePosition = this._reader.LinePosition + 3; utilWriter.Write("<?xml"); while (this._reader.MoveToNextAttribute()) { int num10 = this._reader.LineNumber; int num11 = this._reader.LinePosition; utilWriter.AppendRequiredWhiteSpace(fromLineNumber, fromLinePosition, num10, num11); int num12 = utilWriter.Write(this._reader.Name) + utilWriter.Write('='); num12 += utilWriter.AppendAttributeValue(this._reader); fromLineNumber = num10; fromLinePosition = num11 + num12; } this._reader.MoveToElement(); break; case XmlNodeType.SignificantWhitespace: utilWriter.Write(this._reader.Value); break; case XmlNodeType.ProcessingInstruction: utilWriter.AppendProcessingInstruction(this._reader.Name, this._reader.Value); break; case XmlNodeType.EntityReference: utilWriter.AppendEntityRef(this._reader.Name); break; case XmlNodeType.CDATA: utilWriter.AppendCData(this._reader.Value); break; default: if (nodeType == XmlNodeType.DocumentType) { int num13 = utilWriter.Write("<!DOCTYPE"); utilWriter.AppendRequiredWhiteSpace(this._lastLineNumber, this._lastLinePosition + num13, this._reader.LineNumber, this._reader.LinePosition); utilWriter.Write(this._reader.Name); string str2 = null; if (this._reader.HasValue) { str2 = this._reader.Value; } fromLineNumber = this._reader.LineNumber; fromLinePosition = this._reader.LinePosition + this._reader.Name.Length; if (this._reader.MoveToFirstAttribute()) { utilWriter.AppendRequiredWhiteSpace(fromLineNumber, fromLinePosition, this._reader.LineNumber, this._reader.LinePosition); string name = this._reader.Name; utilWriter.Write(name); utilWriter.AppendSpace(); utilWriter.AppendAttributeValue(this._reader); this._reader.MoveToAttribute(0); if (name == "PUBLIC") { this._reader.MoveToAttribute(1); utilWriter.AppendSpace(); utilWriter.AppendAttributeValue(this._reader); this._reader.MoveToAttribute(1); } } if ((str2 != null) && (str2.Length > 0)) { utilWriter.Write(" ["); utilWriter.Write(str2); utilWriter.Write(']'); } utilWriter.Write('>'); } break; } bool flag = this._reader.Read(); nodeType = this._reader.NodeType; if (s != null) { int positionOffset = GetPositionOffset(nodeType); int num15 = this._reader.LineNumber; int num16 = (this._reader.LinePosition - positionOffset) - s.Length; utilWriter.AppendWhiteSpace(fromLineNumber, fromLinePosition, num15, num16); utilWriter.Write(s); } if (utilWriter.TrackPosition) { this._lastLineNumber = (lineNumber - num5) + utilWriter.LineNumber; if (num5 == utilWriter.LineNumber) { this._lastLinePosition = (linePosition - num6) + utilWriter.LinePosition; return flag; } this._lastLinePosition = utilWriter.LinePosition; } return flag; }
// Recursively write new sections for each section group. private bool WriteNewConfigDefinitionsRecursive(XmlUtilWriter utilWriter, SectionUpdates sectionUpdates, int linePosition, int indent, bool skipFirstIndent) { bool wroteASection = false; string[] movedSectionNames = sectionUpdates.GetMovedSectionNames(); if (movedSectionNames != null) { wroteASection = true; foreach (string configKey in movedSectionNames) { DefinitionUpdate update = sectionUpdates.GetDefinitionUpdate(configKey); WriteSectionUpdate(utilWriter, update, linePosition, indent, skipFirstIndent); utilWriter.AppendNewLine(); skipFirstIndent = false; } } string[] newGroupNames = sectionUpdates.GetNewGroupNames(); if (newGroupNames != null) { foreach (string group in newGroupNames) { if (TargetFramework != null) { ConfigurationSectionGroup g = GetSectionGroup(group); if (g != null && !g.ShouldSerializeSectionGroupInTargetVersion(TargetFramework)){ sectionUpdates.MarkGroupAsRetrieved(group); continue; } } if (!skipFirstIndent) { utilWriter.AppendSpacesToLinePosition(linePosition); } skipFirstIndent = false; utilWriter.Write("<" + group + ">\r\n"); bool recurseWroteASection = WriteNewConfigDefinitionsRecursive( utilWriter, sectionUpdates.GetSectionUpdatesForGroup(group), linePosition + indent, indent, false); if (recurseWroteASection) { wroteASection = true; } utilWriter.AppendSpacesToLinePosition(linePosition); utilWriter.Write("</" + group + ">\r\n"); } } sectionUpdates.IsNew = false; return wroteASection; }
internal static string FormatXmlElement(string xmlElement, int linePosition, int indent, bool skipFirstIndent) { XmlParserContext context = new XmlParserContext(null, null, null, XmlSpace.Default, Encoding.Unicode); XmlTextReader reader = new XmlTextReader(xmlElement, XmlNodeType.Element, context); StringWriter writer = new StringWriter(new StringBuilder(0x40), CultureInfo.InvariantCulture); XmlUtilWriter writer2 = new XmlUtilWriter(writer, false); bool newLine = false; bool flag2 = false; int num2 = 0; while (reader.Read()) { int num; int attributeCount; int num4; bool flag3; XmlNodeType nodeType = reader.NodeType; if (flag2) { writer2.Flush(); num = num2 - ((StringWriter) writer2.Writer).GetStringBuilder().Length; } else { num = 0; } XmlNodeType type2 = nodeType; if (type2 <= XmlNodeType.CDATA) { switch (type2) { case XmlNodeType.Element: case XmlNodeType.CDATA: goto Label_0091; } goto Label_00CA; } if ((type2 != XmlNodeType.Comment) && (type2 != XmlNodeType.EndElement)) { goto Label_00CA; } Label_0091: if (!skipFirstIndent && !flag2) { writer2.AppendIndent(linePosition, indent, reader.Depth, newLine); if (newLine) { writer2.Flush(); num2 = ((StringWriter) writer2.Writer).GetStringBuilder().Length; } } Label_00CA: flag2 = false; switch (nodeType) { case XmlNodeType.Element: writer2.Write('<'); writer2.Write(reader.Name); num += reader.Name.Length + 2; attributeCount = reader.AttributeCount; num4 = 0; goto Label_0274; case XmlNodeType.Text: writer2.AppendEscapeTextString(reader.Value); flag2 = true; goto Label_02D6; case XmlNodeType.CDATA: writer2.AppendCData(reader.Value); goto Label_02D6; case XmlNodeType.EntityReference: writer2.AppendEntityRef(reader.Name); goto Label_02D6; case XmlNodeType.ProcessingInstruction: writer2.AppendProcessingInstruction(reader.Name, reader.Value); goto Label_02D6; case XmlNodeType.Comment: writer2.AppendComment(reader.Value); goto Label_02D6; case XmlNodeType.SignificantWhitespace: writer2.Write(reader.Value); goto Label_02D6; case XmlNodeType.EndElement: writer2.Write("</"); writer2.Write(reader.Name); writer2.Write('>'); goto Label_02D6; default: goto Label_02D6; } Label_01BE: if (num > 60) { writer2.AppendIndent(linePosition, indent, reader.Depth - 1, true); num = indent; flag3 = false; writer2.Flush(); num2 = ((StringWriter) writer2.Writer).GetStringBuilder().Length; } else { flag3 = true; } reader.MoveToNextAttribute(); writer2.Flush(); int length = ((StringWriter) writer2.Writer).GetStringBuilder().Length; if (flag3) { writer2.AppendSpace(); } writer2.Write(reader.Name); writer2.Write('='); writer2.AppendAttributeValue(reader); writer2.Flush(); num += ((StringWriter) writer2.Writer).GetStringBuilder().Length - length; num4++; Label_0274: if (num4 < attributeCount) { goto Label_01BE; } reader.MoveToElement(); if (reader.IsEmptyElement) { writer2.Write(" />"); } else { writer2.Write('>'); } Label_02D6: newLine = true; skipFirstIndent = false; } writer2.Flush(); return ((StringWriter) writer2.Writer).ToString(); }
// Copy a config file, replacing sections with updates. private void CopyConfig(SectionUpdates declarationUpdates, ConfigDefinitionUpdates definitionUpdates, byte[] buffer, string filename, NamespaceChange namespaceChange, XmlUtilWriter utilWriter) { CheckPreamble(ConfigStreamInfo.StreamEncoding.GetPreamble(), utilWriter, buffer); using (Stream stream = new MemoryStream(buffer)) { using (XmlUtil xmlUtil = new XmlUtil(stream, filename, false)) { // copy up to the <configuration> node XmlTextReader reader = xmlUtil.Reader; reader.WhitespaceHandling = WhitespaceHandling.All; reader.Read(); xmlUtil.CopyReaderToNextElement(utilWriter, false); Debug.Assert(reader.NodeType == XmlNodeType.Element && reader.Name == KEYWORD_CONFIGURATION, "reader.NodeType == XmlNodeType.Element && reader.Name == KEYWORD_CONFIGURATION"); int indent = DEFAULT_INDENT; int configurationElementLinePosition = xmlUtil.TrueLinePosition; bool isEmptyConfigurationElement = reader.IsEmptyElement; // copy <configuration> node // if the node is an empty element, we may need to open it. string configurationStartElement; if (namespaceChange == NamespaceChange.Add) { configurationStartElement = string.Format( CultureInfo.InvariantCulture, FORMAT_CONFIGURATION_NAMESPACE, KEYWORD_CONFIGURATION_NAMESPACE); } else if (namespaceChange == NamespaceChange.Remove) { configurationStartElement = FORMAT_CONFIGURATION; } else { configurationStartElement = null; } bool needsChildren = (declarationUpdates != null || definitionUpdates != null); string configurationEndElement = xmlUtil.UpdateStartElement(utilWriter, configurationStartElement, needsChildren, configurationElementLinePosition, indent); bool foundConfigSectionsElement = false; if (!isEmptyConfigurationElement) { // copy up to the first element under <configuration> xmlUtil.CopyReaderToNextElement(utilWriter, true); // updateIndent indent = UpdateIndent(indent, xmlUtil, utilWriter, configurationElementLinePosition); if (reader.NodeType == XmlNodeType.Element && reader.Name == KEYWORD_CONFIGSECTIONS) { foundConfigSectionsElement = true; int configSectionsElementLinePosition = xmlUtil.TrueLinePosition; bool isEmptyConfigSectionsElement = reader.IsEmptyElement; // if no updates, copy the entire <configSections> element if (declarationUpdates == null) { xmlUtil.CopyOuterXmlToNextElement(utilWriter, true); } else { // copy <configSections>, and open it if it is an empty element string configSectionsEndElement = xmlUtil.UpdateStartElement( utilWriter, null, true, configSectionsElementLinePosition, indent); if (!isEmptyConfigSectionsElement) { // copy to next element under <configSections>, or up to closing </configSections> xmlUtil.CopyReaderToNextElement(utilWriter, true); // copy config declarations CopyConfigDeclarationsRecursive(declarationUpdates, xmlUtil, utilWriter, string.Empty, configSectionsElementLinePosition, indent); Debug.Assert(reader.NodeType == XmlNodeType.EndElement && reader.Name == KEYWORD_CONFIGSECTIONS, "reader.NodeType == XmlNodeType.EndElement && reader.Name == \"KEYWORD_CONFIGSECTIONS\""); } // write declarations not written by above copy if (declarationUpdates.HasUnretrievedSections()) { // determine the line position of the end element int endElementLinePosition = 0; if (configSectionsEndElement == null) { endElementLinePosition = xmlUtil.TrueLinePosition; } // indent a new line if (!utilWriter.IsLastLineBlank) { utilWriter.AppendNewLine(); } WriteUnwrittenConfigDeclarations(declarationUpdates, utilWriter, configSectionsElementLinePosition + indent, indent, false); // restore spaces to end element if (configSectionsEndElement == null) { utilWriter.AppendSpacesToLinePosition(endElementLinePosition); } } // Copy the </configSections> element if (configSectionsEndElement == null) { xmlUtil.CopyXmlNode(utilWriter); } else { // note that configSectionsEndElement already contains the proper indenting utilWriter.Write(configSectionsEndElement); } // copy up to the next element under <configuration>, or up to closing </configSections> xmlUtil.CopyReaderToNextElement(utilWriter, true); } } } // Write new declarations if (!foundConfigSectionsElement && declarationUpdates != null) { bool skipFirstIndent = reader.Depth > 0 && reader.NodeType == XmlNodeType.Element; int newConfigSectionsLinePosition; if (skipFirstIndent) { newConfigSectionsLinePosition = xmlUtil.TrueLinePosition; } else { newConfigSectionsLinePosition = configurationElementLinePosition + indent; } WriteNewConfigDeclarations(declarationUpdates, utilWriter, newConfigSectionsLinePosition, indent, skipFirstIndent); } if (definitionUpdates != null) { // // Copy sections recursively. In the file we copy we start out at // location path="." allowOverride="true" inheritInChildApps="true" // bool locationPathApplies = false; LocationUpdates locationUpdates = null; SectionUpdates sectionUpdates = null; if (!IsLocationConfig) { locationPathApplies = true; locationUpdates = definitionUpdates.FindLocationUpdates(OverrideModeSetting.LocationDefault, true); if (locationUpdates != null) { sectionUpdates = locationUpdates.SectionUpdates; } } CopyConfigDefinitionsRecursive(definitionUpdates, xmlUtil, utilWriter, locationPathApplies, locationUpdates, sectionUpdates, true, string.Empty, configurationElementLinePosition, indent); // Write new config sections from new groups. WriteNewConfigDefinitions(definitionUpdates, utilWriter, configurationElementLinePosition + indent, indent); #if DBG Debug.Assert(configurationEndElement != null || (reader.NodeType == XmlNodeType.EndElement && reader.Name == KEYWORD_CONFIGURATION), "configurationEndElement != null || (reader.NodeType == XmlNodeType.EndElement && reader.Name == KEYWORD_CONFIGURATION)"); #endif #if DBG { foreach (LocationUpdates l in definitionUpdates.LocationUpdatesList) { Debug.Assert(!l.SectionUpdates.HasUnretrievedSections(), "!l.SectionUpdates.HasUnretrievedSections()"); } } #endif } if (configurationEndElement != null) { // If we have to add closing config tag, then do it now // before copying extra whitespace/comments if (!utilWriter.IsLastLineBlank) { utilWriter.AppendNewLine(); } utilWriter.Write(configurationEndElement); } // // Copy the remainder of the file, the closing </configuration> node plus any whitespace // and comments // while (xmlUtil.CopyXmlNode(utilWriter)) { } } } }
internal string UpdateStartElement(XmlUtilWriter utilWriter, string updatedStartElement, bool needsChildren, int linePosition, int indent) { string str = null; string str6; bool flag = false; string name = this._reader.Name; if (this._reader.IsEmptyElement) { if ((updatedStartElement == null) && needsChildren) { updatedStartElement = this.RetrieveFullOpenElementTag(); } flag = updatedStartElement != null; } if (updatedStartElement == null) { this.CopyXmlNode(utilWriter); return str; } string str5 = FormatXmlElement(updatedStartElement + ("</" + name + ">"), linePosition, indent, true); int startIndex = str5.LastIndexOf('\n') + 1; if (flag) { str = str5.Substring(startIndex); str6 = str5.Substring(0, startIndex); } else { str6 = str5.Substring(0, startIndex - 2); } utilWriter.Write(str6); this._reader.Read(); return str; }
private void WriteSectionUpdate(XmlUtilWriter utilWriter, DefinitionUpdate update, int linePosition, int indent, bool skipFirstIndent) { ConfigurationSection configSection = (ConfigurationSection) update.SectionRecord.Result; string updatedXml; if (!String.IsNullOrEmpty(configSection.SectionInformation.ConfigSource)) { updatedXml = string.Format(CultureInfo.InvariantCulture, FORMAT_SECTION_CONFIGSOURCE, configSection.SectionInformation.Name, configSection.SectionInformation.ConfigSource); } else { updatedXml = update.UpdatedXml; } string formattedXml = XmlUtil.FormatXmlElement(updatedXml, linePosition, indent, skipFirstIndent); utilWriter.Write(formattedXml); }
// Create a new config file. private void CreateNewConfig( SectionUpdates declarationUpdates, ConfigDefinitionUpdates definitionUpdates, NamespaceChange namespaceChange, XmlUtilWriter utilWriter) { // Write Header utilWriter.Write(string.Format(CultureInfo.InvariantCulture, FormatNewconfigfile, ConfigStreamInfo.StreamEncoding.WebName)); // Write <configuration> tag if (namespaceChange == NamespaceChange.Add) { utilWriter.Write(string.Format(CultureInfo.InvariantCulture, FormatConfigurationNamespace, KeywordConfigurationNamespace)); } else utilWriter.Write(FormatConfiguration); const int LineIndent = DefaultIndent + 1; if (declarationUpdates != null) WriteNewConfigDeclarations(declarationUpdates, utilWriter, LineIndent, DefaultIndent, false); WriteNewConfigDefinitions(definitionUpdates, utilWriter, LineIndent, DefaultIndent); utilWriter.Write(FormatConfigurationEndelement); }
private void CreateNewConfigSource(XmlUtilWriter utilWriter, string updatedXml, int indent) { string formattedXml = XmlUtil.FormatXmlElement(updatedXml, 0, indent, true); utilWriter.Write(string.Format(CultureInfo.InvariantCulture, FORMAT_CONFIGSOURCE_FILE, ConfigStreamInfo.StreamEncoding.WebName)); utilWriter.Write(formattedXml + NL); }
private void WriteNewConfigDefinitions(ConfigDefinitionUpdates configDefinitionUpdates, XmlUtilWriter utilWriter, int linePosition, int indent) { if (configDefinitionUpdates != null) { foreach (LocationUpdates updates in configDefinitionUpdates.LocationUpdatesList) { SectionUpdates sectionUpdates = updates.SectionUpdates; if (!sectionUpdates.IsEmpty && sectionUpdates.IsNew) { configDefinitionUpdates.FlagLocationWritten(); bool flag = (base._locationSubPath != null) || !updates.IsDefault; int num = linePosition; utilWriter.AppendSpacesToLinePosition(linePosition); if (flag) { if (base._locationSubPath == null) { utilWriter.Write(string.Format(CultureInfo.InvariantCulture, "<location {0} inheritInChildApplications=\"{1}\">\r\n", new object[] { updates.OverrideMode.LocationTagXmlString, BoolToString(updates.InheritInChildApps) })); } else { utilWriter.Write(string.Format(CultureInfo.InvariantCulture, "<location path=\"{2}\" {0} inheritInChildApplications=\"{1}\">\r\n", new object[] { updates.OverrideMode.LocationTagXmlString, BoolToString(updates.InheritInChildApps), base._locationSubPath })); } num += indent; utilWriter.AppendSpacesToLinePosition(num); } this.WriteNewConfigDefinitionsRecursive(utilWriter, updates.SectionUpdates, num, indent, true); if (flag) { utilWriter.AppendSpacesToLinePosition(linePosition); utilWriter.Write("</location>"); utilWriter.AppendNewLine(); } } } if (configDefinitionUpdates.RequireLocation) { configDefinitionUpdates.FlagLocationWritten(); utilWriter.AppendSpacesToLinePosition(linePosition); utilWriter.Write(string.Format(CultureInfo.InvariantCulture, "<location path=\"{2}\" {0} inheritInChildApplications=\"{1}\">\r\n", new object[] { OverrideModeSetting.LocationDefault.LocationTagXmlString, "true", base._locationSubPath })); utilWriter.AppendSpacesToLinePosition(linePosition); utilWriter.Write("</location>"); utilWriter.AppendNewLine(); } } }