Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / XmlUtils / System / Xml / Xsl / XsltOld / RecordBuilder.cs / 1 / RecordBuilder.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- namespace System.Xml.Xsl.XsltOld { using Res = System.Xml.Utils.Res; using System; using System.Diagnostics; using System.Text; using System.Xml; using System.Xml.XPath; using System.Collections; internal sealed class RecordBuilder { private int outputState; private RecordBuilder next; RecordOutput output; // Atomization: private XmlNameTable nameTable; private OutKeywords atoms; // Namespace manager for output private OutputScopeManager scopeManager; // Main node + Fields Collection private BuilderInfo mainNode = new BuilderInfo(); private ArrayList attributeList = new ArrayList(); private int attributeCount; private ArrayList namespaceList = new ArrayList(); private int namespaceCount; private BuilderInfo dummy = new BuilderInfo(); // Current position in the list private BuilderInfo currentInfo; // Builder state private bool popScope; private int recordState; private int recordDepth; private const int NoRecord = 0; // No part of a new record was generated (old record was cleared out) private const int SomeRecord = 1; // Record was generated partially (can be eventually record) private const int HaveRecord = 2; // Record was fully generated private const char s_Minus = '-'; private const string s_Space = " "; private const string s_SpaceMinus = " -"; private const char s_Question = '?'; private const char s_Greater = '>'; private const string s_SpaceGreater = " >"; private const string PrefixFormat = "xp_{0}"; private const string s_SpaceDefault = "default"; private const string s_SpacePreserve = "preserve"; internal RecordBuilder(RecordOutput output, XmlNameTable nameTable) { Debug.Assert(output != null); this.output = output; this.nameTable = nameTable != null ? nameTable : new NameTable(); this.atoms = new OutKeywords(this.nameTable); this.scopeManager = new OutputScopeManager(this.nameTable, this.atoms); } // // Internal properties // internal int OutputState { get { return this.outputState; } set { this.outputState = value; } } internal RecordBuilder Next { get { return this.next; } set { this.next = value; } } internal RecordOutput Output { get { return this.output; } } internal BuilderInfo MainNode { get { return this.mainNode; } } internal ArrayList AttributeList { get { return this.attributeList; } } internal int AttributeCount { get { return this.attributeCount; } } internal OutputScopeManager Manager { get { return this.scopeManager; } } private void ValueAppend(string s, bool disableOutputEscaping) { this.currentInfo.ValueAppend(s, disableOutputEscaping); } private bool CanOutput(int state) { Debug.Assert(this.recordState != HaveRecord); // If we have no record cached or the next event doesn't start new record, we are OK if (this.recordState == NoRecord || (state & StateMachine.BeginRecord) == 0) { return true; } else { this.recordState = HaveRecord; FinalizeRecord(); SetEmptyFlag(state); return this.output.RecordDone(this) == Processor.OutputResult.Continue; } } internal Processor.OutputResult BeginEvent(int state, XPathNodeType nodeType, string prefix, string name, string nspace, bool empty, Object htmlProps, bool search) { if (! CanOutput(state)) { return Processor.OutputResult.Overflow; } Debug.Assert(this.recordState == NoRecord || (state & StateMachine.BeginRecord) == 0); AdjustDepth(state); ResetRecord(state); PopElementScope(); prefix = (prefix != null) ? this.nameTable.Add(prefix) : this.atoms.Empty; name = (name != null) ? this.nameTable.Add(name) : this.atoms.Empty; nspace = (nspace != null) ? this.nameTable.Add(nspace) : this.atoms.Empty; switch (nodeType) { case XPathNodeType.Element: this.mainNode.htmlProps = htmlProps as HtmlElementProps; this.mainNode.search = search; BeginElement(prefix, name, nspace, empty); break; case XPathNodeType.Attribute: BeginAttribute(prefix, name, nspace, htmlProps, search); break; case XPathNodeType.Namespace: BeginNamespace(name, nspace); break; case XPathNodeType.Text: break; case XPathNodeType.ProcessingInstruction: if (BeginProcessingInstruction(prefix, name, nspace) == false) { return Processor.OutputResult.Error; } break; case XPathNodeType.Comment: BeginComment(); break; case XPathNodeType.Root: break; case XPathNodeType.Whitespace: case XPathNodeType.SignificantWhitespace: case XPathNodeType.All: break; } return CheckRecordBegin(state); } internal Processor.OutputResult TextEvent(int state, string text, bool disableOutputEscaping) { if (! CanOutput(state)) { return Processor.OutputResult.Overflow; } Debug.Assert(this.recordState == NoRecord || (state & StateMachine.BeginRecord) == 0); AdjustDepth(state); ResetRecord(state); PopElementScope(); if ((state & StateMachine.BeginRecord) != 0) { this.currentInfo.Depth = this.recordDepth; this.currentInfo.NodeType = XmlNodeType.Text; } ValueAppend(text, disableOutputEscaping); return CheckRecordBegin(state); } internal Processor.OutputResult EndEvent(int state, XPathNodeType nodeType) { if (! CanOutput(state)) { return Processor.OutputResult.Overflow; } AdjustDepth(state); PopElementScope(); this.popScope = (state & StateMachine.PopScope) != 0; if ((state & StateMachine.EmptyTag) != 0 && this.mainNode.IsEmptyTag == true) { return Processor.OutputResult.Continue; } ResetRecord(state); if ((state & StateMachine.BeginRecord) != 0) { if(nodeType == XPathNodeType.Element) { EndElement(); } } return CheckRecordEnd(state); } internal void Reset() { if (this.recordState == HaveRecord) { this.recordState = NoRecord; } } internal void TheEnd() { if (this.recordState == SomeRecord) { this.recordState = HaveRecord; FinalizeRecord(); this.output.RecordDone(this); } this.output.TheEnd(); } // // Utility implementation methods // private int FindAttribute(string name, string nspace, ref string prefix) { Debug.Assert(this.attributeCount <= this.attributeList.Count); for (int attrib = 0; attrib < this.attributeCount; attrib ++) { Debug.Assert(this.attributeList[attrib] != null && this.attributeList[attrib] is BuilderInfo); BuilderInfo attribute = (BuilderInfo) this.attributeList[attrib]; if (Keywords.Equals(attribute.LocalName, name)) { if (Keywords.Equals(attribute.NamespaceURI, nspace)) { return attrib; } if (Keywords.Equals(attribute.Prefix, prefix)) { // prefix conflict. Should be renamed. prefix = string.Empty; } } } return -1; } private void BeginElement(string prefix, string name, string nspace, bool empty) { Debug.Assert(this.attributeCount == 0); this.currentInfo.NodeType = XmlNodeType.Element; this.currentInfo.Prefix = prefix; this.currentInfo.LocalName = name; this.currentInfo.NamespaceURI = nspace; this.currentInfo.Depth = this.recordDepth; this.currentInfo.IsEmptyTag = empty; this.scopeManager.PushScope(name, nspace, prefix); } private void EndElement() { Debug.Assert(this.attributeCount == 0); OutputScope elementScope = this.scopeManager.CurrentElementScope; this.currentInfo.NodeType = XmlNodeType.EndElement; this.currentInfo.Prefix = elementScope.Prefix; this.currentInfo.LocalName = elementScope.Name; this.currentInfo.NamespaceURI = elementScope.Namespace; this.currentInfo.Depth = this.recordDepth; } private int NewAttribute() { if (this.attributeCount >= this.attributeList.Count) { Debug.Assert(this.attributeCount == this.attributeList.Count); this.attributeList.Add(new BuilderInfo()); } return this.attributeCount ++; } private void BeginAttribute(string prefix, string name, string nspace, Object htmlAttrProps, bool search) { int attrib = FindAttribute(name, nspace, ref prefix); if (attrib == -1) { attrib = NewAttribute(); } Debug.Assert(this.attributeList[attrib] != null && this.attributeList[attrib] is BuilderInfo); BuilderInfo attribute = (BuilderInfo) this.attributeList[attrib]; attribute.Initialize(prefix, name, nspace); attribute.Depth = this.recordDepth; attribute.NodeType = XmlNodeType.Attribute; attribute.htmlAttrProps = htmlAttrProps as HtmlAttributeProps; attribute.search = search; this.currentInfo = attribute; } private void BeginNamespace(string name, string nspace) { bool thisScope = false; if (Keywords.Equals(name, this.atoms.Empty)) { if (Keywords.Equals(nspace, this.scopeManager.DefaultNamespace)) { // Main Node is OK } else if (Keywords.Equals(this.mainNode.NamespaceURI, this.atoms.Empty)) { // http://www.w3.org/1999/11/REC-xslt-19991116-errata/ E25 // Should throw an error but ingnoring it in Everett. // Would be a breaking change } else { DeclareNamespace(nspace, name); } } else { string nspaceDeclared = this.scopeManager.ResolveNamespace(name, out thisScope); if (nspaceDeclared != null) { if (! Keywords.Equals(nspace, nspaceDeclared)) { if(!thisScope) { DeclareNamespace(nspace, name); } } } else { DeclareNamespace(nspace, name); } } this.currentInfo = dummy; currentInfo.NodeType = XmlNodeType.Attribute; } private bool BeginProcessingInstruction(string prefix, string name, string nspace) { this.currentInfo.NodeType = XmlNodeType.ProcessingInstruction; this.currentInfo.Prefix = prefix; this.currentInfo.LocalName = name; this.currentInfo.NamespaceURI = nspace; this.currentInfo.Depth = this.recordDepth; return true; } private void BeginComment() { this.currentInfo.NodeType = XmlNodeType.Comment; this.currentInfo.Depth = this.recordDepth; } private void AdjustDepth(int state) { switch (state & StateMachine.DepthMask) { case StateMachine.DepthUp: this.recordDepth ++; break; case StateMachine.DepthDown: this.recordDepth --; break; default: break; } } private void ResetRecord(int state) { Debug.Assert(this.recordState == NoRecord || this.recordState == SomeRecord); if ((state & StateMachine.BeginRecord) != 0) { this.attributeCount = 0; this.namespaceCount = 0; this.currentInfo = this.mainNode; this.currentInfo.Initialize(this.atoms.Empty, this.atoms.Empty, this.atoms.Empty); this.currentInfo.NodeType = XmlNodeType.None; this.currentInfo.IsEmptyTag = false; this.currentInfo.htmlProps = null; this.currentInfo.htmlAttrProps = null; } } private void PopElementScope() { if (this.popScope) { this.scopeManager.PopScope(); this.popScope = false; } } private Processor.OutputResult CheckRecordBegin(int state) { Debug.Assert(this.recordState == NoRecord || this.recordState == SomeRecord); if ((state & StateMachine.EndRecord) != 0) { this.recordState = HaveRecord; FinalizeRecord(); SetEmptyFlag(state); return this.output.RecordDone(this); } else { this.recordState = SomeRecord; return Processor.OutputResult.Continue; } } private Processor.OutputResult CheckRecordEnd(int state) { Debug.Assert(this.recordState == NoRecord || this.recordState == SomeRecord); if ((state & StateMachine.EndRecord) != 0) { this.recordState = HaveRecord; FinalizeRecord(); SetEmptyFlag(state); return this.output.RecordDone(this); } else { // For end event, if there is no end token, don't force token return Processor.OutputResult.Continue; } } private void SetEmptyFlag(int state) { Debug.Assert(this.mainNode != null); if ((state & StateMachine.BeginChild) != 0) { this.mainNode.IsEmptyTag = false; } } private void AnalyzeSpaceLang() { Debug.Assert(this.mainNode.NodeType == XmlNodeType.Element); for (int attr = 0; attr < this.attributeCount; attr ++) { Debug.Assert(this.attributeList[attr] is BuilderInfo); BuilderInfo info = (BuilderInfo) this.attributeList[attr]; if (Keywords.Equals(info.Prefix, this.atoms.Xml)) { OutputScope scope = this.scopeManager.CurrentElementScope; if (Keywords.Equals(info.LocalName, this.atoms.Lang)) { scope.Lang = info.Value; } else if (Keywords.Equals(info.LocalName, this.atoms.Space)) { scope.Space = TranslateXmlSpace(info.Value); } } } } private void FixupElement() { Debug.Assert(this.mainNode.NodeType == XmlNodeType.Element); if (Keywords.Equals(this.mainNode.NamespaceURI, this.atoms.Empty)) { this.mainNode.Prefix = this.atoms.Empty; } if (Keywords.Equals(this.mainNode.Prefix, this.atoms.Empty)) { if (Keywords.Equals(this.mainNode.NamespaceURI, this.scopeManager.DefaultNamespace)) { // Main Node is OK } else { DeclareNamespace(this.mainNode.NamespaceURI, this.mainNode.Prefix); } } else { bool thisScope = false; string nspace = this.scopeManager.ResolveNamespace(this.mainNode.Prefix, out thisScope); if (nspace != null) { if (! Keywords.Equals(this.mainNode.NamespaceURI, nspace)) { if (thisScope) { // Prefix conflict this.mainNode.Prefix = GetPrefixForNamespace(this.mainNode.NamespaceURI); } else { DeclareNamespace(this.mainNode.NamespaceURI, this.mainNode.Prefix); } } } else { DeclareNamespace(this.mainNode.NamespaceURI, this.mainNode.Prefix); } } OutputScope elementScope = this.scopeManager.CurrentElementScope; elementScope.Prefix = this.mainNode.Prefix; } private void FixupAttributes(int attributeCount) { for (int attr = 0; attr < attributeCount; attr ++) { Debug.Assert(this.attributeList[attr] is BuilderInfo); BuilderInfo info = (BuilderInfo) this.attributeList[attr]; if (Keywords.Equals(info.NamespaceURI, this.atoms.Empty)) { info.Prefix = this.atoms.Empty; } else { if (Keywords.Equals(info.Prefix, this.atoms.Empty)) { info.Prefix = GetPrefixForNamespace(info.NamespaceURI); } else { bool thisScope = false; string nspace = this.scopeManager.ResolveNamespace(info.Prefix, out thisScope); if (nspace != null) { if (! Keywords.Equals(info.NamespaceURI, nspace)) { if(thisScope) { // prefix conflict info.Prefix = GetPrefixForNamespace(info.NamespaceURI); } else { DeclareNamespace(info.NamespaceURI, info.Prefix); } } } else { DeclareNamespace(info.NamespaceURI, info.Prefix); } } } } } private void AppendNamespaces() { for (int i = this.namespaceCount - 1; i >= 0; i --) { BuilderInfo attribute = (BuilderInfo) this.attributeList[NewAttribute()]; attribute.Initialize((BuilderInfo)this.namespaceList[i]); } } private void AnalyzeComment() { Debug.Assert(this.mainNode.NodeType == XmlNodeType.Comment); Debug.Assert((object) this.currentInfo == (object) this.mainNode); StringBuilder newComment = null; string comment = this.mainNode.Value; bool minus = false; int index = 0, begin = 0; for (; index < comment.Length; index ++) { switch (comment[index]) { case s_Minus: if (minus) { if (newComment == null) newComment = new StringBuilder(comment, begin, index, 2 * comment.Length); else newComment.Append(comment, begin, index - begin); newComment.Append(s_SpaceMinus); begin = index + 1; } minus = true; break; default: minus = false; break; } } if (newComment != null) { if (begin < comment.Length) newComment.Append(comment, begin, comment.Length - begin); if (minus) newComment.Append(s_Space); this.mainNode.Value = newComment.ToString(); } else if (minus) { this.mainNode.ValueAppend(s_Space, false); } } private void AnalyzeProcessingInstruction() { Debug.Assert(this.mainNode.NodeType == XmlNodeType.ProcessingInstruction || this.mainNode.NodeType == XmlNodeType.XmlDeclaration); //Debug.Assert((object) this.currentInfo == (object) this.mainNode); StringBuilder newPI = null; string pi = this.mainNode.Value; bool question = false; int index = 0, begin = 0; for (; index < pi.Length; index ++) { switch (pi[index]) { case s_Question: question = true; break; case s_Greater: if (question) { if (newPI == null) { newPI = new StringBuilder(pi, begin, index, 2 * pi.Length); } else { newPI.Append(pi, begin, index - begin); } newPI.Append(s_SpaceGreater); begin = index + 1; } question = false; break; default: question = false; break; } } if (newPI != null) { if (begin < pi.Length) { newPI.Append(pi, begin, pi.Length - begin); } this.mainNode.Value = newPI.ToString(); } } private void FinalizeRecord() { switch (this.mainNode.NodeType) { case XmlNodeType.Element: // Save count since FixupElement can add attribute... int attributeCount = this.attributeCount; FixupElement(); FixupAttributes(attributeCount); AnalyzeSpaceLang(); AppendNamespaces(); break; case XmlNodeType.Comment: AnalyzeComment(); break; case XmlNodeType.ProcessingInstruction: AnalyzeProcessingInstruction(); break; } } private int NewNamespace() { if (this.namespaceCount >= this.namespaceList.Count) { Debug.Assert(this.namespaceCount == this.namespaceList.Count); this.namespaceList.Add(new BuilderInfo()); } return this.namespaceCount ++; } private void DeclareNamespace(string nspace, string prefix) { int index = NewNamespace(); Debug.Assert(this.namespaceList[index] != null && this.namespaceList[index] is BuilderInfo); BuilderInfo ns = (BuilderInfo) this.namespaceList[index]; if (prefix == this.atoms.Empty) { ns.Initialize(this.atoms.Empty, this.atoms.Xmlns, this.atoms.XmlnsNamespace); } else { ns.Initialize(this.atoms.Xmlns, prefix, this.atoms.XmlnsNamespace); } ns.Depth = this.recordDepth; ns.NodeType = XmlNodeType.Attribute; ns.Value = nspace; this.scopeManager.PushNamespace(prefix, nspace); } private string DeclareNewNamespace(string nspace) { string prefix = this.scopeManager.GeneratePrefix(PrefixFormat); DeclareNamespace(nspace, prefix); return prefix; } internal string GetPrefixForNamespace(string nspace) { string prefix = null; if (this.scopeManager.FindPrefix(nspace, out prefix)) { Debug.Assert(prefix != null && prefix.Length > 0); return prefix; } else { return DeclareNewNamespace(nspace); } } private static XmlSpace TranslateXmlSpace(string space) { if (Keywords.Compare(space, s_SpaceDefault)) { return XmlSpace.Default; } else if (Keywords.Compare(space, s_SpacePreserve)) { return XmlSpace.Preserve; } else { return XmlSpace.None; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- namespace System.Xml.Xsl.XsltOld { using Res = System.Xml.Utils.Res; using System; using System.Diagnostics; using System.Text; using System.Xml; using System.Xml.XPath; using System.Collections; internal sealed class RecordBuilder { private int outputState; private RecordBuilder next; RecordOutput output; // Atomization: private XmlNameTable nameTable; private OutKeywords atoms; // Namespace manager for output private OutputScopeManager scopeManager; // Main node + Fields Collection private BuilderInfo mainNode = new BuilderInfo(); private ArrayList attributeList = new ArrayList(); private int attributeCount; private ArrayList namespaceList = new ArrayList(); private int namespaceCount; private BuilderInfo dummy = new BuilderInfo(); // Current position in the list private BuilderInfo currentInfo; // Builder state private bool popScope; private int recordState; private int recordDepth; private const int NoRecord = 0; // No part of a new record was generated (old record was cleared out) private const int SomeRecord = 1; // Record was generated partially (can be eventually record) private const int HaveRecord = 2; // Record was fully generated private const char s_Minus = '-'; private const string s_Space = " "; private const string s_SpaceMinus = " -"; private const char s_Question = '?'; private const char s_Greater = '>'; private const string s_SpaceGreater = " >"; private const string PrefixFormat = "xp_{0}"; private const string s_SpaceDefault = "default"; private const string s_SpacePreserve = "preserve"; internal RecordBuilder(RecordOutput output, XmlNameTable nameTable) { Debug.Assert(output != null); this.output = output; this.nameTable = nameTable != null ? nameTable : new NameTable(); this.atoms = new OutKeywords(this.nameTable); this.scopeManager = new OutputScopeManager(this.nameTable, this.atoms); } // // Internal properties // internal int OutputState { get { return this.outputState; } set { this.outputState = value; } } internal RecordBuilder Next { get { return this.next; } set { this.next = value; } } internal RecordOutput Output { get { return this.output; } } internal BuilderInfo MainNode { get { return this.mainNode; } } internal ArrayList AttributeList { get { return this.attributeList; } } internal int AttributeCount { get { return this.attributeCount; } } internal OutputScopeManager Manager { get { return this.scopeManager; } } private void ValueAppend(string s, bool disableOutputEscaping) { this.currentInfo.ValueAppend(s, disableOutputEscaping); } private bool CanOutput(int state) { Debug.Assert(this.recordState != HaveRecord); // If we have no record cached or the next event doesn't start new record, we are OK if (this.recordState == NoRecord || (state & StateMachine.BeginRecord) == 0) { return true; } else { this.recordState = HaveRecord; FinalizeRecord(); SetEmptyFlag(state); return this.output.RecordDone(this) == Processor.OutputResult.Continue; } } internal Processor.OutputResult BeginEvent(int state, XPathNodeType nodeType, string prefix, string name, string nspace, bool empty, Object htmlProps, bool search) { if (! CanOutput(state)) { return Processor.OutputResult.Overflow; } Debug.Assert(this.recordState == NoRecord || (state & StateMachine.BeginRecord) == 0); AdjustDepth(state); ResetRecord(state); PopElementScope(); prefix = (prefix != null) ? this.nameTable.Add(prefix) : this.atoms.Empty; name = (name != null) ? this.nameTable.Add(name) : this.atoms.Empty; nspace = (nspace != null) ? this.nameTable.Add(nspace) : this.atoms.Empty; switch (nodeType) { case XPathNodeType.Element: this.mainNode.htmlProps = htmlProps as HtmlElementProps; this.mainNode.search = search; BeginElement(prefix, name, nspace, empty); break; case XPathNodeType.Attribute: BeginAttribute(prefix, name, nspace, htmlProps, search); break; case XPathNodeType.Namespace: BeginNamespace(name, nspace); break; case XPathNodeType.Text: break; case XPathNodeType.ProcessingInstruction: if (BeginProcessingInstruction(prefix, name, nspace) == false) { return Processor.OutputResult.Error; } break; case XPathNodeType.Comment: BeginComment(); break; case XPathNodeType.Root: break; case XPathNodeType.Whitespace: case XPathNodeType.SignificantWhitespace: case XPathNodeType.All: break; } return CheckRecordBegin(state); } internal Processor.OutputResult TextEvent(int state, string text, bool disableOutputEscaping) { if (! CanOutput(state)) { return Processor.OutputResult.Overflow; } Debug.Assert(this.recordState == NoRecord || (state & StateMachine.BeginRecord) == 0); AdjustDepth(state); ResetRecord(state); PopElementScope(); if ((state & StateMachine.BeginRecord) != 0) { this.currentInfo.Depth = this.recordDepth; this.currentInfo.NodeType = XmlNodeType.Text; } ValueAppend(text, disableOutputEscaping); return CheckRecordBegin(state); } internal Processor.OutputResult EndEvent(int state, XPathNodeType nodeType) { if (! CanOutput(state)) { return Processor.OutputResult.Overflow; } AdjustDepth(state); PopElementScope(); this.popScope = (state & StateMachine.PopScope) != 0; if ((state & StateMachine.EmptyTag) != 0 && this.mainNode.IsEmptyTag == true) { return Processor.OutputResult.Continue; } ResetRecord(state); if ((state & StateMachine.BeginRecord) != 0) { if(nodeType == XPathNodeType.Element) { EndElement(); } } return CheckRecordEnd(state); } internal void Reset() { if (this.recordState == HaveRecord) { this.recordState = NoRecord; } } internal void TheEnd() { if (this.recordState == SomeRecord) { this.recordState = HaveRecord; FinalizeRecord(); this.output.RecordDone(this); } this.output.TheEnd(); } // // Utility implementation methods // private int FindAttribute(string name, string nspace, ref string prefix) { Debug.Assert(this.attributeCount <= this.attributeList.Count); for (int attrib = 0; attrib < this.attributeCount; attrib ++) { Debug.Assert(this.attributeList[attrib] != null && this.attributeList[attrib] is BuilderInfo); BuilderInfo attribute = (BuilderInfo) this.attributeList[attrib]; if (Keywords.Equals(attribute.LocalName, name)) { if (Keywords.Equals(attribute.NamespaceURI, nspace)) { return attrib; } if (Keywords.Equals(attribute.Prefix, prefix)) { // prefix conflict. Should be renamed. prefix = string.Empty; } } } return -1; } private void BeginElement(string prefix, string name, string nspace, bool empty) { Debug.Assert(this.attributeCount == 0); this.currentInfo.NodeType = XmlNodeType.Element; this.currentInfo.Prefix = prefix; this.currentInfo.LocalName = name; this.currentInfo.NamespaceURI = nspace; this.currentInfo.Depth = this.recordDepth; this.currentInfo.IsEmptyTag = empty; this.scopeManager.PushScope(name, nspace, prefix); } private void EndElement() { Debug.Assert(this.attributeCount == 0); OutputScope elementScope = this.scopeManager.CurrentElementScope; this.currentInfo.NodeType = XmlNodeType.EndElement; this.currentInfo.Prefix = elementScope.Prefix; this.currentInfo.LocalName = elementScope.Name; this.currentInfo.NamespaceURI = elementScope.Namespace; this.currentInfo.Depth = this.recordDepth; } private int NewAttribute() { if (this.attributeCount >= this.attributeList.Count) { Debug.Assert(this.attributeCount == this.attributeList.Count); this.attributeList.Add(new BuilderInfo()); } return this.attributeCount ++; } private void BeginAttribute(string prefix, string name, string nspace, Object htmlAttrProps, bool search) { int attrib = FindAttribute(name, nspace, ref prefix); if (attrib == -1) { attrib = NewAttribute(); } Debug.Assert(this.attributeList[attrib] != null && this.attributeList[attrib] is BuilderInfo); BuilderInfo attribute = (BuilderInfo) this.attributeList[attrib]; attribute.Initialize(prefix, name, nspace); attribute.Depth = this.recordDepth; attribute.NodeType = XmlNodeType.Attribute; attribute.htmlAttrProps = htmlAttrProps as HtmlAttributeProps; attribute.search = search; this.currentInfo = attribute; } private void BeginNamespace(string name, string nspace) { bool thisScope = false; if (Keywords.Equals(name, this.atoms.Empty)) { if (Keywords.Equals(nspace, this.scopeManager.DefaultNamespace)) { // Main Node is OK } else if (Keywords.Equals(this.mainNode.NamespaceURI, this.atoms.Empty)) { // http://www.w3.org/1999/11/REC-xslt-19991116-errata/ E25 // Should throw an error but ingnoring it in Everett. // Would be a breaking change } else { DeclareNamespace(nspace, name); } } else { string nspaceDeclared = this.scopeManager.ResolveNamespace(name, out thisScope); if (nspaceDeclared != null) { if (! Keywords.Equals(nspace, nspaceDeclared)) { if(!thisScope) { DeclareNamespace(nspace, name); } } } else { DeclareNamespace(nspace, name); } } this.currentInfo = dummy; currentInfo.NodeType = XmlNodeType.Attribute; } private bool BeginProcessingInstruction(string prefix, string name, string nspace) { this.currentInfo.NodeType = XmlNodeType.ProcessingInstruction; this.currentInfo.Prefix = prefix; this.currentInfo.LocalName = name; this.currentInfo.NamespaceURI = nspace; this.currentInfo.Depth = this.recordDepth; return true; } private void BeginComment() { this.currentInfo.NodeType = XmlNodeType.Comment; this.currentInfo.Depth = this.recordDepth; } private void AdjustDepth(int state) { switch (state & StateMachine.DepthMask) { case StateMachine.DepthUp: this.recordDepth ++; break; case StateMachine.DepthDown: this.recordDepth --; break; default: break; } } private void ResetRecord(int state) { Debug.Assert(this.recordState == NoRecord || this.recordState == SomeRecord); if ((state & StateMachine.BeginRecord) != 0) { this.attributeCount = 0; this.namespaceCount = 0; this.currentInfo = this.mainNode; this.currentInfo.Initialize(this.atoms.Empty, this.atoms.Empty, this.atoms.Empty); this.currentInfo.NodeType = XmlNodeType.None; this.currentInfo.IsEmptyTag = false; this.currentInfo.htmlProps = null; this.currentInfo.htmlAttrProps = null; } } private void PopElementScope() { if (this.popScope) { this.scopeManager.PopScope(); this.popScope = false; } } private Processor.OutputResult CheckRecordBegin(int state) { Debug.Assert(this.recordState == NoRecord || this.recordState == SomeRecord); if ((state & StateMachine.EndRecord) != 0) { this.recordState = HaveRecord; FinalizeRecord(); SetEmptyFlag(state); return this.output.RecordDone(this); } else { this.recordState = SomeRecord; return Processor.OutputResult.Continue; } } private Processor.OutputResult CheckRecordEnd(int state) { Debug.Assert(this.recordState == NoRecord || this.recordState == SomeRecord); if ((state & StateMachine.EndRecord) != 0) { this.recordState = HaveRecord; FinalizeRecord(); SetEmptyFlag(state); return this.output.RecordDone(this); } else { // For end event, if there is no end token, don't force token return Processor.OutputResult.Continue; } } private void SetEmptyFlag(int state) { Debug.Assert(this.mainNode != null); if ((state & StateMachine.BeginChild) != 0) { this.mainNode.IsEmptyTag = false; } } private void AnalyzeSpaceLang() { Debug.Assert(this.mainNode.NodeType == XmlNodeType.Element); for (int attr = 0; attr < this.attributeCount; attr ++) { Debug.Assert(this.attributeList[attr] is BuilderInfo); BuilderInfo info = (BuilderInfo) this.attributeList[attr]; if (Keywords.Equals(info.Prefix, this.atoms.Xml)) { OutputScope scope = this.scopeManager.CurrentElementScope; if (Keywords.Equals(info.LocalName, this.atoms.Lang)) { scope.Lang = info.Value; } else if (Keywords.Equals(info.LocalName, this.atoms.Space)) { scope.Space = TranslateXmlSpace(info.Value); } } } } private void FixupElement() { Debug.Assert(this.mainNode.NodeType == XmlNodeType.Element); if (Keywords.Equals(this.mainNode.NamespaceURI, this.atoms.Empty)) { this.mainNode.Prefix = this.atoms.Empty; } if (Keywords.Equals(this.mainNode.Prefix, this.atoms.Empty)) { if (Keywords.Equals(this.mainNode.NamespaceURI, this.scopeManager.DefaultNamespace)) { // Main Node is OK } else { DeclareNamespace(this.mainNode.NamespaceURI, this.mainNode.Prefix); } } else { bool thisScope = false; string nspace = this.scopeManager.ResolveNamespace(this.mainNode.Prefix, out thisScope); if (nspace != null) { if (! Keywords.Equals(this.mainNode.NamespaceURI, nspace)) { if (thisScope) { // Prefix conflict this.mainNode.Prefix = GetPrefixForNamespace(this.mainNode.NamespaceURI); } else { DeclareNamespace(this.mainNode.NamespaceURI, this.mainNode.Prefix); } } } else { DeclareNamespace(this.mainNode.NamespaceURI, this.mainNode.Prefix); } } OutputScope elementScope = this.scopeManager.CurrentElementScope; elementScope.Prefix = this.mainNode.Prefix; } private void FixupAttributes(int attributeCount) { for (int attr = 0; attr < attributeCount; attr ++) { Debug.Assert(this.attributeList[attr] is BuilderInfo); BuilderInfo info = (BuilderInfo) this.attributeList[attr]; if (Keywords.Equals(info.NamespaceURI, this.atoms.Empty)) { info.Prefix = this.atoms.Empty; } else { if (Keywords.Equals(info.Prefix, this.atoms.Empty)) { info.Prefix = GetPrefixForNamespace(info.NamespaceURI); } else { bool thisScope = false; string nspace = this.scopeManager.ResolveNamespace(info.Prefix, out thisScope); if (nspace != null) { if (! Keywords.Equals(info.NamespaceURI, nspace)) { if(thisScope) { // prefix conflict info.Prefix = GetPrefixForNamespace(info.NamespaceURI); } else { DeclareNamespace(info.NamespaceURI, info.Prefix); } } } else { DeclareNamespace(info.NamespaceURI, info.Prefix); } } } } } private void AppendNamespaces() { for (int i = this.namespaceCount - 1; i >= 0; i --) { BuilderInfo attribute = (BuilderInfo) this.attributeList[NewAttribute()]; attribute.Initialize((BuilderInfo)this.namespaceList[i]); } } private void AnalyzeComment() { Debug.Assert(this.mainNode.NodeType == XmlNodeType.Comment); Debug.Assert((object) this.currentInfo == (object) this.mainNode); StringBuilder newComment = null; string comment = this.mainNode.Value; bool minus = false; int index = 0, begin = 0; for (; index < comment.Length; index ++) { switch (comment[index]) { case s_Minus: if (minus) { if (newComment == null) newComment = new StringBuilder(comment, begin, index, 2 * comment.Length); else newComment.Append(comment, begin, index - begin); newComment.Append(s_SpaceMinus); begin = index + 1; } minus = true; break; default: minus = false; break; } } if (newComment != null) { if (begin < comment.Length) newComment.Append(comment, begin, comment.Length - begin); if (minus) newComment.Append(s_Space); this.mainNode.Value = newComment.ToString(); } else if (minus) { this.mainNode.ValueAppend(s_Space, false); } } private void AnalyzeProcessingInstruction() { Debug.Assert(this.mainNode.NodeType == XmlNodeType.ProcessingInstruction || this.mainNode.NodeType == XmlNodeType.XmlDeclaration); //Debug.Assert((object) this.currentInfo == (object) this.mainNode); StringBuilder newPI = null; string pi = this.mainNode.Value; bool question = false; int index = 0, begin = 0; for (; index < pi.Length; index ++) { switch (pi[index]) { case s_Question: question = true; break; case s_Greater: if (question) { if (newPI == null) { newPI = new StringBuilder(pi, begin, index, 2 * pi.Length); } else { newPI.Append(pi, begin, index - begin); } newPI.Append(s_SpaceGreater); begin = index + 1; } question = false; break; default: question = false; break; } } if (newPI != null) { if (begin < pi.Length) { newPI.Append(pi, begin, pi.Length - begin); } this.mainNode.Value = newPI.ToString(); } } private void FinalizeRecord() { switch (this.mainNode.NodeType) { case XmlNodeType.Element: // Save count since FixupElement can add attribute... int attributeCount = this.attributeCount; FixupElement(); FixupAttributes(attributeCount); AnalyzeSpaceLang(); AppendNamespaces(); break; case XmlNodeType.Comment: AnalyzeComment(); break; case XmlNodeType.ProcessingInstruction: AnalyzeProcessingInstruction(); break; } } private int NewNamespace() { if (this.namespaceCount >= this.namespaceList.Count) { Debug.Assert(this.namespaceCount == this.namespaceList.Count); this.namespaceList.Add(new BuilderInfo()); } return this.namespaceCount ++; } private void DeclareNamespace(string nspace, string prefix) { int index = NewNamespace(); Debug.Assert(this.namespaceList[index] != null && this.namespaceList[index] is BuilderInfo); BuilderInfo ns = (BuilderInfo) this.namespaceList[index]; if (prefix == this.atoms.Empty) { ns.Initialize(this.atoms.Empty, this.atoms.Xmlns, this.atoms.XmlnsNamespace); } else { ns.Initialize(this.atoms.Xmlns, prefix, this.atoms.XmlnsNamespace); } ns.Depth = this.recordDepth; ns.NodeType = XmlNodeType.Attribute; ns.Value = nspace; this.scopeManager.PushNamespace(prefix, nspace); } private string DeclareNewNamespace(string nspace) { string prefix = this.scopeManager.GeneratePrefix(PrefixFormat); DeclareNamespace(nspace, prefix); return prefix; } internal string GetPrefixForNamespace(string nspace) { string prefix = null; if (this.scopeManager.FindPrefix(nspace, out prefix)) { Debug.Assert(prefix != null && prefix.Length > 0); return prefix; } else { return DeclareNewNamespace(nspace); } } private static XmlSpace TranslateXmlSpace(string space) { if (Keywords.Compare(space, s_SpaceDefault)) { return XmlSpace.Default; } else if (Keywords.Compare(space, s_SpacePreserve)) { return XmlSpace.Preserve; } else { return XmlSpace.None; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SecureEnvironment.cs
- ListViewSelectEventArgs.cs
- BindingExpressionBase.cs
- FixedSchema.cs
- StreamBodyWriter.cs
- ToolboxService.cs
- LocalizabilityAttribute.cs
- ZipIOExtraFieldElement.cs
- Application.cs
- AttributeCallbackBuilder.cs
- SynthesizerStateChangedEventArgs.cs
- ValidatorCollection.cs
- KeyboardInputProviderAcquireFocusEventArgs.cs
- VersionUtil.cs
- VirtualizingStackPanel.cs
- ServiceDeploymentInfo.cs
- PageRanges.cs
- XmlnsCache.cs
- XmlSerializationReader.cs
- ProcessRequestArgs.cs
- XmlNamespaceMappingCollection.cs
- RayHitTestParameters.cs
- EDesignUtil.cs
- DataControlLinkButton.cs
- FrameworkContentElement.cs
- RightsManagementEncryptedStream.cs
- Stylesheet.cs
- ClientUtils.cs
- PaperSize.cs
- FormsAuthenticationUser.cs
- SynchronizationLockException.cs
- FileUtil.cs
- StylusShape.cs
- ClientSettingsSection.cs
- EntityUtil.cs
- DocumentSchemaValidator.cs
- ReferentialConstraint.cs
- CodeCastExpression.cs
- LoginDesignerUtil.cs
- Command.cs
- EventNotify.cs
- x509utils.cs
- BitmapMetadata.cs
- TextProperties.cs
- PenThreadPool.cs
- Evaluator.cs
- ColumnCollection.cs
- CompressedStack.cs
- XsltSettings.cs
- XmlSchemaSimpleTypeRestriction.cs
- EventData.cs
- DefaultHttpHandler.cs
- WaitForChangedResult.cs
- KeyFrames.cs
- DbExpressionVisitor_TResultType.cs
- InternalTypeHelper.cs
- DataShape.cs
- GrammarBuilderWildcard.cs
- ConnectionInterfaceCollection.cs
- ToolStripDropTargetManager.cs
- InternalMappingException.cs
- XmlArrayItemAttribute.cs
- SelectingProviderEventArgs.cs
- WindowsEditBoxRange.cs
- MimeObjectFactory.cs
- RadioButtonRenderer.cs
- _LocalDataStoreMgr.cs
- ProxyHelper.cs
- XNodeValidator.cs
- UriWriter.cs
- _IPv4Address.cs
- CatalogZoneAutoFormat.cs
- XmlQueryTypeFactory.cs
- AssociationSetMetadata.cs
- GlyphsSerializer.cs
- SurrogateEncoder.cs
- SqlDataSourceSelectingEventArgs.cs
- isolationinterop.cs
- EntityContainerRelationshipSetEnd.cs
- WindowShowOrOpenTracker.cs
- SchemaType.cs
- EventlogProvider.cs
- DbConnectionHelper.cs
- DiscoveryClientReferences.cs
- Timer.cs
- MatrixValueSerializer.cs
- XhtmlBasicValidationSummaryAdapter.cs
- BamlResourceContent.cs
- ValueType.cs
- CommandCollectionEditor.cs
- WebPartConnectionsCloseVerb.cs
- CommandPlan.cs
- MenuCommand.cs
- WmlPageAdapter.cs
- OleTxTransactionInfo.cs
- ManagementClass.cs
- TrackBar.cs
- ToolStripScrollButton.cs
- CompositeFontFamily.cs
- UTF7Encoding.cs