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 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; }