C14NUtil.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / clr / src / ManagedLibraries / Security / System / Security / Cryptography / Xml / C14NUtil.cs / 1 / C14NUtil.cs

                            // ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 

// 
// C14NUtil.cs 
//
 
namespace System.Security.Cryptography.Xml {
    using System;
    using System.Xml;
    using System.IO; 
    using System.Text;
    using System.Collections; 
 
    // the current rendering position in document
    internal enum DocPosition { 
        BeforeRootElement,
        InRootElement,
        AfterRootElement
    } 

    // the interface to be implemented by all subclasses of XmlNode 
    // that have to provide node subsetting and canonicalization features. 
    internal interface ICanonicalizableNode {
        bool IsInNodeSet { 
            get;
            set;
        }
 
        void Write(StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc);
        void WriteHash(HashAlgorithm hash, DocPosition docPos, AncestralNamespaceContextManager anc); 
    } 

    // the central dispatcher for canonicalization writes. not all node classes 
    // implement ICanonicalizableNode; so a manual dispatch is sometimes necessary.
    internal class CanonicalizationDispatcher {
        private CanonicalizationDispatcher() {}
 
        public static void Write(XmlNode node, StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc) {
            if (node is ICanonicalizableNode) { 
                ((ICanonicalizableNode) node).Write(strBuilder, docPos, anc); 
            } else {
                WriteGenericNode(node, strBuilder, docPos, anc); 
            }
        }

        public static void WriteGenericNode(XmlNode node, StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc) { 
            if (node == null)
                throw new ArgumentNullException("node"); 
 
            XmlNodeList childNodes = node.ChildNodes;
            foreach (XmlNode childNode in childNodes) { 
                Write(childNode, strBuilder, docPos, anc);
            }
        }
 
        public static void WriteHash(XmlNode node, HashAlgorithm hash, DocPosition docPos, AncestralNamespaceContextManager anc) {
            if (node is ICanonicalizableNode) { 
                ((ICanonicalizableNode) node).WriteHash(hash, docPos, anc); 
            } else {
                WriteHashGenericNode(node, hash, docPos, anc); 
            }
        }

        public static void WriteHashGenericNode(XmlNode node, HashAlgorithm hash, DocPosition docPos, AncestralNamespaceContextManager anc) { 
            if (node == null)
                throw new ArgumentNullException("node"); 
 
            XmlNodeList childNodes = node.ChildNodes;
            foreach (XmlNode childNode in childNodes) { 
                WriteHash(childNode, hash, docPos, anc);
            }
        }
    } 

    // all input types eventually lead to the creation of an XmlDocument document 
    // of this type. it maintains the node subset state and performs output rendering during canonicalization 
    internal class CanonicalXmlDocument : XmlDocument, ICanonicalizableNode {
        bool m_defaultNodeSetInclusionState; 
        bool m_includeComments;
        bool m_isInNodeSet;

        public CanonicalXmlDocument(bool defaultNodeSetInclusionState, bool includeComments) : base() { 
            this.PreserveWhitespace = true;
            m_includeComments = includeComments; 
            m_isInNodeSet = m_defaultNodeSetInclusionState = defaultNodeSetInclusionState; 
        }
 
        public bool IsInNodeSet {
            get { return m_isInNodeSet; }
            set { m_isInNodeSet = value; }
        } 

        public void Write(StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc) { 
            docPos = DocPosition.BeforeRootElement; 
            foreach (XmlNode childNode in this.ChildNodes) {
                if (childNode.NodeType == XmlNodeType.Element) { 
                    CanonicalizationDispatcher.Write(childNode, strBuilder, DocPosition.InRootElement, anc);
                    docPos = DocPosition.AfterRootElement;
                } else {
                    CanonicalizationDispatcher.Write(childNode, strBuilder, docPos, anc); 
                }
            } 
        } 

        public void WriteHash(HashAlgorithm hash, DocPosition docPos, AncestralNamespaceContextManager anc) { 
            docPos = DocPosition.BeforeRootElement;
            foreach (XmlNode childNode in this.ChildNodes) {
                if (childNode.NodeType == XmlNodeType.Element) {
                    CanonicalizationDispatcher.WriteHash(childNode, hash, DocPosition.InRootElement, anc); 
                    docPos = DocPosition.AfterRootElement;
                } else { 
                    CanonicalizationDispatcher.WriteHash(childNode, hash, docPos, anc); 
                }
            } 
        }

        public override XmlElement CreateElement(string prefix, string localName, string namespaceURI) {
            return new CanonicalXmlElement(prefix, localName, namespaceURI, this, m_defaultNodeSetInclusionState); 
        }
 
        public override XmlAttribute CreateAttribute(string prefix, string localName, string namespaceURI) { 
            return new CanonicalXmlAttribute(prefix, localName, namespaceURI, this, m_defaultNodeSetInclusionState);
        } 

        protected override XmlAttribute CreateDefaultAttribute(string prefix, string localName, string namespaceURI) {
            return new CanonicalXmlAttribute(prefix, localName, namespaceURI, this, m_defaultNodeSetInclusionState);
        } 

        public override XmlText CreateTextNode(string text) { 
            return new CanonicalXmlText(text, this, m_defaultNodeSetInclusionState); 
        }
 
        public override XmlWhitespace CreateWhitespace(string prefix) {
            return new CanonicalXmlWhitespace(prefix, this, m_defaultNodeSetInclusionState);
        }
 
        public override XmlSignificantWhitespace CreateSignificantWhitespace(string text) {
            return new CanonicalXmlSignificantWhitespace(text, this, m_defaultNodeSetInclusionState); 
        } 

        public override XmlProcessingInstruction CreateProcessingInstruction(string target, string data) { 
            return new CanonicalXmlProcessingInstruction(target, data, this, m_defaultNodeSetInclusionState);
        }

        public override XmlComment CreateComment(string data) { 
            return new CanonicalXmlComment(data, this, m_defaultNodeSetInclusionState, m_includeComments);
        } 
 
        public override XmlEntityReference CreateEntityReference(string name) {
            return new CanonicalXmlEntityReference(name, this, m_defaultNodeSetInclusionState); 
        }

        public override XmlCDataSection CreateCDataSection(string data) {
            return new CanonicalXmlCDataSection(data, this, m_defaultNodeSetInclusionState); 
        }
    } 
 
    // the class that provides node subset state and canonicalization function to XmlElement
    internal class CanonicalXmlElement : XmlElement, ICanonicalizableNode { 
        private bool m_isInNodeSet;

        public CanonicalXmlElement(string prefix, string localName, string namespaceURI, XmlDocument doc, bool defaultNodeSetInclusionState)
            : base(prefix, localName, namespaceURI, doc) { 
            m_isInNodeSet = defaultNodeSetInclusionState;
        } 
 
        public bool IsInNodeSet {
            get { return m_isInNodeSet; } 
            set { m_isInNodeSet = value; }
        }

        public void Write(StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc) { 
            Hashtable nsLocallyDeclared = new Hashtable();
            SortedList nsListToRender = new SortedList(new NamespaceSortOrder()); 
            SortedList attrListToRender = new SortedList(new AttributeSortOrder()); 

            XmlAttributeCollection attrList = this.Attributes; 
            if (attrList != null) {
                foreach (XmlAttribute attr in attrList) {
                    if (((CanonicalXmlAttribute) attr).IsInNodeSet || Utils.IsNamespaceNode(attr) || Utils.IsXmlNamespaceNode(attr)) {
                        if (Utils.IsNamespaceNode(attr)) { 
                            anc.TrackNamespaceNode(attr, nsListToRender, nsLocallyDeclared);
                        } 
                        else if (Utils.IsXmlNamespaceNode(attr)) { 
                            anc.TrackXmlNamespaceNode(attr, nsListToRender, attrListToRender, nsLocallyDeclared);
                        } 
                        else if (IsInNodeSet) {
                            attrListToRender.Add(attr, null);
                        }
                    } 
                }
            } 
 
            if (!Utils.IsCommittedNamespace(this, this.Prefix, this.NamespaceURI)) {
                string name = ((this.Prefix.Length > 0) ? "xmlns" + ":" + this.Prefix : "xmlns"); 
                XmlAttribute nsattrib = (XmlAttribute) this.OwnerDocument.CreateAttribute(name);
                nsattrib.Value = this.NamespaceURI;
                anc.TrackNamespaceNode(nsattrib, nsListToRender, nsLocallyDeclared);
            } 

            if (IsInNodeSet) { 
                anc.GetNamespacesToRender(this, attrListToRender, nsListToRender, nsLocallyDeclared); 

                strBuilder.Append("<" + this.Name); 
                foreach (object attr in nsListToRender.GetKeyList()) {
                    (attr as CanonicalXmlAttribute).Write(strBuilder, docPos, anc);
                }
                foreach (object attr in attrListToRender.GetKeyList()) { 
                    (attr as CanonicalXmlAttribute).Write(strBuilder, docPos, anc);
                } 
                strBuilder.Append(">"); 
            }
 
            anc.EnterElementContext();
            anc.LoadUnrenderedNamespaces(nsLocallyDeclared);
            anc.LoadRenderedNamespaces(nsListToRender);
 
            XmlNodeList childNodes = this.ChildNodes;
            foreach (XmlNode childNode in childNodes) { 
                CanonicalizationDispatcher.Write(childNode, strBuilder, docPos, anc); 
            }
 
            anc.ExitElementContext();

            if (IsInNodeSet) {
                strBuilder.Append(""); 
            }
        } 
 
        public void WriteHash(HashAlgorithm hash, DocPosition docPos, AncestralNamespaceContextManager anc) {
            Hashtable nsLocallyDeclared = new Hashtable(); 
            SortedList nsListToRender = new SortedList(new NamespaceSortOrder());
            SortedList attrListToRender = new SortedList(new AttributeSortOrder());
            UTF8Encoding utf8 = new UTF8Encoding(false);
            byte[] rgbData; 

            XmlAttributeCollection attrList = this.Attributes; 
            if (attrList != null) { 
                foreach (XmlAttribute attr in attrList) {
                    if (((CanonicalXmlAttribute) attr).IsInNodeSet || Utils.IsNamespaceNode(attr) || Utils.IsXmlNamespaceNode(attr)) { 
                        if (Utils.IsNamespaceNode(attr)) {
                            anc.TrackNamespaceNode(attr, nsListToRender, nsLocallyDeclared);
                        }
                        else if (Utils.IsXmlNamespaceNode(attr)) { 
                            anc.TrackXmlNamespaceNode(attr, nsListToRender, attrListToRender, nsLocallyDeclared);
                        } 
                        else if(IsInNodeSet) { 
                            attrListToRender.Add(attr, null);
                        } 
                    }
                }
            }
 
            if (!Utils.IsCommittedNamespace(this, this.Prefix, this.NamespaceURI)) {
                string name = ((this.Prefix.Length > 0) ? "xmlns" + ":" + this.Prefix : "xmlns"); 
                XmlAttribute nsattrib = (XmlAttribute) this.OwnerDocument.CreateAttribute(name); 
                nsattrib.Value = this.NamespaceURI;
                anc.TrackNamespaceNode(nsattrib, nsListToRender, nsLocallyDeclared); 
            }

            if (IsInNodeSet) {
                anc.GetNamespacesToRender(this, attrListToRender, nsListToRender, nsLocallyDeclared); 
                rgbData = utf8.GetBytes("<" + this.Name);
                hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0); 
                foreach (object attr in nsListToRender.GetKeyList()) { 
                    (attr as CanonicalXmlAttribute).WriteHash(hash, docPos, anc);
                } 
                foreach (object attr in attrListToRender.GetKeyList()) {
                    (attr as CanonicalXmlAttribute).WriteHash(hash, docPos, anc);
                }
                rgbData = utf8.GetBytes(">"); 
                hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0);
            } 
 
            anc.EnterElementContext();
            anc.LoadUnrenderedNamespaces(nsLocallyDeclared); 
            anc.LoadRenderedNamespaces(nsListToRender);

            XmlNodeList childNodes = this.ChildNodes;
            foreach (XmlNode childNode in childNodes) { 
                CanonicalizationDispatcher.WriteHash(childNode, hash, docPos, anc);
            } 
 
            anc.ExitElementContext();
 
            if (IsInNodeSet) {
                rgbData = utf8.GetBytes("");
                hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0);
            } 
        }
    } 
 
    // the class that provides node subset state and canonicalization function to XmlAttribute
    internal class CanonicalXmlAttribute : XmlAttribute, ICanonicalizableNode { 
        private bool m_isInNodeSet;

        public CanonicalXmlAttribute(string prefix, string localName, string namespaceURI, XmlDocument doc, bool defaultNodeSetInclusionState)
            : base(prefix, localName, namespaceURI, doc) { 
            IsInNodeSet = defaultNodeSetInclusionState;
        } 
 
        public bool IsInNodeSet {
            get { return m_isInNodeSet; } 
            set { m_isInNodeSet = value; }
        }

        public void Write(StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc) { 
            strBuilder.Append(" " + this.Name + "=\"");
            strBuilder.Append(Utils.EscapeAttributeValue(this.Value)); 
            strBuilder.Append("\""); 
        }
 
        public void WriteHash(HashAlgorithm hash, DocPosition docPos, AncestralNamespaceContextManager anc) {
            UTF8Encoding utf8 = new UTF8Encoding(false);
            byte[] rgbData = utf8.GetBytes(" " + this.Name + "=\"");
            hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0); 
            rgbData = utf8.GetBytes(Utils.EscapeAttributeValue(this.Value));
            hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0); 
            rgbData = utf8.GetBytes("\""); 
            hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0);
        } 
    }

    // the class that provides node subset state and canonicalization function to XmlText
    internal class CanonicalXmlText : XmlText, ICanonicalizableNode { 
        private bool m_isInNodeSet;
 
        public CanonicalXmlText(string strData, XmlDocument doc, bool defaultNodeSetInclusionState) 
            : base(strData, doc) {
            m_isInNodeSet = defaultNodeSetInclusionState; 
        }

        public bool IsInNodeSet {
            get { return m_isInNodeSet; } 
            set { m_isInNodeSet = value; }
        } 
 
        public void Write(StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc) {
            if (IsInNodeSet) 
                strBuilder.Append(Utils.EscapeTextData(this.Value));
        }

        public void WriteHash(HashAlgorithm hash, DocPosition docPos, AncestralNamespaceContextManager anc) { 
            if (IsInNodeSet) {
                UTF8Encoding utf8 = new UTF8Encoding(false); 
                byte[] rgbData = utf8.GetBytes(Utils.EscapeTextData(this.Value)); 
                hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0);
            } 
        }
    }

    // the class that provides node subset state and canonicalization function to XmlWhitespace 
    internal class CanonicalXmlWhitespace : XmlWhitespace, ICanonicalizableNode {
        private bool m_isInNodeSet; 
 
        public CanonicalXmlWhitespace(string strData, XmlDocument doc, bool defaultNodeSetInclusionState)
            : base(strData, doc) { 
            m_isInNodeSet = defaultNodeSetInclusionState;
        }

        public bool IsInNodeSet { 
            get { return m_isInNodeSet; }
            set { m_isInNodeSet = value; } 
        } 

        public void Write(StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc) { 
            if (IsInNodeSet && docPos == DocPosition.InRootElement)
                strBuilder.Append(Utils.EscapeWhitespaceData(this.Value));
        }
 
        public void WriteHash(HashAlgorithm hash, DocPosition docPos, AncestralNamespaceContextManager anc) {
            if (IsInNodeSet && docPos == DocPosition.InRootElement) { 
                UTF8Encoding utf8 = new UTF8Encoding(false); 
                byte[] rgbData = utf8.GetBytes(Utils.EscapeWhitespaceData(this.Value));
                hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0); 
            }
        }
    }
 
    // the class that provides node subset state and canonicalization function to XmlSignificantWhitespace
    internal class CanonicalXmlSignificantWhitespace : XmlSignificantWhitespace, ICanonicalizableNode { 
        private bool m_isInNodeSet; 

        public CanonicalXmlSignificantWhitespace(string strData, XmlDocument doc, bool defaultNodeSetInclusionState) 
            : base(strData, doc) {
            m_isInNodeSet = defaultNodeSetInclusionState;
        }
 
        public bool IsInNodeSet {
            get { return m_isInNodeSet; } 
            set { m_isInNodeSet = value; } 
        }
 
        public void Write(StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc) {
            if (IsInNodeSet && docPos == DocPosition.InRootElement)
                strBuilder.Append(Utils.EscapeWhitespaceData(this.Value));
        } 

        public void WriteHash(HashAlgorithm hash, DocPosition docPos, AncestralNamespaceContextManager anc) { 
            if (IsInNodeSet && docPos == DocPosition.InRootElement) { 
                UTF8Encoding utf8 = new UTF8Encoding(false);
                byte[] rgbData = utf8.GetBytes(Utils.EscapeWhitespaceData(this.Value)); 
                hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0);
            }
        }
    } 

    // the class that provides node subset state and canonicalization function to XmlComment 
    internal class CanonicalXmlComment : XmlComment, ICanonicalizableNode { 
        private bool m_isInNodeSet;
        private bool m_includeComments; 

        public CanonicalXmlComment(string comment, XmlDocument doc, bool defaultNodeSetInclusionState, bool includeComments)
            : base(comment, doc) {
            m_isInNodeSet = defaultNodeSetInclusionState; 
            m_includeComments = includeComments;
        } 
 
        public bool IsInNodeSet {
            get { return m_isInNodeSet; } 
            set { m_isInNodeSet = value; }
        }

        public bool IncludeComments { 
            get { return m_includeComments; }
        } 
 
        public void Write(StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc) {
            if (!IsInNodeSet || !IncludeComments) 
                return;

            if (docPos == DocPosition.AfterRootElement)
                strBuilder.Append((char) 10); 
            strBuilder.Append(""); 
            if (docPos == DocPosition.BeforeRootElement)
                strBuilder.Append((char) 10); 
        }

        public void WriteHash(HashAlgorithm hash, DocPosition docPos, AncestralNamespaceContextManager anc) {
            if (!IsInNodeSet || !IncludeComments) 
                return;
 
            UTF8Encoding utf8 = new UTF8Encoding(false); 
            byte[] rgbData = utf8.GetBytes("(char) 10");
            if (docPos == DocPosition.AfterRootElement) 
                hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0);
            rgbData = utf8.GetBytes(""); 
            hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0); 
            if (docPos == DocPosition.BeforeRootElement) {
                rgbData = utf8.GetBytes("(char) 10"); 
                hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0);
            }
        }
    } 

 
 
    // the class that provides node subset state and canonicalization function to XmlProcessingInstruction
    internal class CanonicalXmlProcessingInstruction : XmlProcessingInstruction, ICanonicalizableNode { 
        private bool m_isInNodeSet;

        public CanonicalXmlProcessingInstruction(string target, string data, XmlDocument doc, bool defaultNodeSetInclusionState)
            : base(target, data, doc) { 
            m_isInNodeSet = defaultNodeSetInclusionState;
        } 
 
        public bool IsInNodeSet {
            get { return m_isInNodeSet; } 
            set { m_isInNodeSet = value; }
        }

        public void Write(StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc) { 
            if (!IsInNodeSet)
                return; 
 
            if (docPos == DocPosition.AfterRootElement)
                strBuilder.Append((char) 10); 
            strBuilder.Append(" 0))
                strBuilder.Append(" " + this.Value); 
            strBuilder.Append("?>");
            if (docPos == DocPosition.BeforeRootElement) 
                strBuilder.Append((char) 10); 
        }
 
        public void WriteHash(HashAlgorithm hash, DocPosition docPos, AncestralNamespaceContextManager anc) {
            if (!IsInNodeSet)
                return;
 
            UTF8Encoding utf8 = new UTF8Encoding(false);
            byte[] rgbData; 
            if (docPos == DocPosition.AfterRootElement) { 
                rgbData = utf8.GetBytes("(char) 10");
                hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0); 
            }
            rgbData = utf8.GetBytes(" 0)) { 
                rgbData = utf8.GetBytes(" " + this.Value); 
                hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0);
            } 
            rgbData = utf8.GetBytes("?>");
            hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0);
            if (docPos == DocPosition.BeforeRootElement) {
                rgbData = utf8.GetBytes("(char) 10"); 
                hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0);
            } 
        } 
    }
 


    // the class that provides node subset state and canonicalization function to XmlEntityReference
    internal class CanonicalXmlEntityReference : XmlEntityReference, ICanonicalizableNode { 
        private bool m_isInNodeSet;
 
        public CanonicalXmlEntityReference(string name, XmlDocument doc, bool defaultNodeSetInclusionState) 
            : base(name, doc) {
            m_isInNodeSet = defaultNodeSetInclusionState; 
        }

        public bool IsInNodeSet {
            get { return m_isInNodeSet; } 
            set { m_isInNodeSet = value; }
        } 
 
        public void Write(StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc) {
            if (IsInNodeSet) 
                CanonicalizationDispatcher.WriteGenericNode(this, strBuilder, docPos, anc);
        }

        public void WriteHash(HashAlgorithm hash, DocPosition docPos, AncestralNamespaceContextManager anc) { 
            if (IsInNodeSet)
                CanonicalizationDispatcher.WriteHashGenericNode(this, hash, docPos, anc); 
        } 
    }
 
    // the class that provides node subset state and canonicalization function to XmlCDataSection
    internal class CanonicalXmlCDataSection: XmlCDataSection, ICanonicalizableNode {
        private bool m_isInNodeSet;
        public CanonicalXmlCDataSection(string data, XmlDocument doc, bool defaultNodeSetInclusionState) : base(data, doc) { 
            m_isInNodeSet = defaultNodeSetInclusionState;
        } 
 
        public bool IsInNodeSet {
            get { return m_isInNodeSet; } 
            set { m_isInNodeSet = value; }
        }

        public void Write(StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc) { 
            if (IsInNodeSet)
                strBuilder.Append(Utils.EscapeCData(this.Data)); 
        } 

        public void WriteHash(HashAlgorithm hash, DocPosition docPos, AncestralNamespaceContextManager anc) { 
            if (IsInNodeSet) {
                UTF8Encoding utf8 = new UTF8Encoding(false);
                byte[] rgbData = utf8.GetBytes(Utils.EscapeCData(this.Data));
                hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0); 
            }
        } 
    } 

    internal class CanonicalXmlNodeList : XmlNodeList, IList { 
        private ArrayList m_nodeArray;

        internal CanonicalXmlNodeList() {
            m_nodeArray = new ArrayList(); 
        }
 
        public override XmlNode Item(int index) { 
            return (XmlNode) m_nodeArray[index];
        } 

        public override IEnumerator GetEnumerator() {
            return m_nodeArray.GetEnumerator();
        } 

        public override int Count { 
            get { return m_nodeArray.Count; } 
        }
 
        // IList methods
        public int Add(Object value) {
            if (!(value is XmlNode))
                throw new ArgumentException(SecurityResources.GetResourceString("Cryptography_Xml_IncorrectObjectType"), "node"); 
            return m_nodeArray.Add(value);
        } 
 
        public void Clear() {
            m_nodeArray.Clear(); 
        }

        public bool Contains(Object value) {
            return m_nodeArray.Contains(value); 
        }
 
        public int IndexOf(Object value) { 
            return m_nodeArray.IndexOf(value);
        } 

        public void Insert(int index, Object value) {
            if (!(value is XmlNode))
                throw new ArgumentException(SecurityResources.GetResourceString("Cryptography_Xml_IncorrectObjectType"), "value"); 
            m_nodeArray.Insert(index,value);
        } 
 
        public void Remove(Object value) {
            m_nodeArray.Remove(value); 
        }

        public void RemoveAt(int index) {
            m_nodeArray.RemoveAt(index); 
        }
 
        public Boolean IsFixedSize { 
            get { return m_nodeArray.IsFixedSize; }
        } 

        public Boolean IsReadOnly {
            get { return m_nodeArray.IsReadOnly; }
        } 

        Object IList.this[int index] { 
            get { return m_nodeArray[index]; } 
            set {
                if (!(value is XmlNode)) 
                    throw new ArgumentException(SecurityResources.GetResourceString("Cryptography_Xml_IncorrectObjectType"), "value");
                m_nodeArray[index] = value;
            }
        } 

        public void CopyTo(Array array, int index) { 
            m_nodeArray.CopyTo(array, index); 
        }
 
        public Object SyncRoot {
            get { return m_nodeArray.SyncRoot; }
        }
 
        public bool IsSynchronized {
            get { return m_nodeArray.IsSynchronized; } 
        } 
    }
 
    // This class does lexicographic sorting by NamespaceURI first and then by LocalName.
    internal class AttributeSortOrder : IComparer {
        internal AttributeSortOrder() {}
 
        public int Compare(Object a, Object b) {
            XmlNode nodeA = a as XmlNode; 
            XmlNode nodeB = b as XmlNode; 
            if ((a == null) || (b == null))
                throw new ArgumentException(); 
            int namespaceCompare = String.CompareOrdinal(nodeA.NamespaceURI, nodeB.NamespaceURI);
            if (namespaceCompare != 0) return namespaceCompare;
            return String.CompareOrdinal(nodeA.LocalName, nodeB.LocalName);
        } 
    }
 
    internal class NamespaceSortOrder : IComparer { 
        internal NamespaceSortOrder() {}
 
        public int Compare(Object a, Object b) {
            XmlNode nodeA = a as XmlNode;
            XmlNode nodeB = b as XmlNode;
            if ((a == null) || (b == null)) 
                throw new ArgumentException();
            bool nodeAdefault = Utils.IsDefaultNamespaceNode(nodeA); 
            bool nodeBdefault = Utils.IsDefaultNamespaceNode(nodeB); 
            if (nodeAdefault && nodeBdefault) return 0;
            if (nodeAdefault) return -1; 
            if (nodeBdefault) return 1;
            return String.CompareOrdinal(nodeA.LocalName, nodeB.LocalName);
        }
    } 

    // the namespaces context corresponding to one XmlElement. the rendered list contains the namespace nodes that are actually 
    // rendered to the canonicalized output. the unrendered list contains the namespace nodes that are in the node set and have 
    // the XmlElement as the owner, but are not rendered.
    internal class NamespaceFrame { 
        private Hashtable m_rendered = new Hashtable();
        private Hashtable m_unrendered = new Hashtable();

        internal NamespaceFrame() {} 

        internal void AddRendered(XmlAttribute attr) { 
            m_rendered.Add(Utils.GetNamespacePrefix(attr), attr); 
        }
 
        internal XmlAttribute GetRendered(string nsPrefix) {
            return (XmlAttribute) m_rendered[nsPrefix];
        }
 
        internal void AddUnrendered(XmlAttribute attr) {
            m_unrendered.Add(Utils.GetNamespacePrefix(attr), attr); 
        } 

        internal XmlAttribute GetUnrendered(string nsPrefix) { 
            return (XmlAttribute) m_unrendered[nsPrefix];
        }

        internal Hashtable GetUnrendered() { 
            return m_unrendered;
        } 
    } 

    abstract internal class AncestralNamespaceContextManager { 
        internal ArrayList m_ancestorStack = new ArrayList();

        internal NamespaceFrame GetScopeAt(int i) {
            return (NamespaceFrame) m_ancestorStack[i]; 
        }
 
        internal NamespaceFrame GetCurrentScope() { 
            return GetScopeAt(m_ancestorStack.Count - 1);
        } 

        protected XmlAttribute GetNearestRenderedNamespaceWithMatchingPrefix(string nsPrefix, out int depth) {
            XmlAttribute attr = null;
            depth = -1; 
            for (int i = m_ancestorStack.Count - 1; i >= 0; i--) {
                if ((attr = GetScopeAt(i).GetRendered(nsPrefix)) != null) { 
                    depth = i; 
                    return attr;
                } 
            }
            return null;
        }
 
        protected XmlAttribute GetNearestUnrenderedNamespaceWithMatchingPrefix(string nsPrefix, out int depth) {
            XmlAttribute attr = null; 
            depth = -1; 
            for (int i = m_ancestorStack.Count - 1; i >= 0; i--) {
                if ((attr = GetScopeAt(i).GetUnrendered(nsPrefix)) != null) { 
                    depth = i;
                    return attr;
                }
            } 
            return null;
        } 
 
        internal void EnterElementContext() {
            m_ancestorStack.Add(new NamespaceFrame()); 
        }

        internal void ExitElementContext() {
            m_ancestorStack.RemoveAt(m_ancestorStack.Count - 1); 
        }
 
        internal abstract void TrackNamespaceNode(XmlAttribute attr, SortedList nsListToRender, Hashtable nsLocallyDeclared); 
        internal abstract void TrackXmlNamespaceNode(XmlAttribute attr, SortedList nsListToRender, SortedList attrListToRender, Hashtable nsLocallyDeclared);
        internal abstract void GetNamespacesToRender (XmlElement element, SortedList attrListToRender, SortedList nsListToRender, Hashtable nsLocallyDeclared); 

        internal void LoadUnrenderedNamespaces(Hashtable nsLocallyDeclared) {
            object[] attrs = new object[nsLocallyDeclared.Count];
            nsLocallyDeclared.Values.CopyTo(attrs, 0); 
            foreach (object attr in attrs) {
                AddUnrendered((XmlAttribute) attr); 
            } 
        }
 
        internal void LoadRenderedNamespaces(SortedList nsRenderedList) {
            foreach (object attr in nsRenderedList.GetKeyList()) {
                AddRendered((XmlAttribute) attr);
            } 
        }
 
        internal void AddRendered(XmlAttribute attr) { 
            GetCurrentScope().AddRendered(attr);
        } 

        internal void AddUnrendered(XmlAttribute attr) {
            GetCurrentScope().AddUnrendered(attr);
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 

// 
// C14NUtil.cs 
//
 
namespace System.Security.Cryptography.Xml {
    using System;
    using System.Xml;
    using System.IO; 
    using System.Text;
    using System.Collections; 
 
    // the current rendering position in document
    internal enum DocPosition { 
        BeforeRootElement,
        InRootElement,
        AfterRootElement
    } 

    // the interface to be implemented by all subclasses of XmlNode 
    // that have to provide node subsetting and canonicalization features. 
    internal interface ICanonicalizableNode {
        bool IsInNodeSet { 
            get;
            set;
        }
 
        void Write(StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc);
        void WriteHash(HashAlgorithm hash, DocPosition docPos, AncestralNamespaceContextManager anc); 
    } 

    // the central dispatcher for canonicalization writes. not all node classes 
    // implement ICanonicalizableNode; so a manual dispatch is sometimes necessary.
    internal class CanonicalizationDispatcher {
        private CanonicalizationDispatcher() {}
 
        public static void Write(XmlNode node, StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc) {
            if (node is ICanonicalizableNode) { 
                ((ICanonicalizableNode) node).Write(strBuilder, docPos, anc); 
            } else {
                WriteGenericNode(node, strBuilder, docPos, anc); 
            }
        }

        public static void WriteGenericNode(XmlNode node, StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc) { 
            if (node == null)
                throw new ArgumentNullException("node"); 
 
            XmlNodeList childNodes = node.ChildNodes;
            foreach (XmlNode childNode in childNodes) { 
                Write(childNode, strBuilder, docPos, anc);
            }
        }
 
        public static void WriteHash(XmlNode node, HashAlgorithm hash, DocPosition docPos, AncestralNamespaceContextManager anc) {
            if (node is ICanonicalizableNode) { 
                ((ICanonicalizableNode) node).WriteHash(hash, docPos, anc); 
            } else {
                WriteHashGenericNode(node, hash, docPos, anc); 
            }
        }

        public static void WriteHashGenericNode(XmlNode node, HashAlgorithm hash, DocPosition docPos, AncestralNamespaceContextManager anc) { 
            if (node == null)
                throw new ArgumentNullException("node"); 
 
            XmlNodeList childNodes = node.ChildNodes;
            foreach (XmlNode childNode in childNodes) { 
                WriteHash(childNode, hash, docPos, anc);
            }
        }
    } 

    // all input types eventually lead to the creation of an XmlDocument document 
    // of this type. it maintains the node subset state and performs output rendering during canonicalization 
    internal class CanonicalXmlDocument : XmlDocument, ICanonicalizableNode {
        bool m_defaultNodeSetInclusionState; 
        bool m_includeComments;
        bool m_isInNodeSet;

        public CanonicalXmlDocument(bool defaultNodeSetInclusionState, bool includeComments) : base() { 
            this.PreserveWhitespace = true;
            m_includeComments = includeComments; 
            m_isInNodeSet = m_defaultNodeSetInclusionState = defaultNodeSetInclusionState; 
        }
 
        public bool IsInNodeSet {
            get { return m_isInNodeSet; }
            set { m_isInNodeSet = value; }
        } 

        public void Write(StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc) { 
            docPos = DocPosition.BeforeRootElement; 
            foreach (XmlNode childNode in this.ChildNodes) {
                if (childNode.NodeType == XmlNodeType.Element) { 
                    CanonicalizationDispatcher.Write(childNode, strBuilder, DocPosition.InRootElement, anc);
                    docPos = DocPosition.AfterRootElement;
                } else {
                    CanonicalizationDispatcher.Write(childNode, strBuilder, docPos, anc); 
                }
            } 
        } 

        public void WriteHash(HashAlgorithm hash, DocPosition docPos, AncestralNamespaceContextManager anc) { 
            docPos = DocPosition.BeforeRootElement;
            foreach (XmlNode childNode in this.ChildNodes) {
                if (childNode.NodeType == XmlNodeType.Element) {
                    CanonicalizationDispatcher.WriteHash(childNode, hash, DocPosition.InRootElement, anc); 
                    docPos = DocPosition.AfterRootElement;
                } else { 
                    CanonicalizationDispatcher.WriteHash(childNode, hash, docPos, anc); 
                }
            } 
        }

        public override XmlElement CreateElement(string prefix, string localName, string namespaceURI) {
            return new CanonicalXmlElement(prefix, localName, namespaceURI, this, m_defaultNodeSetInclusionState); 
        }
 
        public override XmlAttribute CreateAttribute(string prefix, string localName, string namespaceURI) { 
            return new CanonicalXmlAttribute(prefix, localName, namespaceURI, this, m_defaultNodeSetInclusionState);
        } 

        protected override XmlAttribute CreateDefaultAttribute(string prefix, string localName, string namespaceURI) {
            return new CanonicalXmlAttribute(prefix, localName, namespaceURI, this, m_defaultNodeSetInclusionState);
        } 

        public override XmlText CreateTextNode(string text) { 
            return new CanonicalXmlText(text, this, m_defaultNodeSetInclusionState); 
        }
 
        public override XmlWhitespace CreateWhitespace(string prefix) {
            return new CanonicalXmlWhitespace(prefix, this, m_defaultNodeSetInclusionState);
        }
 
        public override XmlSignificantWhitespace CreateSignificantWhitespace(string text) {
            return new CanonicalXmlSignificantWhitespace(text, this, m_defaultNodeSetInclusionState); 
        } 

        public override XmlProcessingInstruction CreateProcessingInstruction(string target, string data) { 
            return new CanonicalXmlProcessingInstruction(target, data, this, m_defaultNodeSetInclusionState);
        }

        public override XmlComment CreateComment(string data) { 
            return new CanonicalXmlComment(data, this, m_defaultNodeSetInclusionState, m_includeComments);
        } 
 
        public override XmlEntityReference CreateEntityReference(string name) {
            return new CanonicalXmlEntityReference(name, this, m_defaultNodeSetInclusionState); 
        }

        public override XmlCDataSection CreateCDataSection(string data) {
            return new CanonicalXmlCDataSection(data, this, m_defaultNodeSetInclusionState); 
        }
    } 
 
    // the class that provides node subset state and canonicalization function to XmlElement
    internal class CanonicalXmlElement : XmlElement, ICanonicalizableNode { 
        private bool m_isInNodeSet;

        public CanonicalXmlElement(string prefix, string localName, string namespaceURI, XmlDocument doc, bool defaultNodeSetInclusionState)
            : base(prefix, localName, namespaceURI, doc) { 
            m_isInNodeSet = defaultNodeSetInclusionState;
        } 
 
        public bool IsInNodeSet {
            get { return m_isInNodeSet; } 
            set { m_isInNodeSet = value; }
        }

        public void Write(StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc) { 
            Hashtable nsLocallyDeclared = new Hashtable();
            SortedList nsListToRender = new SortedList(new NamespaceSortOrder()); 
            SortedList attrListToRender = new SortedList(new AttributeSortOrder()); 

            XmlAttributeCollection attrList = this.Attributes; 
            if (attrList != null) {
                foreach (XmlAttribute attr in attrList) {
                    if (((CanonicalXmlAttribute) attr).IsInNodeSet || Utils.IsNamespaceNode(attr) || Utils.IsXmlNamespaceNode(attr)) {
                        if (Utils.IsNamespaceNode(attr)) { 
                            anc.TrackNamespaceNode(attr, nsListToRender, nsLocallyDeclared);
                        } 
                        else if (Utils.IsXmlNamespaceNode(attr)) { 
                            anc.TrackXmlNamespaceNode(attr, nsListToRender, attrListToRender, nsLocallyDeclared);
                        } 
                        else if (IsInNodeSet) {
                            attrListToRender.Add(attr, null);
                        }
                    } 
                }
            } 
 
            if (!Utils.IsCommittedNamespace(this, this.Prefix, this.NamespaceURI)) {
                string name = ((this.Prefix.Length > 0) ? "xmlns" + ":" + this.Prefix : "xmlns"); 
                XmlAttribute nsattrib = (XmlAttribute) this.OwnerDocument.CreateAttribute(name);
                nsattrib.Value = this.NamespaceURI;
                anc.TrackNamespaceNode(nsattrib, nsListToRender, nsLocallyDeclared);
            } 

            if (IsInNodeSet) { 
                anc.GetNamespacesToRender(this, attrListToRender, nsListToRender, nsLocallyDeclared); 

                strBuilder.Append("<" + this.Name); 
                foreach (object attr in nsListToRender.GetKeyList()) {
                    (attr as CanonicalXmlAttribute).Write(strBuilder, docPos, anc);
                }
                foreach (object attr in attrListToRender.GetKeyList()) { 
                    (attr as CanonicalXmlAttribute).Write(strBuilder, docPos, anc);
                } 
                strBuilder.Append(">"); 
            }
 
            anc.EnterElementContext();
            anc.LoadUnrenderedNamespaces(nsLocallyDeclared);
            anc.LoadRenderedNamespaces(nsListToRender);
 
            XmlNodeList childNodes = this.ChildNodes;
            foreach (XmlNode childNode in childNodes) { 
                CanonicalizationDispatcher.Write(childNode, strBuilder, docPos, anc); 
            }
 
            anc.ExitElementContext();

            if (IsInNodeSet) {
                strBuilder.Append(""); 
            }
        } 
 
        public void WriteHash(HashAlgorithm hash, DocPosition docPos, AncestralNamespaceContextManager anc) {
            Hashtable nsLocallyDeclared = new Hashtable(); 
            SortedList nsListToRender = new SortedList(new NamespaceSortOrder());
            SortedList attrListToRender = new SortedList(new AttributeSortOrder());
            UTF8Encoding utf8 = new UTF8Encoding(false);
            byte[] rgbData; 

            XmlAttributeCollection attrList = this.Attributes; 
            if (attrList != null) { 
                foreach (XmlAttribute attr in attrList) {
                    if (((CanonicalXmlAttribute) attr).IsInNodeSet || Utils.IsNamespaceNode(attr) || Utils.IsXmlNamespaceNode(attr)) { 
                        if (Utils.IsNamespaceNode(attr)) {
                            anc.TrackNamespaceNode(attr, nsListToRender, nsLocallyDeclared);
                        }
                        else if (Utils.IsXmlNamespaceNode(attr)) { 
                            anc.TrackXmlNamespaceNode(attr, nsListToRender, attrListToRender, nsLocallyDeclared);
                        } 
                        else if(IsInNodeSet) { 
                            attrListToRender.Add(attr, null);
                        } 
                    }
                }
            }
 
            if (!Utils.IsCommittedNamespace(this, this.Prefix, this.NamespaceURI)) {
                string name = ((this.Prefix.Length > 0) ? "xmlns" + ":" + this.Prefix : "xmlns"); 
                XmlAttribute nsattrib = (XmlAttribute) this.OwnerDocument.CreateAttribute(name); 
                nsattrib.Value = this.NamespaceURI;
                anc.TrackNamespaceNode(nsattrib, nsListToRender, nsLocallyDeclared); 
            }

            if (IsInNodeSet) {
                anc.GetNamespacesToRender(this, attrListToRender, nsListToRender, nsLocallyDeclared); 
                rgbData = utf8.GetBytes("<" + this.Name);
                hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0); 
                foreach (object attr in nsListToRender.GetKeyList()) { 
                    (attr as CanonicalXmlAttribute).WriteHash(hash, docPos, anc);
                } 
                foreach (object attr in attrListToRender.GetKeyList()) {
                    (attr as CanonicalXmlAttribute).WriteHash(hash, docPos, anc);
                }
                rgbData = utf8.GetBytes(">"); 
                hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0);
            } 
 
            anc.EnterElementContext();
            anc.LoadUnrenderedNamespaces(nsLocallyDeclared); 
            anc.LoadRenderedNamespaces(nsListToRender);

            XmlNodeList childNodes = this.ChildNodes;
            foreach (XmlNode childNode in childNodes) { 
                CanonicalizationDispatcher.WriteHash(childNode, hash, docPos, anc);
            } 
 
            anc.ExitElementContext();
 
            if (IsInNodeSet) {
                rgbData = utf8.GetBytes("");
                hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0);
            } 
        }
    } 
 
    // the class that provides node subset state and canonicalization function to XmlAttribute
    internal class CanonicalXmlAttribute : XmlAttribute, ICanonicalizableNode { 
        private bool m_isInNodeSet;

        public CanonicalXmlAttribute(string prefix, string localName, string namespaceURI, XmlDocument doc, bool defaultNodeSetInclusionState)
            : base(prefix, localName, namespaceURI, doc) { 
            IsInNodeSet = defaultNodeSetInclusionState;
        } 
 
        public bool IsInNodeSet {
            get { return m_isInNodeSet; } 
            set { m_isInNodeSet = value; }
        }

        public void Write(StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc) { 
            strBuilder.Append(" " + this.Name + "=\"");
            strBuilder.Append(Utils.EscapeAttributeValue(this.Value)); 
            strBuilder.Append("\""); 
        }
 
        public void WriteHash(HashAlgorithm hash, DocPosition docPos, AncestralNamespaceContextManager anc) {
            UTF8Encoding utf8 = new UTF8Encoding(false);
            byte[] rgbData = utf8.GetBytes(" " + this.Name + "=\"");
            hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0); 
            rgbData = utf8.GetBytes(Utils.EscapeAttributeValue(this.Value));
            hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0); 
            rgbData = utf8.GetBytes("\""); 
            hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0);
        } 
    }

    // the class that provides node subset state and canonicalization function to XmlText
    internal class CanonicalXmlText : XmlText, ICanonicalizableNode { 
        private bool m_isInNodeSet;
 
        public CanonicalXmlText(string strData, XmlDocument doc, bool defaultNodeSetInclusionState) 
            : base(strData, doc) {
            m_isInNodeSet = defaultNodeSetInclusionState; 
        }

        public bool IsInNodeSet {
            get { return m_isInNodeSet; } 
            set { m_isInNodeSet = value; }
        } 
 
        public void Write(StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc) {
            if (IsInNodeSet) 
                strBuilder.Append(Utils.EscapeTextData(this.Value));
        }

        public void WriteHash(HashAlgorithm hash, DocPosition docPos, AncestralNamespaceContextManager anc) { 
            if (IsInNodeSet) {
                UTF8Encoding utf8 = new UTF8Encoding(false); 
                byte[] rgbData = utf8.GetBytes(Utils.EscapeTextData(this.Value)); 
                hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0);
            } 
        }
    }

    // the class that provides node subset state and canonicalization function to XmlWhitespace 
    internal class CanonicalXmlWhitespace : XmlWhitespace, ICanonicalizableNode {
        private bool m_isInNodeSet; 
 
        public CanonicalXmlWhitespace(string strData, XmlDocument doc, bool defaultNodeSetInclusionState)
            : base(strData, doc) { 
            m_isInNodeSet = defaultNodeSetInclusionState;
        }

        public bool IsInNodeSet { 
            get { return m_isInNodeSet; }
            set { m_isInNodeSet = value; } 
        } 

        public void Write(StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc) { 
            if (IsInNodeSet && docPos == DocPosition.InRootElement)
                strBuilder.Append(Utils.EscapeWhitespaceData(this.Value));
        }
 
        public void WriteHash(HashAlgorithm hash, DocPosition docPos, AncestralNamespaceContextManager anc) {
            if (IsInNodeSet && docPos == DocPosition.InRootElement) { 
                UTF8Encoding utf8 = new UTF8Encoding(false); 
                byte[] rgbData = utf8.GetBytes(Utils.EscapeWhitespaceData(this.Value));
                hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0); 
            }
        }
    }
 
    // the class that provides node subset state and canonicalization function to XmlSignificantWhitespace
    internal class CanonicalXmlSignificantWhitespace : XmlSignificantWhitespace, ICanonicalizableNode { 
        private bool m_isInNodeSet; 

        public CanonicalXmlSignificantWhitespace(string strData, XmlDocument doc, bool defaultNodeSetInclusionState) 
            : base(strData, doc) {
            m_isInNodeSet = defaultNodeSetInclusionState;
        }
 
        public bool IsInNodeSet {
            get { return m_isInNodeSet; } 
            set { m_isInNodeSet = value; } 
        }
 
        public void Write(StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc) {
            if (IsInNodeSet && docPos == DocPosition.InRootElement)
                strBuilder.Append(Utils.EscapeWhitespaceData(this.Value));
        } 

        public void WriteHash(HashAlgorithm hash, DocPosition docPos, AncestralNamespaceContextManager anc) { 
            if (IsInNodeSet && docPos == DocPosition.InRootElement) { 
                UTF8Encoding utf8 = new UTF8Encoding(false);
                byte[] rgbData = utf8.GetBytes(Utils.EscapeWhitespaceData(this.Value)); 
                hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0);
            }
        }
    } 

    // the class that provides node subset state and canonicalization function to XmlComment 
    internal class CanonicalXmlComment : XmlComment, ICanonicalizableNode { 
        private bool m_isInNodeSet;
        private bool m_includeComments; 

        public CanonicalXmlComment(string comment, XmlDocument doc, bool defaultNodeSetInclusionState, bool includeComments)
            : base(comment, doc) {
            m_isInNodeSet = defaultNodeSetInclusionState; 
            m_includeComments = includeComments;
        } 
 
        public bool IsInNodeSet {
            get { return m_isInNodeSet; } 
            set { m_isInNodeSet = value; }
        }

        public bool IncludeComments { 
            get { return m_includeComments; }
        } 
 
        public void Write(StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc) {
            if (!IsInNodeSet || !IncludeComments) 
                return;

            if (docPos == DocPosition.AfterRootElement)
                strBuilder.Append((char) 10); 
            strBuilder.Append(""); 
            if (docPos == DocPosition.BeforeRootElement)
                strBuilder.Append((char) 10); 
        }

        public void WriteHash(HashAlgorithm hash, DocPosition docPos, AncestralNamespaceContextManager anc) {
            if (!IsInNodeSet || !IncludeComments) 
                return;
 
            UTF8Encoding utf8 = new UTF8Encoding(false); 
            byte[] rgbData = utf8.GetBytes("(char) 10");
            if (docPos == DocPosition.AfterRootElement) 
                hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0);
            rgbData = utf8.GetBytes(""); 
            hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0); 
            if (docPos == DocPosition.BeforeRootElement) {
                rgbData = utf8.GetBytes("(char) 10"); 
                hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0);
            }
        }
    } 

 
 
    // the class that provides node subset state and canonicalization function to XmlProcessingInstruction
    internal class CanonicalXmlProcessingInstruction : XmlProcessingInstruction, ICanonicalizableNode { 
        private bool m_isInNodeSet;

        public CanonicalXmlProcessingInstruction(string target, string data, XmlDocument doc, bool defaultNodeSetInclusionState)
            : base(target, data, doc) { 
            m_isInNodeSet = defaultNodeSetInclusionState;
        } 
 
        public bool IsInNodeSet {
            get { return m_isInNodeSet; } 
            set { m_isInNodeSet = value; }
        }

        public void Write(StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc) { 
            if (!IsInNodeSet)
                return; 
 
            if (docPos == DocPosition.AfterRootElement)
                strBuilder.Append((char) 10); 
            strBuilder.Append(" 0))
                strBuilder.Append(" " + this.Value); 
            strBuilder.Append("?>");
            if (docPos == DocPosition.BeforeRootElement) 
                strBuilder.Append((char) 10); 
        }
 
        public void WriteHash(HashAlgorithm hash, DocPosition docPos, AncestralNamespaceContextManager anc) {
            if (!IsInNodeSet)
                return;
 
            UTF8Encoding utf8 = new UTF8Encoding(false);
            byte[] rgbData; 
            if (docPos == DocPosition.AfterRootElement) { 
                rgbData = utf8.GetBytes("(char) 10");
                hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0); 
            }
            rgbData = utf8.GetBytes(" 0)) { 
                rgbData = utf8.GetBytes(" " + this.Value); 
                hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0);
            } 
            rgbData = utf8.GetBytes("?>");
            hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0);
            if (docPos == DocPosition.BeforeRootElement) {
                rgbData = utf8.GetBytes("(char) 10"); 
                hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0);
            } 
        } 
    }
 


    // the class that provides node subset state and canonicalization function to XmlEntityReference
    internal class CanonicalXmlEntityReference : XmlEntityReference, ICanonicalizableNode { 
        private bool m_isInNodeSet;
 
        public CanonicalXmlEntityReference(string name, XmlDocument doc, bool defaultNodeSetInclusionState) 
            : base(name, doc) {
            m_isInNodeSet = defaultNodeSetInclusionState; 
        }

        public bool IsInNodeSet {
            get { return m_isInNodeSet; } 
            set { m_isInNodeSet = value; }
        } 
 
        public void Write(StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc) {
            if (IsInNodeSet) 
                CanonicalizationDispatcher.WriteGenericNode(this, strBuilder, docPos, anc);
        }

        public void WriteHash(HashAlgorithm hash, DocPosition docPos, AncestralNamespaceContextManager anc) { 
            if (IsInNodeSet)
                CanonicalizationDispatcher.WriteHashGenericNode(this, hash, docPos, anc); 
        } 
    }
 
    // the class that provides node subset state and canonicalization function to XmlCDataSection
    internal class CanonicalXmlCDataSection: XmlCDataSection, ICanonicalizableNode {
        private bool m_isInNodeSet;
        public CanonicalXmlCDataSection(string data, XmlDocument doc, bool defaultNodeSetInclusionState) : base(data, doc) { 
            m_isInNodeSet = defaultNodeSetInclusionState;
        } 
 
        public bool IsInNodeSet {
            get { return m_isInNodeSet; } 
            set { m_isInNodeSet = value; }
        }

        public void Write(StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc) { 
            if (IsInNodeSet)
                strBuilder.Append(Utils.EscapeCData(this.Data)); 
        } 

        public void WriteHash(HashAlgorithm hash, DocPosition docPos, AncestralNamespaceContextManager anc) { 
            if (IsInNodeSet) {
                UTF8Encoding utf8 = new UTF8Encoding(false);
                byte[] rgbData = utf8.GetBytes(Utils.EscapeCData(this.Data));
                hash.TransformBlock(rgbData, 0, rgbData.Length, rgbData, 0); 
            }
        } 
    } 

    internal class CanonicalXmlNodeList : XmlNodeList, IList { 
        private ArrayList m_nodeArray;

        internal CanonicalXmlNodeList() {
            m_nodeArray = new ArrayList(); 
        }
 
        public override XmlNode Item(int index) { 
            return (XmlNode) m_nodeArray[index];
        } 

        public override IEnumerator GetEnumerator() {
            return m_nodeArray.GetEnumerator();
        } 

        public override int Count { 
            get { return m_nodeArray.Count; } 
        }
 
        // IList methods
        public int Add(Object value) {
            if (!(value is XmlNode))
                throw new ArgumentException(SecurityResources.GetResourceString("Cryptography_Xml_IncorrectObjectType"), "node"); 
            return m_nodeArray.Add(value);
        } 
 
        public void Clear() {
            m_nodeArray.Clear(); 
        }

        public bool Contains(Object value) {
            return m_nodeArray.Contains(value); 
        }
 
        public int IndexOf(Object value) { 
            return m_nodeArray.IndexOf(value);
        } 

        public void Insert(int index, Object value) {
            if (!(value is XmlNode))
                throw new ArgumentException(SecurityResources.GetResourceString("Cryptography_Xml_IncorrectObjectType"), "value"); 
            m_nodeArray.Insert(index,value);
        } 
 
        public void Remove(Object value) {
            m_nodeArray.Remove(value); 
        }

        public void RemoveAt(int index) {
            m_nodeArray.RemoveAt(index); 
        }
 
        public Boolean IsFixedSize { 
            get { return m_nodeArray.IsFixedSize; }
        } 

        public Boolean IsReadOnly {
            get { return m_nodeArray.IsReadOnly; }
        } 

        Object IList.this[int index] { 
            get { return m_nodeArray[index]; } 
            set {
                if (!(value is XmlNode)) 
                    throw new ArgumentException(SecurityResources.GetResourceString("Cryptography_Xml_IncorrectObjectType"), "value");
                m_nodeArray[index] = value;
            }
        } 

        public void CopyTo(Array array, int index) { 
            m_nodeArray.CopyTo(array, index); 
        }
 
        public Object SyncRoot {
            get { return m_nodeArray.SyncRoot; }
        }
 
        public bool IsSynchronized {
            get { return m_nodeArray.IsSynchronized; } 
        } 
    }
 
    // This class does lexicographic sorting by NamespaceURI first and then by LocalName.
    internal class AttributeSortOrder : IComparer {
        internal AttributeSortOrder() {}
 
        public int Compare(Object a, Object b) {
            XmlNode nodeA = a as XmlNode; 
            XmlNode nodeB = b as XmlNode; 
            if ((a == null) || (b == null))
                throw new ArgumentException(); 
            int namespaceCompare = String.CompareOrdinal(nodeA.NamespaceURI, nodeB.NamespaceURI);
            if (namespaceCompare != 0) return namespaceCompare;
            return String.CompareOrdinal(nodeA.LocalName, nodeB.LocalName);
        } 
    }
 
    internal class NamespaceSortOrder : IComparer { 
        internal NamespaceSortOrder() {}
 
        public int Compare(Object a, Object b) {
            XmlNode nodeA = a as XmlNode;
            XmlNode nodeB = b as XmlNode;
            if ((a == null) || (b == null)) 
                throw new ArgumentException();
            bool nodeAdefault = Utils.IsDefaultNamespaceNode(nodeA); 
            bool nodeBdefault = Utils.IsDefaultNamespaceNode(nodeB); 
            if (nodeAdefault && nodeBdefault) return 0;
            if (nodeAdefault) return -1; 
            if (nodeBdefault) return 1;
            return String.CompareOrdinal(nodeA.LocalName, nodeB.LocalName);
        }
    } 

    // the namespaces context corresponding to one XmlElement. the rendered list contains the namespace nodes that are actually 
    // rendered to the canonicalized output. the unrendered list contains the namespace nodes that are in the node set and have 
    // the XmlElement as the owner, but are not rendered.
    internal class NamespaceFrame { 
        private Hashtable m_rendered = new Hashtable();
        private Hashtable m_unrendered = new Hashtable();

        internal NamespaceFrame() {} 

        internal void AddRendered(XmlAttribute attr) { 
            m_rendered.Add(Utils.GetNamespacePrefix(attr), attr); 
        }
 
        internal XmlAttribute GetRendered(string nsPrefix) {
            return (XmlAttribute) m_rendered[nsPrefix];
        }
 
        internal void AddUnrendered(XmlAttribute attr) {
            m_unrendered.Add(Utils.GetNamespacePrefix(attr), attr); 
        } 

        internal XmlAttribute GetUnrendered(string nsPrefix) { 
            return (XmlAttribute) m_unrendered[nsPrefix];
        }

        internal Hashtable GetUnrendered() { 
            return m_unrendered;
        } 
    } 

    abstract internal class AncestralNamespaceContextManager { 
        internal ArrayList m_ancestorStack = new ArrayList();

        internal NamespaceFrame GetScopeAt(int i) {
            return (NamespaceFrame) m_ancestorStack[i]; 
        }
 
        internal NamespaceFrame GetCurrentScope() { 
            return GetScopeAt(m_ancestorStack.Count - 1);
        } 

        protected XmlAttribute GetNearestRenderedNamespaceWithMatchingPrefix(string nsPrefix, out int depth) {
            XmlAttribute attr = null;
            depth = -1; 
            for (int i = m_ancestorStack.Count - 1; i >= 0; i--) {
                if ((attr = GetScopeAt(i).GetRendered(nsPrefix)) != null) { 
                    depth = i; 
                    return attr;
                } 
            }
            return null;
        }
 
        protected XmlAttribute GetNearestUnrenderedNamespaceWithMatchingPrefix(string nsPrefix, out int depth) {
            XmlAttribute attr = null; 
            depth = -1; 
            for (int i = m_ancestorStack.Count - 1; i >= 0; i--) {
                if ((attr = GetScopeAt(i).GetUnrendered(nsPrefix)) != null) { 
                    depth = i;
                    return attr;
                }
            } 
            return null;
        } 
 
        internal void EnterElementContext() {
            m_ancestorStack.Add(new NamespaceFrame()); 
        }

        internal void ExitElementContext() {
            m_ancestorStack.RemoveAt(m_ancestorStack.Count - 1); 
        }
 
        internal abstract void TrackNamespaceNode(XmlAttribute attr, SortedList nsListToRender, Hashtable nsLocallyDeclared); 
        internal abstract void TrackXmlNamespaceNode(XmlAttribute attr, SortedList nsListToRender, SortedList attrListToRender, Hashtable nsLocallyDeclared);
        internal abstract void GetNamespacesToRender (XmlElement element, SortedList attrListToRender, SortedList nsListToRender, Hashtable nsLocallyDeclared); 

        internal void LoadUnrenderedNamespaces(Hashtable nsLocallyDeclared) {
            object[] attrs = new object[nsLocallyDeclared.Count];
            nsLocallyDeclared.Values.CopyTo(attrs, 0); 
            foreach (object attr in attrs) {
                AddUnrendered((XmlAttribute) attr); 
            } 
        }
 
        internal void LoadRenderedNamespaces(SortedList nsRenderedList) {
            foreach (object attr in nsRenderedList.GetKeyList()) {
                AddRendered((XmlAttribute) attr);
            } 
        }
 
        internal void AddRendered(XmlAttribute attr) { 
            GetCurrentScope().AddRendered(attr);
        } 

        internal void AddUnrendered(XmlAttribute attr) {
            GetCurrentScope().AddUnrendered(attr);
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK