XmlBaseReader.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WCF / Serialization / System / Xml / XmlBaseReader.cs / 1305376 / XmlBaseReader.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------
// PERF, [....], [....]: Make LookupNamespace do something smarter when lots of names
// PERF, [....], [....]: Make Attribute lookup smarter when lots of attributes 
namespace System.Xml
{ 
    using System; 
    using System.Collections;
    using System.Globalization; 
    using System.IO;
    using System.Runtime;
    using System.Runtime.Serialization;
    using System.Text; 

    // Large numbers of attributes 
    // Use delimiter on node for figuring out Element/EndElement? 
    // Optimize StringHandle.CompareTo
    // Fix FixXmlAttribute - Temporary until we actually write an XmlAttribute node 

    abstract class XmlBaseReader : XmlDictionaryReader
    {
        XmlBufferReader bufferReader; 
        XmlNode node;
        NamespaceManager nsMgr; 
        XmlElementNode[] elementNodes; 
        XmlAttributeNode[] attributeNodes;
        XmlAtomicTextNode atomicTextNode; 
        int depth;
        int attributeCount;
        int attributeStart;    // Starting index for searching
        XmlDictionaryReaderQuotas quotas; 

        XmlNameTable nameTable; 
        XmlDeclarationNode declarationNode; 
        XmlComplexTextNode complexTextNode;
        XmlWhitespaceTextNode whitespaceTextNode; 
        XmlCDataNode cdataNode;
        XmlCommentNode commentNode;
        XmlElementNode rootElementNode;
        int attributeIndex;    // Index for iteration 
        char[] chars;
        string prefix; 
        string localName; 
        string ns;
        string value; 
        int trailCharCount;
        int trailByteCount;
        char[] trailChars;
        byte[] trailBytes; 
        bool rootElement;
        bool readingElement; 
        XmlSigningNodeWriter signingWriter; 
        bool signing;
        AttributeSorter attributeSorter; 

        static XmlInitialNode initialNode = new XmlInitialNode(XmlBufferReader.Empty);
        static XmlEndOfFileNode endOfFileNode = new XmlEndOfFileNode(XmlBufferReader.Empty);
        static XmlClosedNode closedNode = new XmlClosedNode(XmlBufferReader.Empty); 
        static BinHexEncoding binhexEncoding;
        static Base64Encoding base64Encoding; 
 
        const string xmlns = "xmlns";
        const string xml = "xml"; 
        const string xmlnsNamespace = "http://www.w3.org/2000/xmlns/";
        const string xmlNamespace = "http://www.w3.org/XML/1998/namespace";

        protected XmlBaseReader() 
        {
            this.bufferReader = new XmlBufferReader(this); 
            this.nsMgr = new NamespaceManager(bufferReader); 
            this.quotas = new XmlDictionaryReaderQuotas();
            this.rootElementNode = new XmlElementNode(bufferReader); 
            this.atomicTextNode = new XmlAtomicTextNode(bufferReader);
            this.node = closedNode;
        }
 
        static BinHexEncoding BinHexEncoding
        { 
            get 
            {
                if (binhexEncoding == null) 
                    binhexEncoding = new BinHexEncoding();
                return binhexEncoding;
            }
        } 

        static Base64Encoding Base64Encoding 
        { 
            get
            { 
                if (base64Encoding == null)
                    base64Encoding = new Base64Encoding();
                return base64Encoding;
            } 
        }
 
        protected XmlBufferReader BufferReader 
        {
            get 
            {
                return bufferReader;
            }
        } 

        public override XmlDictionaryReaderQuotas Quotas 
        { 
            get
            { 
                return quotas;
            }
        }
 
        protected XmlNode Node
        { 
            get 
            {
                return node; 
            }
        }

        protected void MoveToNode(XmlNode node) 
        {
            this.node = node; 
            this.ns = null; 
            this.localName = null;
            this.prefix = null; 
            this.value = null;
        }

        protected void MoveToInitial(XmlDictionaryReaderQuotas quotas) 
        {
            if (quotas == null) 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("quotas"); 

            quotas.InternalCopyTo(this.quotas); 
            this.quotas.MakeReadOnly();
            this.nsMgr.Clear();
            this.depth = 0;
            this.attributeCount = 0; 
            this.attributeStart = -1;
            this.attributeIndex = -1; 
            this.rootElement = false; 
            this.readingElement = false;
            this.signing = false; 
            MoveToNode(initialNode);
        }

        protected XmlDeclarationNode MoveToDeclaration() 
        {
            if (attributeCount < 1) 
                XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.XmlDeclMissingVersion))); 

            if (attributeCount > 3) 
                XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.XmlMalformedDecl)));

            // version
            if (!CheckDeclAttribute(0, "version", "1.0", false, SR.XmlInvalidVersion)) 
                XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.XmlDeclMissingVersion)));
 
            // encoding/standalone 
            // We only validate that they are the only attributes that exist.  Encoding can have any value.
            if (attributeCount > 1) 
            {
                if (CheckDeclAttribute(1, "encoding", null, true, SR.XmlInvalidEncoding))
                {
                    if (attributeCount == 3 && !CheckStandalone(2)) 
                        XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.XmlMalformedDecl)));
                } 
                else if (!CheckStandalone(1) || attributeCount > 2) 
                {
                    XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.XmlMalformedDecl))); 
                }
            }

            if (declarationNode == null) 
            {
                declarationNode = new XmlDeclarationNode(bufferReader); 
            } 
            MoveToNode(declarationNode);
            return declarationNode; 
        }

        bool CheckStandalone(int attr)
        { 
            XmlAttributeNode node = attributeNodes[attr];
            if (!node.Prefix.IsEmpty) 
                XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.XmlMalformedDecl))); 

            if (node.LocalName != "standalone") 
                return false;

            if (!node.Value.Equals2("yes", false) && !node.Value.Equals2("no", false))
                XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.XmlInvalidStandalone))); 

            return true; 
        } 

        bool CheckDeclAttribute(int index, string localName, string value, bool checkLower, string valueSR) 
        {
            XmlAttributeNode node = attributeNodes[index];
            if (!node.Prefix.IsEmpty)
                XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.XmlMalformedDecl))); 

            if (node.LocalName != localName) 
                return false; 

            if (value != null && !node.Value.Equals2(value, checkLower)) 
                XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(valueSR)));

            return true;
        } 

        protected XmlCommentNode MoveToComment() 
        { 
            if (commentNode == null)
            { 
                commentNode = new XmlCommentNode(bufferReader);
            }
            MoveToNode(commentNode);
            return commentNode; 
        }
 
        protected XmlCDataNode MoveToCData() 
        {
            if (cdataNode == null) 
            {
                this.cdataNode = new XmlCDataNode(bufferReader);
            }
            MoveToNode(cdataNode); 
            return cdataNode;
        } 
 
        protected XmlAtomicTextNode MoveToAtomicText()
        { 
            XmlAtomicTextNode textNode = this.atomicTextNode;
            MoveToNode(textNode);
            return textNode;
        } 

        protected XmlComplexTextNode MoveToComplexText() 
        { 
            if (complexTextNode == null)
            { 
                complexTextNode = new XmlComplexTextNode(bufferReader);
            }
            MoveToNode(complexTextNode);
            return complexTextNode; 
        }
 
        protected XmlTextNode MoveToWhitespaceText() 
        {
            if (whitespaceTextNode == null) 
            {
                whitespaceTextNode = new XmlWhitespaceTextNode(bufferReader);
            }
            if (nsMgr.XmlSpace == XmlSpace.Preserve) 
                whitespaceTextNode.NodeType = XmlNodeType.SignificantWhitespace;
            else 
                whitespaceTextNode.NodeType = XmlNodeType.Whitespace; 
            MoveToNode(whitespaceTextNode);
            return whitespaceTextNode; 
        }

        protected XmlElementNode ElementNode
        { 
            get
            { 
                if (depth == 0) 
                    return rootElementNode;
                else 
                    return elementNodes[depth];
            }
        }
 
        protected void MoveToEndElement()
        { 
            if (depth == 0) 
                XmlExceptionHelper.ThrowInvalidBinaryFormat(this);
            XmlElementNode elementNode = elementNodes[depth]; 
            XmlEndElementNode endElementNode = elementNode.EndElement;
            endElementNode.Namespace = elementNode.Namespace;
            MoveToNode(endElementNode);
        } 

        protected void MoveToEndOfFile() 
        { 
            if (depth != 0)
                XmlExceptionHelper.ThrowUnexpectedEndOfFile(this); 
            MoveToNode(endOfFileNode);
        }

        protected XmlElementNode EnterScope() 
        {
            if (depth == 0) 
            { 
                if (rootElement)
                    XmlExceptionHelper.ThrowMultipleRootElements(this); 
                rootElement = true;
            }
            nsMgr.EnterScope();
            depth++; 
            if (depth > quotas.MaxDepth)
                XmlExceptionHelper.ThrowMaxDepthExceeded(this, quotas.MaxDepth); 
            if (elementNodes == null) 
            {
                elementNodes = new XmlElementNode[4]; 
            }
            else if (elementNodes.Length == depth)
            {
                XmlElementNode[] newElementNodes = new XmlElementNode[depth * 2]; 
                Array.Copy(elementNodes, newElementNodes, depth);
                elementNodes = newElementNodes; 
            } 
            XmlElementNode elementNode = elementNodes[depth];
            if (elementNode == null) 
            {
                elementNode = new XmlElementNode(bufferReader);
                elementNodes[depth] = elementNode;
            } 
            this.attributeCount = 0;
            this.attributeStart = -1; 
            this.attributeIndex = -1; 
            MoveToNode(elementNode);
            return elementNode; 
        }

        protected void ExitScope()
        { 
            if (depth == 0)
                XmlExceptionHelper.ThrowUnexpectedEndElement(this); 
            depth--; 
            nsMgr.ExitScope();
        } 

        XmlAttributeNode AddAttribute(QNameType qnameType, bool isAtomicValue)
        {
            int attributeIndex = this.attributeCount; 
            if (attributeNodes == null)
            { 
                attributeNodes = new XmlAttributeNode[4]; 
            }
            else if (attributeNodes.Length == attributeIndex) 
            {
                XmlAttributeNode[] newAttributeNodes = new XmlAttributeNode[attributeIndex * 2];
                Array.Copy(attributeNodes, newAttributeNodes, attributeIndex);
                attributeNodes = newAttributeNodes; 
            }
            XmlAttributeNode attributeNode = attributeNodes[attributeIndex]; 
            if (attributeNode == null) 
            {
                attributeNode = new XmlAttributeNode(bufferReader); 
                attributeNodes[attributeIndex] = attributeNode;
            }
            attributeNode.QNameType = qnameType;
            attributeNode.IsAtomicValue = isAtomicValue; 
            attributeNode.AttributeText.QNameType = qnameType;
            attributeNode.AttributeText.IsAtomicValue = isAtomicValue; 
            this.attributeCount++; 
            return attributeNode;
        } 

        protected Namespace AddNamespace()
        {
            return nsMgr.AddNamespace(); 
        }
 
        protected XmlAttributeNode AddAttribute() 
        {
            return AddAttribute(QNameType.Normal, true); 
        }

        protected XmlAttributeNode AddXmlAttribute()
        { 
            return AddAttribute(QNameType.Normal, true);
        } 
 
        protected XmlAttributeNode AddXmlnsAttribute(Namespace ns)
        { 
            if (!ns.Prefix.IsEmpty && ns.Uri.IsEmpty)
                XmlExceptionHelper.ThrowEmptyNamespace(this);

            // Some prefixes can only be bound to a particular namespace 
            if (ns.Prefix.IsXml && ns.Uri != xmlNamespace)
            { 
                XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.XmlSpecificBindingPrefix, "xml", xmlNamespace))); 
            }
            else if (ns.Prefix.IsXmlns && ns.Uri != xmlnsNamespace) 
            {
                XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.XmlSpecificBindingPrefix, "xmlns", xmlnsNamespace)));
            }
 
            nsMgr.Register(ns);
            XmlAttributeNode attributeNode = AddAttribute(QNameType.Xmlns, false); 
            attributeNode.Namespace = ns; 
            attributeNode.AttributeText.Namespace = ns;
            return attributeNode; 
        }

        protected void FixXmlAttribute(XmlAttributeNode attributeNode)
        { 
            if (attributeNode.Prefix == xml)
            { 
                if (attributeNode.LocalName == "lang") 
                {
                    nsMgr.AddLangAttribute(attributeNode.Value.GetString()); 
                }
                else if (attributeNode.LocalName == "space")
                {
                    string value = attributeNode.Value.GetString(); 
                    if (value == "preserve")
                    { 
                        nsMgr.AddSpaceAttribute(XmlSpace.Preserve); 
                    }
                    else if (value == "default") 
                    {
                        nsMgr.AddSpaceAttribute(XmlSpace.Default);
                    }
                } 
            }
        } 
 
        protected bool OutsideRootElement
        { 
            get
            {
                return depth == 0;
            } 
        }
 
        public override bool CanReadBinaryContent 
        {
            get { return true; } 
        }

        public override bool CanReadValueChunk
        { 
            get { return true; }
        } 
 
        public override string BaseURI
        { 
            get
            {
                return string.Empty;
            } 
        }
 
        public override bool HasValue 
        {
            get 
            {
                return node.HasValue;
            }
        } 

        public override bool IsDefault 
        { 
            get
            { 
                return false;
            }
        }
 
        public override string this[int index]
        { 
            get 
            {
                return GetAttribute(index); 
            }
        }

        public override string this[string name] 
        {
            get 
            { 
                return GetAttribute(name);
            } 
        }

        public override string this[string localName, string namespaceUri]
        { 
            get
            { 
                return GetAttribute(localName, namespaceUri); 
            }
        } 

        public override int AttributeCount
        {
            get 
            {
                if (node.CanGetAttribute) 
                    return attributeCount; 
                return 0;
            } 
        }

        public override void Close()
        { 
            MoveToNode(closedNode);
            nameTable = null; 
            if (attributeNodes != null && attributeNodes.Length > 16) 
                attributeNodes = null;
            if (elementNodes != null && elementNodes.Length > 16) 
                elementNodes = null;
            nsMgr.Close();
            bufferReader.Close();
            if (signingWriter != null) 
                signingWriter.Close();
            if (attributeSorter != null) 
                attributeSorter.Close(); 
        }
 
        public sealed override int Depth
        {
            get
            { 
                // Internally, depth is simply measured by Element/EndElement.  What XmlReader exposes is a little different
                // so we need to account for this with some minor adjustments. 
 
                // We increment depth immediately when we see an element, but XmlTextReader waits until its consumed
                // We decrement depth when its consumed, but XmlTextReader decrements depth immediately 

                // If we're on Attribute Text (i.e. ReadAttributeValue), then its considered a level deeper
                return this.depth + node.DepthDelta;
            } 
        }
 
        public override bool EOF 
        {
            get 
            {
                return node.ReadState == ReadState.EndOfFile;
            }
        } 

        XmlAttributeNode GetAttributeNode(int index) 
        { 
            if (!node.CanGetAttribute)
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("index", SR.GetString(SR.XmlElementAttributes))); 
            if (index < 0)
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("index", SR.GetString(SR.ValueMustBeNonNegative)));
            if (index >= attributeCount)
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("index", SR.GetString(SR.OffsetExceedsBufferSize, attributeCount))); 
            return attributeNodes[index];
        } 
 
        XmlAttributeNode GetAttributeNode(string name)
        { 
            if (name == null)
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("name"));
            if (!node.CanGetAttribute)
                return null; 
            int index = name.IndexOf(':');
            string prefix; 
            string localName; 
            if (index == -1)
            { 
                if (name == xmlns)
                {
                    prefix = xmlns;
                    localName = string.Empty; 
                }
                else 
                { 
                    prefix = string.Empty;
                    localName = name; 
                }
            }
            else
            { 
                // If this function becomes a performance issue because of the allocated strings then we can
                // make a version of Equals that takes an offset and count into the string. 
                prefix = name.Substring(0, index); 
                localName = name.Substring(index + 1);
            } 
            XmlAttributeNode[] attributeNodes = this.attributeNodes;
            int attributeCount = this.attributeCount;
            int attributeIndex = this.attributeStart;
            for (int i = 0; i < attributeCount; i++) 
            {
                if (++attributeIndex >= attributeCount) 
                { 
                    attributeIndex = 0;
                } 
                XmlAttributeNode attributeNode = attributeNodes[attributeIndex];
                if (attributeNode.IsPrefixAndLocalName(prefix, localName))
                {
                    this.attributeStart = attributeIndex; 
                    return attributeNode;
                } 
            } 
            return null;
        } 

        XmlAttributeNode GetAttributeNode(string localName, string namespaceUri)
        {
            if (localName == null) 
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("localName"));
            if (namespaceUri == null) 
                namespaceUri = string.Empty; 
            if (!node.CanGetAttribute)
                return null; 
            XmlAttributeNode[] attributeNodes = this.attributeNodes;
            int attributeCount = this.attributeCount;
            int attributeIndex = this.attributeStart;
            for (int i = 0; i < attributeCount; i++) 
            {
                if (++attributeIndex >= attributeCount) 
                { 
                    attributeIndex = 0;
                } 
                XmlAttributeNode attributeNode = attributeNodes[attributeIndex];
                if (attributeNode.IsLocalNameAndNamespaceUri(localName, namespaceUri))
                {
                    this.attributeStart = attributeIndex; 
                    return attributeNode;
                } 
            } 
            return null;
        } 

        XmlAttributeNode GetAttributeNode(XmlDictionaryString localName, XmlDictionaryString namespaceUri)
        {
            if (localName == null) 
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("localName"));
            if (namespaceUri == null) 
                namespaceUri = XmlDictionaryString.Empty; 
            if (!node.CanGetAttribute)
                return null; 
            XmlAttributeNode[] attributeNodes = this.attributeNodes;
            int attributeCount = this.attributeCount;
            int attributeIndex = this.attributeStart;
            for (int i = 0; i < attributeCount; i++) 
            {
                if (++attributeIndex >= attributeCount) 
                { 
                    attributeIndex = 0;
                } 
                XmlAttributeNode attributeNode = attributeNodes[attributeIndex];
                if (attributeNode.IsLocalNameAndNamespaceUri(localName, namespaceUri))
                {
                    this.attributeStart = attributeIndex; 
                    return attributeNode;
                } 
            } 
            return null;
        } 

        public override string GetAttribute(int index)
        {
            return GetAttributeNode(index).ValueAsString; 
        }
 
        public override string GetAttribute(string name) 
        {
            XmlAttributeNode attributeNode = GetAttributeNode(name); 
            if (attributeNode == null)
                return null;
            return attributeNode.ValueAsString;
        } 

        public override string GetAttribute(string localName, string namespaceUri) 
        { 
            XmlAttributeNode attributeNode = GetAttributeNode(localName, namespaceUri);
            if (attributeNode == null) 
                return null;
            return attributeNode.ValueAsString;
        }
 
        public override string GetAttribute(XmlDictionaryString localName, XmlDictionaryString namespaceUri)
        { 
            XmlAttributeNode attributeNode = GetAttributeNode(localName, namespaceUri); 
            if (attributeNode == null)
                return null; 
            return attributeNode.ValueAsString;
        }

        public sealed override bool IsEmptyElement 
        {
            get 
            { 
                return node.IsEmptyElement;
            } 
        }

        public override string LocalName
        { 
            get
            { 
                if (this.localName == null) 
                {
                    this.localName = GetLocalName(true); 
                }

                return this.localName;
            } 
        }
 
        public override string LookupNamespace(string prefix) 
        {
            Namespace ns = nsMgr.LookupNamespace(prefix); 
            if (ns != null)
                return ns.Uri.GetString(NameTable);
            if (prefix == xmlns)
                return xmlnsNamespace; 
            return null;
        } 
 
        protected Namespace LookupNamespace(PrefixHandleType prefix)
        { 
            Namespace ns = nsMgr.LookupNamespace(prefix);
            if (ns == null)
                XmlExceptionHelper.ThrowUndefinedPrefix(this, PrefixHandle.GetString(prefix));
            return ns; 
        }
 
        protected Namespace LookupNamespace(PrefixHandle prefix) 
        {
            Namespace ns = nsMgr.LookupNamespace(prefix); 
            if (ns == null)
                XmlExceptionHelper.ThrowUndefinedPrefix(this, prefix.GetString());
            return ns;
        } 

        protected void ProcessAttributes() 
        { 
            if (attributeCount > 0)
            { 
                ProcessAttributes(attributeNodes, attributeCount);
            }
        }
 
        void ProcessAttributes(XmlAttributeNode[] attributeNodes, int attributeCount)
        { 
            for (int i = 0; i < attributeCount; i++) 
            {
                XmlAttributeNode attributeNode = attributeNodes[i]; 
                if (attributeNode.QNameType == QNameType.Normal)
                {
                    PrefixHandle prefix = attributeNode.Prefix;
                    if (!prefix.IsEmpty) 
                    {
                        attributeNode.Namespace = LookupNamespace(prefix); 
                    } 
                    else
                    { 
                        attributeNode.Namespace = NamespaceManager.EmptyNamespace;
                    }
                    attributeNode.AttributeText.Namespace = attributeNode.Namespace;
                } 
            }
 
            if (attributeCount > 1) 
            {
                if (attributeCount < 12) 
                {
                    // For small numbers of attributes, a naive n * (n - 1) / 2 comparisons to check for uniqueness is faster
                    for (int i = 0; i < attributeCount - 1; i++)
                    { 
                        XmlAttributeNode attributeNode1 = attributeNodes[i];
                        QNameType qnameType = attributeNode1.QNameType; 
                        if (qnameType == QNameType.Normal) 
                        {
                            for (int j = i + 1; j < attributeCount; j++) 
                            {
                                XmlAttributeNode attributeNode2 = attributeNodes[j];
                                if (attributeNode2.QNameType == QNameType.Normal && attributeNode1.LocalName == attributeNode2.LocalName && attributeNode1.Namespace.Uri == attributeNode2.Namespace.Uri)
                                { 
                                    XmlExceptionHelper.ThrowDuplicateAttribute(this, attributeNode1.Prefix.GetString(), attributeNode2.Prefix.GetString(), attributeNode1.LocalName.GetString(), attributeNode1.Namespace.Uri.GetString());
                                } 
                            } 
                        }
                        else 
                        {
                            Fx.Assert(qnameType == QNameType.Xmlns, "");
                            for (int j = i + 1; j < attributeCount; j++)
                            { 
                                XmlAttributeNode attributeNode2 = attributeNodes[j];
                                if (attributeNode2.QNameType == QNameType.Xmlns && attributeNode1.Namespace.Prefix == attributeNode2.Namespace.Prefix) 
                                    XmlExceptionHelper.ThrowDuplicateAttribute(this, xmlns, xmlns, attributeNode1.Namespace.Prefix.GetString(), xmlnsNamespace); 
                            }
                        } 
                    }
                }
                else
                { 
                    CheckAttributes(attributeNodes, attributeCount);
                } 
            } 
        }
 
        void CheckAttributes(XmlAttributeNode[] attributeNodes, int attributeCount)
        {
            // For large numbers of attributes, sorting the attributes (n * lg(n)) is faster
            if (attributeSorter == null) 
                attributeSorter = new AttributeSorter();
 
            if (!attributeSorter.Sort(attributeNodes, attributeCount)) 
            {
                int attribute1, attribute2; 
                attributeSorter.GetIndeces(out attribute1, out attribute2);
                if (attributeNodes[attribute1].QNameType == QNameType.Xmlns)
                    XmlExceptionHelper.ThrowDuplicateXmlnsAttribute(this, attributeNodes[attribute1].Namespace.Prefix.GetString(), xmlnsNamespace);
                else 
                    XmlExceptionHelper.ThrowDuplicateAttribute(this, attributeNodes[attribute1].Prefix.GetString(), attributeNodes[attribute2].Prefix.GetString(), attributeNodes[attribute1].LocalName.GetString(), attributeNodes[attribute1].Namespace.Uri.GetString());
            } 
        } 

        public override void MoveToAttribute(int index) 
        {
            MoveToNode(GetAttributeNode(index));
            this.attributeIndex = index;
        } 

        public override bool MoveToAttribute(string name) 
        { 
            XmlNode attributeNode = GetAttributeNode(name);
            if (attributeNode == null) 
                return false;
            MoveToNode(attributeNode);
            this.attributeIndex = this.attributeStart;
            return true; 
        }
 
        public override bool MoveToAttribute(string localName, string namespaceUri) 
        {
            XmlNode attributeNode = GetAttributeNode(localName, namespaceUri); 
            if (attributeNode == null)
                return false;
            MoveToNode(attributeNode);
            this.attributeIndex = this.attributeStart; 
            return true;
        } 
 
        public override bool MoveToElement()
        { 
            if (!node.CanMoveToElement)
                return false;
            if (depth == 0)
                MoveToDeclaration(); 
            else
                MoveToNode(elementNodes[depth]); 
            this.attributeIndex = -1; 
            return true;
        } 

        public override XmlNodeType MoveToContent()
        {
            do 
            {
                if (node.HasContent) 
                { 
                    if (node.NodeType != XmlNodeType.Text && node.NodeType != XmlNodeType.CDATA)
                        break; 

                    if (trailByteCount > 0)
                    {
                        break; 
                    }
 
                    if (this.value == null) 
                    {
                        if (!node.Value.IsWhitespace()) 
                            break;
                    }
                    else
                    { 
                        if (!XmlConverter.IsWhitespace(this.value))
                            break; 
                    } 
                }
                else 
                {
                    if (node.NodeType == XmlNodeType.Attribute)
                    {
                        MoveToElement(); 
                        break;
                    } 
                } 
            }
            while (Read()); 
            return node.NodeType;
        }

        public override bool MoveToFirstAttribute() 
        {
            if (!node.CanGetAttribute || attributeCount == 0) 
                return false; 
            MoveToNode(GetAttributeNode(0));
            this.attributeIndex = 0; 
            return true;
        }

        public override bool MoveToNextAttribute() 
        {
            if (!node.CanGetAttribute) 
                return false; 
            int attributeIndex = this.attributeIndex + 1;
            if (attributeIndex >= attributeCount) 
                return false;
            MoveToNode(GetAttributeNode(attributeIndex));
            this.attributeIndex = attributeIndex;
            return true; 
        }
 
        public override string NamespaceURI 
        {
            get 
            {
                if (this.ns == null)
                {
                    this.ns = GetNamespaceUri(true); 
                }
                return this.ns; 
            } 
        }
 
        public override XmlNameTable NameTable
        {
            get
            { 
                if (nameTable == null)
                { 
                    nameTable = new QuotaNameTable(this, quotas.MaxNameTableCharCount); 
                    nameTable.Add(xml);
                    nameTable.Add(xmlns); 
                    nameTable.Add(xmlnsNamespace);
                    nameTable.Add(xmlNamespace);
                    for (PrefixHandleType i = PrefixHandleType.A; i <= PrefixHandleType.Z; i++)
                    { 
                        nameTable.Add(PrefixHandle.GetString(i));
                    } 
                } 

                return nameTable; 
            }
        }

        public sealed override XmlNodeType NodeType 
        {
            get 
            { 
                return node.NodeType;
            } 
        }

        public override string Prefix
        { 
            get
            { 
                if (prefix == null) 
                {
                    QNameType qnameType = node.QNameType; 
                    if (qnameType == QNameType.Normal)
                    {
                        prefix = node.Prefix.GetString(NameTable);
                    } 
                    else if (qnameType == QNameType.Xmlns)
                    { 
                        if (node.Namespace.Prefix.IsEmpty) 
                            prefix = string.Empty;
                        else 
                            prefix = xmlns;
                    }
                    else
                    { 
                        prefix = xml;
                    } 
                } 

                return prefix; 
            }
        }

        public override char QuoteChar 
        {
            get 
            { 
                return node.QuoteChar;
            } 
        }

        string GetLocalName(bool enforceAtomization)
        { 
            if (this.localName != null)
            { 
                return this.localName; 
            }
 
            QNameType qnameType = node.QNameType;
            if (qnameType == QNameType.Normal)
            {
                if (enforceAtomization || nameTable != null) 
                {
                    return node.LocalName.GetString(NameTable); 
                } 
                else
                { 
                    return node.LocalName.GetString();
                }
            }
            else 
            {
                Fx.Assert(qnameType == QNameType.Xmlns, ""); 
                if (node.Namespace.Prefix.IsEmpty) 
                {
                    return xmlns; 
                }
                else
                {
                    if (enforceAtomization || nameTable != null) 
                    {
                        return node.Namespace.Prefix.GetString(NameTable); 
                    } 
                    else
                    { 
                        return node.Namespace.Prefix.GetString();
                    }
                }
            } 
        }
 
        string GetNamespaceUri(bool enforceAtomization) 
        {
            if (this.ns != null) 
            {
                return this.ns;
            }
 
            QNameType qnameType = node.QNameType;
            if (qnameType == QNameType.Normal) 
            { 
                if (enforceAtomization || nameTable != null)
                { 
                    return node.Namespace.Uri.GetString(NameTable);
                }
                else
                { 
                    return node.Namespace.Uri.GetString();
                } 
            } 
            else
            { 
                Fx.Assert(qnameType == QNameType.Xmlns, "");
                return xmlnsNamespace;
            }
        } 

        // In a XmlReader names of elements and attributes should be returned atomized 
        // (see XmlReader.NameTable on MSDN for more information) 
        // to allow a comparison based on object instance comparison instead of string comparison
        // This method allows to receive the localName and namespaceUri without enforcing atomization 
        // to avoid the cost of atomization if this is not necessary.
        public override void GetNonAtomizedNames(out string localName, out string namespaceUri)
        {
            localName = GetLocalName(false); 
            namespaceUri = GetNamespaceUri(false);
        } 
 
        public override bool IsLocalName(string localName)
        { 
            if (localName == null)
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("localName"));
            return node.IsLocalName(localName);
        } 

        public override bool IsLocalName(XmlDictionaryString localName) 
        { 
            if (localName == null)
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("localName")); 
            return node.IsLocalName(localName);
        }

        public override bool IsNamespaceUri(string namespaceUri) 
        {
            if (namespaceUri == null) 
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("namespaceUri"); 
            return node.IsNamespaceUri(namespaceUri);
        } 

        public override bool IsNamespaceUri(XmlDictionaryString namespaceUri)
        {
            if (namespaceUri == null) 
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("namespaceUri");
            return node.IsNamespaceUri(namespaceUri); 
        } 

        public override sealed bool IsStartElement() 
        {
            XmlNodeType nodeType = node.NodeType;
            if (nodeType == XmlNodeType.Element)
                return true; 
            if (nodeType == XmlNodeType.EndElement)
                return false; 
            if (nodeType == XmlNodeType.None) 
            {
                Read(); 
                if (node.NodeType == XmlNodeType.Element)
                    return true;
            }
            return (MoveToContent() == XmlNodeType.Element); 
        }
 
        public override bool IsStartElement(string name) 
        {
            if (name == null) 
                return false;
            int index = name.IndexOf(':');
            string prefix;
            string localName; 
            if (index == -1)
            { 
                prefix = string.Empty; 
                localName = name;
            } 
            else
            {
                prefix = name.Substring(0, index);
                localName = name.Substring(index + 1); 
            }
            return (node.NodeType == XmlNodeType.Element || IsStartElement()) && node.Prefix == prefix && node.LocalName == localName; 
        } 

        public override bool IsStartElement(string localName, string namespaceUri) 
        {
            if (localName == null)
                return false;
            if (namespaceUri == null) 
                return false;
            return (node.NodeType == XmlNodeType.Element || IsStartElement()) && node.LocalName == localName && node.IsNamespaceUri(namespaceUri); 
        } 

        public override bool IsStartElement(XmlDictionaryString localName, XmlDictionaryString namespaceUri) 
        {
            if (localName == null)
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("localName");
            if (namespaceUri == null) 
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("namespaceUri");
            return (node.NodeType == XmlNodeType.Element || IsStartElement()) && node.LocalName == localName && node.IsNamespaceUri(namespaceUri); 
        } 

        public override int IndexOfLocalName(string[] localNames, string namespaceUri) 
        {
            if (localNames == null)
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("localNames");
            if (namespaceUri == null) 
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("namespaceUri");
            QNameType qnameType = node.QNameType; 
            if (node.IsNamespaceUri(namespaceUri)) 
            {
                if (qnameType == QNameType.Normal) 
                {
                    StringHandle localName = node.LocalName;
                    for (int i = 0; i < localNames.Length; i++)
                    { 
                        string value = localNames[i];
                        if (value == null) 
                            throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(string.Format(CultureInfo.InvariantCulture, "localNames[{0}]", i)); 
                        if (localName == value)
                        { 
                            return i;
                        }
                    }
                } 
                else
                { 
                    Fx.Assert(qnameType == QNameType.Xmlns, ""); 
                    PrefixHandle prefix = node.Namespace.Prefix;
                    for (int i = 0; i < localNames.Length; i++) 
                    {
                        string value = localNames[i];
                        if (value == null)
                            throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(string.Format(CultureInfo.InvariantCulture, "localNames[{0}]", i)); 
                        if (prefix == value)
                        { 
                            return i; 
                        }
                    } 
                }
            }
            return -1;
        } 

        public override int IndexOfLocalName(XmlDictionaryString[] localNames, XmlDictionaryString namespaceUri) 
        { 
            if (localNames == null)
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("localNames"); 
            if (namespaceUri == null)
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("namespaceUri");
            QNameType qnameType = node.QNameType;
            if (node.IsNamespaceUri(namespaceUri)) 
            {
                if (qnameType == QNameType.Normal) 
                { 
                    StringHandle localName = node.LocalName;
                    for (int i = 0; i < localNames.Length; i++) 
                    {
                        XmlDictionaryString value = localNames[i];
                        if (value == null)
                            throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(string.Format(CultureInfo.InvariantCulture, "localNames[{0}]", i)); 
                        if (localName == value)
                        { 
                            return i; 
                        }
                    } 
                }
                else
                {
                    Fx.Assert(qnameType == QNameType.Xmlns, ""); 
                    PrefixHandle prefix = node.Namespace.Prefix;
                    for (int i = 0; i < localNames.Length; i++) 
                    { 
                        XmlDictionaryString value = localNames[i];
                        if (value == null) 
                            throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(string.Format(CultureInfo.InvariantCulture, "localNames[{0}]", i));
                        if (prefix == value)
                        {
                            return i; 
                        }
                    } 
                } 
            }
            return -1; 
        }

        public override int ReadValueChunk(char[] chars, int offset, int count)
        { 
            if (chars == null)
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("chars")); 
            if (offset < 0) 
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.ValueMustBeNonNegative)));
            if (offset > chars.Length) 
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.OffsetExceedsBufferSize, chars.Length)));
            if (count < 0)
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.ValueMustBeNonNegative)));
            if (count > chars.Length - offset) 
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.SizeExceedsRemainingBufferSpace, chars.Length - offset)));
            int actual; 
 
            if (this.value == null)
            { 
                if (node.QNameType == QNameType.Normal)
                {
                    if (node.Value.TryReadChars(chars, offset, count, out actual))
                        return actual; 
                }
            } 
 
            string value = this.Value;
            actual = Math.Min(count, value.Length); 
            value.CopyTo(0, chars, offset, actual);
            this.value = value.Substring(actual);
            return actual;
        } 

        public override int ReadValueAsBase64(byte[] buffer, int offset, int count) 
        { 
            if (buffer == null)
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("buffer")); 
            if (offset < 0)
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.ValueMustBeNonNegative)));
            if (offset > buffer.Length)
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.OffsetExceedsBufferSize, buffer.Length))); 
            if (count < 0)
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.ValueMustBeNonNegative))); 
            if (count > buffer.Length - offset) 
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.SizeExceedsRemainingBufferSpace, buffer.Length - offset)));
            if (count == 0) 
                return 0;
            int actual;
            if (this.value == null)
            { 
                if (trailByteCount == 0 && trailCharCount == 0)
                { 
                    if (node.QNameType == QNameType.Normal) 
                    {
                        if (node.Value.TryReadBase64(buffer, offset, count, out actual)) 
                            return actual;
                    }
                }
            } 
            return ReadBytes(Base64Encoding, 3, 4, buffer, offset, Math.Min(count, 512), false);
        } 
 
        public override string ReadElementContentAsString()
        { 
            if (node.NodeType != XmlNodeType.Element)
                MoveToStartElement();

            if (node.IsEmptyElement) 
            {
                Read(); 
                return string.Empty; 
            }
            else 
            {
                Read();
                string s = ReadContentAsString();
                ReadEndElement(); 
                return s;
            } 
        } 

        public override string ReadElementString() 
        {
            MoveToStartElement();
            if (IsEmptyElement)
            { 
                Read();
                return string.Empty; 
            } 
            else
            { 
                Read();
                string s = ReadString();
                ReadEndElement();
                return s; 
            }
        } 
 
        public override string ReadElementString(string name)
        { 
            MoveToStartElement(name);
            return ReadElementString();
        }
 
        public override string ReadElementString(string localName, string namespaceUri)
        { 
            MoveToStartElement(localName, namespaceUri); 
            return ReadElementString();
        } 

        public override void ReadStartElement()
        {
            if (node.NodeType != XmlNodeType.Element) 
                MoveToStartElement();
            Read(); 
        } 

        public override void ReadStartElement(string name) 
        {
            MoveToStartElement(name);
            Read();
        } 

        public override void ReadStartElement(string localName, string namespaceUri) 
        { 
            MoveToStartElement(localName, namespaceUri);
            Read(); 
        }

        public override void ReadEndElement()
        { 
            if (node.NodeType != XmlNodeType.EndElement && MoveToContent() != XmlNodeType.EndElement)
            { 
                int nodeDepth = node.NodeType == XmlNodeType.Element ? this.depth - 1 : this.depth; 
                if (nodeDepth == 0)
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.XmlEndElementNoOpenNodes))); 
                // If depth is non-zero, then the document isn't what was expected
                XmlElementNode elementNode = elementNodes[nodeDepth];
                XmlExceptionHelper.ThrowEndElementExpected(this, elementNode.LocalName.GetString(), elementNode.Namespace.Uri.GetString());
            } 
            Read();
        } 
 
        public override bool ReadAttributeValue()
        { 
            XmlAttributeTextNode attributeTextNode = node.AttributeText;
            if (attributeTextNode == null)
                return false;
            MoveToNode(attributeTextNode); 
            return true;
        } 
 
        public override ReadState ReadState
        { 
            get
            {
                return node.ReadState;
            } 
        }
 
        void SkipValue(XmlNode node) 
        {
            if (node.SkipValue) 
                Read();
        }

        public override bool TryGetBase64ContentLength(out int length) 
        {
            if (trailByteCount == 0 && trailCharCount == 0 && this.value == null) 
            { 
                XmlNode node = this.Node;
                if (node.IsAtomicValue) 
                    return node.Value.TryGetByteArrayLength(out length);
            }
            return base.TryGetBase64ContentLength(out length);
        } 

        public override byte[] ReadContentAsBase64() 
        { 
            if (trailByteCount == 0 && trailCharCount == 0 && this.value == null)
            { 
                XmlNode node = this.Node;
                if (node.IsAtomicValue)
                {
                    byte[] value = node.Value.ToByteArray(); 
                    if (value.Length > quotas.MaxArrayLength)
                        XmlExceptionHelper.ThrowMaxArrayLengthExceeded(this, quotas.MaxArrayLength); 
                    SkipValue(node); 
                    return value;
                } 
            }

            if (!bufferReader.IsStreamed)
                return ReadContentAsBase64(quotas.MaxArrayLength, bufferReader.Buffer.Length); 

            return ReadContentAsBase64(quotas.MaxArrayLength, XmlDictionaryReader.MaxInitialArrayLength);  // Initial count will get ignored 
        } 

        public override int ReadElementContentAsBase64(byte[] buffer, int offset, int count) 
        {
            if (!readingElement)
            {
                if (IsEmptyElement) 
                {
                    Read(); 
                    return 0; 
                }
 
                ReadStartElement();
                readingElement = true;
            }
 
            int i = ReadContentAsBase64(buffer, offset, count);
 
            if (i == 0) 
            {
                ReadEndElement(); 
                readingElement = false;
            }

            return i; 
        }
 
        public override int ReadContentAsBase64(byte[] buffer, int offset, int count) 
        {
            if (buffer == null) 
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("buffer"));
            if (offset < 0)
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.ValueMustBeNonNegative)));
            if (offset > buffer.Length) 
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.OffsetExceedsBufferSize, buffer.Length)));
            if (count < 0) 
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.ValueMustBeNonNegative))); 
            if (count > buffer.Length - offset)
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.SizeExceedsRemainingBufferSpace, buffer.Length - offset))); 
            if (count == 0)
                return 0;
            int actual;
            if (trailByteCount == 0 && trailCharCount == 0 && this.value == null) 
            {
                if (node.QNameType == QNameType.Normal) 
                { 
                    while (node.NodeType != XmlNodeType.Comment && node.Value.TryReadBase64(buffer, offset, count, out actual))
                    { 
                        if (actual != 0)
                            return actual;
                        Read();
                    } 
                }
            } 
            XmlNodeType nodeType = node.NodeType; 
            if (nodeType == XmlNodeType.Element || nodeType == XmlNodeType.EndElement)
                return 0; 
            return ReadBytes(Base64Encoding, 3, 4, buffer, offset, Math.Min(count, 512), true);
        }

        public override byte[] ReadContentAsBinHex() 
        {
            return ReadContentAsBinHex(quotas.MaxArrayLength); 
        } 

        public override int ReadElementContentAsBinHex(byte[] buffer, int offset, int count) 
        {
            if (!readingElement)
            {
                if (IsEmptyElement) 
                {
                    Read(); 
                    return 0; 
                }
 
                ReadStartElement();
                readingElement = true;
            }
 
            int i = ReadContentAsBinHex(buffer, offset, count);
 
            if (i == 0) 
            {
                ReadEndElement(); 
                readingElement = false;
            }

            return i; 
        }
 
        public override int ReadContentAsBinHex(byte[] buffer, int offset, int count) 
        {
            if (buffer == null) 
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("buffer"));
            if (offset < 0)
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.ValueMustBeNonNegative)));
            if (offset > buffer.Length) 
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.OffsetExceedsBufferSize, buffer.Length)));
            if (count < 0) 
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.ValueMustBeNonNegative))); 
            if (count > buffer.Length - offset)
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.SizeExceedsRemainingBufferSpace, buffer.Length - offset))); 
            if (count == 0)
                return 0;
            return ReadBytes(BinHexEncoding, 1, 2, buffer, offset, Math.Min(count, 512), true);
        } 

        int ReadBytes(Encoding encoding, int byteBlock, int charBlock, byte[] buffer, int offset, int byteCount, bool readContent) 
        { 
            // If there are any trailing buffer return them.
            if (trailByteCount > 0) 
            {
                int actual = Math.Min(trailByteCount, byteCount);
                Array.Copy(trailBytes, 0, buffer, offset, actual);
                trailByteCount -= actual; 
                Array.Copy(trailBytes, actual, trailBytes, 0, trailByteCount);
                return actual; 
            } 
            XmlNodeType nodeType = node.NodeType;
            if (nodeType == XmlNodeType.Element || nodeType == XmlNodeType.EndElement) 
                return 0;
            int maxCharCount;
            if (byteCount < byteBlock)
            { 
                // Convert at least charBlock chars
                maxCharCount = charBlock; 
            } 
            else
            { 
                // Round down to the nearest multiple of charBlock
                maxCharCount = byteCount / byteBlock * charBlock;
            }
            char[] chars = GetCharBuffer(maxCharCount); 
            int charCount = 0;
            while (true) 
            { 
                // If we didn't align on the boundary, then we might have some remaining characters
                if (trailCharCount > 0) 
                {
                    Array.Copy(trailChars, 0, chars, charCount, trailCharCount);
                    charCount += trailCharCount;
                    trailCharCount = 0; 
                }
                // Read until we at least get a charBlock 
                while (charCount < charBlock) 
                {
                    int actualCharCount; 
                    if (readContent)
                        actualCharCount = ReadContentAsChars(chars, charCount, maxCharCount - charCount);
                    else
                        actualCharCount = ReadValueChunk(chars, charCount, maxCharCount - charCount); 
                    if (actualCharCount == 0)
                        break; 
                    charCount += actualCharCount; 
                }
                // Trim so its a multiple of charBlock 
                if (charCount >= charBlock)
                {
                    trailCharCount = (charCount % charBlock);
                    if (trailCharCount > 0) 
                    {
                        if (trailChars == null) 
                            trailChars = new char[4]; 
                        charCount = charCount - trailCharCount;
                        Array.Copy(chars, charCount, trailChars, 0, trailCharCount); 
                    }
                }
                try
                { 
                    if (byteCount < byteBlock)
                    { 
                        if (trailBytes == null) 
                            trailBytes = new byte[3];
                        trailByteCount = encoding.GetBytes(chars, 0, charCount, trailBytes, 0); 
                        int actual = Math.Min(trailByteCount, byteCount);
                        Array.Copy(trailBytes, 0, buffer, offset, actual);
                        trailByteCount -= actual;
                        Array.Copy(trailBytes, actual, trailBytes, 0, trailByteCount); 
                        return actual;
                    } 
                    else 
                    {
                        // charCount is a multiple of charBlock and we have enough room to convert everything 
                        return encoding.GetBytes(chars, 0, charCount, buffer, offset);
                    }
                }
                catch (FormatException exception) 
                {
                    // Something was wrong with the format, see if we can strip the spaces 
                    int i = 0; 
                    int j = 0;
                    while (true) 
                    {
                        while (j < charCount && XmlConverter.IsWhitespace(chars[j]))
                            j++;
                        if (j == charCount) 
                            break;
                        chars[i++] = chars[j++]; 
                    } 
                    // No spaces, so don't try again
                    if (i == charCount) 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(exception.Message, exception.InnerException));
                    charCount = i;
                }
            } 
        }
 
        public override string ReadContentAsString() 
        {
            string value; 
            XmlNode node = this.Node;
            if (node.IsAtomicValue)
            {
                if (this.value != null) 
                {
                    value = this.value; 
                    if (node.AttributeText == null) 
                        this.value = string.Empty;
                } 
                else
                {
                    value = node.Value.GetString();
                    SkipValue(node); 
                    if (value.Length > quotas.MaxStringContentLength)
                        XmlExceptionHelper.ThrowMaxStringContentLengthExceeded(this, quotas.MaxStringContentLength); 
                } 
                return value;
            } 
            return base.ReadContentAsString(quotas.MaxStringContentLength);
        }

        public override Boolean ReadContentAsBoolean() 
        {
            XmlNode node = this.Node; 
            if (this.value == null && node.IsAtomicValue) 
            {
                bool value = node.Value.ToBoolean(); 
                SkipValue(node);
                return value;
            }
            return XmlConverter.ToBoolean(ReadContentAsString()); 
        }
 
        public override Int64 ReadContentAsLong() 
        {
            XmlNode node = this.Node; 
            if (this.value == null && node.IsAtomicValue)
            {
                Int64 value = node.Value.ToLong();
                SkipValue(node); 
                return value;
            } 
            return XmlConverter.ToInt64(ReadContentAsString()); 
        }
 
        public override Int32 ReadContentAsInt()
        {
            XmlNode node = this.Node;
            if (this.value == null && node.IsAtomicValue) 
            {
                Int32 value = node.Value.ToInt(); 
                SkipValue(node); 
                return value;
            } 
            return XmlConverter.ToInt32(ReadContentAsString());
        }

        public override DateTime ReadContentAsDateTime() 
        {
            XmlNode node = this.Node; 
            if (this.value == null && node.IsAtomicValue) 
            {
                DateTime value = node.Value.ToDateTime(); 
                SkipValue(node);
                return value;
            }
            return XmlConverter.ToDateTime(ReadContentAsString()); 
        }
 
        public override Double ReadContentAsDouble() 
        {
            XmlNode node = this.Node; 
            if (this.value == null && node.IsAtomicValue)
            {
                double value = node.Value.ToDouble();
                SkipValue(node); 
                return value;
            } 
            return XmlConverter.ToDouble(ReadContentAsString()); 
        }
 
        public override Single ReadContentAsFloat()
        {
            XmlNode node = this.Node;
            if (this.value == null && node.IsAtomicValue) 
            {
                float value = node.Value.ToSingle(); 
                SkipValue(node); 
                return value;
            } 
            return XmlConverter.ToSingle(ReadContentAsString());
        }

        public override Decimal ReadContentAsDecimal() 
        {
            XmlNode node = this.Node; 
            if (this.value == null && node.IsAtomicValue) 
            {
                decimal value = node.Value.ToDecimal(); 
                SkipValue(node);
                return value;
            }
            return XmlConverter.ToDecimal(ReadContentAsString()); 
        }
 
        public override UniqueId ReadContentAsUniqueId() 
        {
            XmlNode node = this.Node; 
            if (this.value == null && node.IsAtomicValue)
            {
                UniqueId value = node.Value.ToUniqueId();
                SkipValue(node); 
                return value;
            } 
            return XmlConverter.ToUniqueId(ReadContentAsString()); 
        }
 
        public override TimeSpan ReadContentAsTimeSpan()
        {
            XmlNode node = this.Node;
            if (this.value == null && node.IsAtomicValue) 
            {
                TimeSpan value = node.Value.ToTimeSpan(); 
                SkipValue(node); 
                return value;
            } 
            return XmlConverter.ToTimeSpan(ReadContentAsString());
        }

        public override Guid ReadContentAsGuid() 
        {
            XmlNode node = this.Node; 
            if (this.value == null && node.IsAtomicValue) 
            {
                Guid value = node.Value.ToGuid(); 
                SkipValue(node);
                return value;
            }
            return XmlConverter.ToGuid(ReadContentAsString()); 
        }
 
        public override object ReadContentAsObject() 
        {
            XmlNode node = this.Node; 
            if (this.value == null && node.IsAtomicValue)
            {
                object obj = node.Value.ToObject();
                SkipValue(node); 
                return obj;
            } 
            return ReadContentAsString(); 
        }
 
        public override object ReadContentAs(Type type, IXmlNamespaceResolver namespaceResolver)
        {
            if (type == typeof(ulong))
            { 
                if (this.value == null && node.IsAtomicValue)
                { 
                    ulong value = node.Value.ToULong(); 
                    SkipValue(node);
                    return value; 
                }
                else
                {
                    return XmlConverter.ToUInt64(ReadContentAsString()); 
                }
            } 
            else if (type == typeof(bool)) 
                return ReadContentAsBoolean();
            else if (type == typeof(int)) 
                return ReadContentAsInt();
            else if (type == typeof(long))
                return ReadContentAsLong();
            else if (type == typeof(float)) 
                return ReadContentAsFloat();
            else if (type == typeof(double)) 
                return ReadContentAsDouble(); 
            else if (type == typeof(decimal))
                return ReadContentAsDecimal(); 
            else if (type == typeof(DateTime))
                return ReadContentAsDateTime();
            else if (type == typeof(UniqueId))
                return ReadContentAsUniqueId(); 
            else if (type == typeof(Guid))
                return ReadContentAsGuid(); 
            else if (type == typeof(TimeSpan)) 
                return ReadContentAsTimeSpan();
            else if (type == typeof(object)) 
                return ReadContentAsObject();
            else
                return base.ReadContentAs(type, namespaceResolver);
        } 

        public override void ResolveEntity() 
        { 
            throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.XmlInvalidOperation)));
        } 

        public override void Skip()
        {
            if (node.ReadState != ReadState.Interactive) 
                return;
            if ((node.NodeType == XmlNodeType.Element || MoveToElement()) && !IsEmptyElement) 
            { 
                int depth = Depth;
                while (Read() && depth < Depth) 
                {
                    // Nothing, just read on
                }
                // consume end tag 
                if (node.NodeType == XmlNodeType.EndElement)
                    Read(); 
            } 
            else
            { 
                Read();
            }
        }
 
        public override string Value
        { 
            get 
            {
                if (value == null) 
                {
                    value = node.ValueAsString;
                }
 
                return value;
            } 
        } 

        public override Type ValueType 
        {
            get
            {
                if (this.value == null && node.QNameType == QNameType.Normal) 
                {
                    Type type = node.Value.ToType(); 
                    if (node.IsAtomicValue) 
                        return type;
                    if (type == typeof(byte[])) 
                        return type;
                }
                return typeof(string);
            } 
        }
 
        public override string XmlLang 
        {
            get 
            {
                return nsMgr.XmlLang;
            }
        } 

        public override XmlSpace XmlSpace 
        { 
            get
            { 
                return nsMgr.XmlSpace;
            }
        }
 
        public override bool TryGetLocalNameAsDictionaryString(out XmlDictionaryString localName)
        { 
            return node.TryGetLocalNameAsDictionaryString(out localName); 
        }
 
        public override bool TryGetNamespaceUriAsDictionaryString(out XmlDictionaryString localName)
        {
            return node.TryGetNamespaceUriAsDictionaryString(out localName);
        } 

        public override bool TryGetValueAsDictionaryString(out XmlDictionaryString value) 
        { 
            return node.TryGetValueAsDictionaryString(out value);
        } 

        public override Int16[] ReadInt16Array(string localName, string namespaceUri)
        {
            return Int16ArrayHelperWithString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength); 
        }
 
        public override Int16[] ReadInt16Array(XmlDictionaryString localName, XmlDictionaryString namespaceUri) 
        {
            return Int16ArrayHelperWithDictionaryString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength); 
        }

        public override Int32[] ReadInt32Array(string localName, string namespaceUri)
        { 
            return Int32ArrayHelperWithString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength);
        } 
 
        public override Int32[] ReadInt32Array(XmlDictionaryString localName, XmlDictionaryString namespaceUri)
        { 
            return Int32ArrayHelperWithDictionaryString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength);
        }

        public override Int64[] ReadInt64Array(string localName, string namespaceUri) 
        {
            return Int64ArrayHelperWithString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength); 
        } 

        public override Int64[] ReadInt64Array(XmlDictionaryString localName, XmlDictionaryString namespaceUri) 
        {
            return Int64ArrayHelperWithDictionaryString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength);
        }
 
        public override float[] ReadSingleArray(string localName, string namespaceUri)
        { 
            return SingleArrayHelperWithString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength); 
        }
 
        public override float[] ReadSingleArray(XmlDictionaryString localName, XmlDictionaryString namespaceUri)
        {
            return SingleArrayHelperWithDictionaryString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength);
        } 

        public override double[] ReadDoubleArray(string localName, string namespaceUri) 
        { 
            return DoubleArrayHelperWithString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength);
        } 

        public override double[] ReadDoubleArray(XmlDictionaryString localName, XmlDictionaryString namespaceUri)
        {
            return DoubleArrayHelperWithDictionaryString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength); 
        }
 
        public override decimal[] ReadDecimalArray(string localName, string namespaceUri) 
        {
            return DecimalArrayHelperWithString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength); 
        }

        public override decimal[] ReadDecimalArray(XmlDictionaryString localName, XmlDictionaryString namespaceUri)
        { 
            return DecimalArrayHelperWithDictionaryString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength);
        } 
 
        public override DateTime[] ReadDateTimeArray(string localName, string namespaceUri)
        { 
            return DateTimeArrayHelperWithString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength);
        }

        public override DateTime[] ReadDateTimeArray(XmlDictionaryString localName, XmlDictionaryString namespaceUri) 
        {
            return DateTimeArrayHelperWithDictionaryString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength); 
        } 

        public override Guid[] ReadGuidArray(string localName, string namespaceUri) 
        {
            return GuidArrayHelperWithString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength);
        }
 
        public override Guid[] ReadGuidArray(XmlDictionaryString localName, XmlDictionaryString namespaceUri)
        { 
            return GuidArrayHelperWithDictionaryString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength); 
        }
 
        public override TimeSpan[] ReadTimeSpanArray(string localName, string namespaceUri)
        {
            return TimeSpanArrayHelperWithString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength);
        } 

        public override TimeSpan[] ReadTimeSpanArray(XmlDictionaryString localName, XmlDictionaryString namespaceUri) 
        { 
            return TimeSpanArrayHelperWithDictionaryString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength);
        } 

        public string GetOpenElements()
        {
            string s = string.Empty; 
            for (int i = depth; i > 0; i--)
            { 
                string localName = elementNodes[i].LocalName.GetString(); 
                if (i != depth)
                    s += ", "; 
                s += localName;
            }
            return s;
        } 

        char[] GetCharBuffer(int count) 
        { 
            if (count > 1024)
                return new char[count]; 

            if (chars == null || chars.Length < count)
                chars = new char[count];
 
            return chars;
        } 
 
        void SignStartElement(XmlSigningNodeWriter writer)
        { 
            int prefixOffset, prefixLength;
            byte[] prefixBuffer = node.Prefix.GetString(out prefixOffset, out prefixLength);
            int localNameOffset, localNameLength;
            byte[] localNameBuffer = node.LocalName.GetString(out localNameOffset, out localNameLength); 
            writer.WriteStartElement(prefixBuffer, prefixOffset, prefixLength, localNameBuffer, localNameOffset, localNameLength);
        } 
 
        void SignAttribute(XmlSigningNodeWriter writer, XmlAttributeNode attributeNode)
        { 
            QNameType qnameType = attributeNode.QNameType;
            if (qnameType == QNameType.Normal)
            {
                int prefixOffset, prefixLength; 
                byte[] prefixBuffer = attributeNode.Prefix.GetString(out prefixOffset, out prefixLength);
                int localNameOffset, localNameLength; 
                byte[] localNameBuffer = attributeNode.LocalName.GetString(out localNameOffset, out localNameLength); 
                writer.WriteStartAttribute(prefixBuffer, prefixOffset, prefixLength, localNameBuffer, localNameOffset, localNameLength);
                attributeNode.Value.Sign(writer); 
                writer.WriteEndAttribute();
            }
            else
            { 
                Fx.Assert(qnameType == QNameType.Xmlns, "");
                int prefixOffset, prefixLength; 
                byte[] prefixBuffer = attributeNode.Namespace.Prefix.GetString(out prefixOffset, out prefixLength); 
                int nsOffset, nsLength;
                byte[] nsBuffer = attributeNode.Namespace.Uri.GetString(out nsOffset, out nsLength); 
                writer.WriteXmlnsAttribute(prefixBuffer, prefixOffset, prefixLength, nsBuffer, nsOffset, nsLength);
            }
        }
 
        void SignEndElement(XmlSigningNodeWriter writer)
        { 
            int prefixOffset, prefixLength; 
            byte[] prefixBuffer = node.Prefix.GetString(out prefixOffset, out prefixLength);
            int localNameOffset, localNameLength; 
            byte[] localNameBuffer = node.LocalName.GetString(out localNameOffset, out localNameLength);
            writer.WriteEndElement(prefixBuffer, prefixOffset, prefixLength, localNameBuffer, localNameOffset, localNameLength);
        }
 
        void SignNode(XmlSigningNodeWriter writer)
        { 
            switch (node.NodeType) 
            {
                case XmlNodeType.None: 
                    break;
                case XmlNodeType.Element:
                    SignStartElement(writer);
                    for (int i = 0; i < attributeCount; i++) 
                        SignAttribute(writer, attributeNodes[i]);
                    writer.WriteEndStartElement(node.IsEmptyElement); 
                    break; 
                case XmlNodeType.Text:
                case XmlNodeType.Whitespace: 
                case XmlNodeType.SignificantWhitespace:
                case XmlNodeType.CDATA:
                    node.Value.Sign(writer);
                    break; 
                case XmlNodeType.XmlDeclaration:
                    writer.WriteDeclaration(); 
                    break; 
                case XmlNodeType.Comment:
                    writer.WriteComment(node.Value.GetString()); 
                    break;
                case XmlNodeType.EndElement:
                    SignEndElement(writer);
                    break; 
                default:
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException()); 
            } 
        }
 
        public override bool CanCanonicalize
        {
            get
            { 
                return true;
            } 
        } 

        protected bool Signing 
        {
            get
            {
                return signing; 
            }
        } 
 
        protected void SignNode()
        { 
            if (signing)
            {
                SignNode(signingWriter);
            } 
        }
 
        public override void StartCanonicalization(Stream stream, bool includeComments, string[] inclusivePrefixes) 
        {
            if (signing) 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.XmlCanonicalizationStarted)));

            if (signingWriter == null)
                signingWriter = CreateSigningNodeWriter(); 

            signingWriter.SetOutput(XmlNodeWriter.Null, stream, includeComments, inclusivePrefixes); 
            nsMgr.Sign(signingWriter); 
            signing = true;
        } 

        public override void EndCanonicalization()
        {
            if (!signing) 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.XmlCanonicalizationNotStarted)));
 
            signingWriter.Flush(); 
            signingWriter.Close();
            signing = false; 
        }

        protected abstract XmlSigningNodeWriter CreateSigningNodeWriter();
 
        protected enum QNameType
        { 
            Normal, 
            Xmlns,
        } 

        protected class XmlNode
        {
            XmlNodeType nodeType; 
            PrefixHandle prefix;
            StringHandle localName; 
            ValueHandle value; 
            Namespace ns;
            bool hasValue; 
            bool canGetAttribute;
            bool canMoveToElement;
            ReadState readState;
            XmlAttributeTextNode attributeTextNode; 
            bool exitScope;
            int depthDelta; 
            bool isAtomicValue; 
            bool skipValue;
            QNameType qnameType; 
            bool hasContent;
            bool isEmptyElement;
            char quoteChar;
 
            protected enum XmlNodeFlags
            { 
                None = 0x00, 
                CanGetAttribute = 0x01,
                CanMoveToElement = 0x02, 
                HasValue = 0x04,
                AtomicValue = 0x08,
                SkipValue = 0x10,
                HasContent = 0x20 
            }
 
            protected XmlNode(XmlNodeType nodeType, 
                              PrefixHandle prefix,
                              StringHandle localName, 
                              ValueHandle value,
                              XmlNodeFlags nodeFlags,
                              ReadState readState,
                              XmlAttributeTextNode attributeTextNode, 
                              int depthDelta)
            { 
                this.nodeType = nodeType; 
                this.prefix = prefix;
                this.localName = localName; 
                this.value = value;
                this.ns = NamespaceManager.EmptyNamespace;
                this.hasValue = ((nodeFlags & XmlNodeFlags.HasValue) != 0);
                this.canGetAttribute = ((nodeFlags & XmlNodeFlags.CanGetAttribute) != 0); 
                this.canMoveToElement = ((nodeFlags & XmlNodeFlags.CanMoveToElement) != 0);
                this.isAtomicValue = ((nodeFlags & XmlNodeFlags.AtomicValue) != 0); 
                this.skipValue = ((nodeFlags & XmlNodeFlags.SkipValue) != 0); 
                this.hasContent = ((nodeFlags & XmlNodeFlags.HasContent) != 0);
                this.readState = readState; 
                this.attributeTextNode = attributeTextNode;
                this.exitScope = (nodeType == XmlNodeType.EndElement);
                this.depthDelta = depthDelta;
                this.isEmptyElement = false; 
                this.quoteChar = '"';
                this.qnameType = QNameType.Normal; 
            } 

            // Most nodes are read-only and fixed for the particular node type, but a few need to be tweaked 
            // QNameType needs to get set for all nodes with a qname (Element/Attribute)
            // NodeType gets set for WhiteSpace vs. SignificantWhitespace
            // ExitScope/IsEmptyElement is only updated by text for empty elements
            // QuoteChar is only updated by text for attributes 
            // IsAtomicValue is set to false for XmlnsAttributes so we don't have to check QNameType
 
            public bool HasValue { get { return hasValue; } } 
            public ReadState ReadState { get { return readState; } }
            public StringHandle LocalName { get { Fx.Assert(qnameType != QNameType.Xmlns, ""); return localName; } } 
            public PrefixHandle Prefix { get { Fx.Assert(qnameType != QNameType.Xmlns, ""); return prefix; } }
            public bool CanGetAttribute { get { return canGetAttribute; } }
            public bool CanMoveToElement { get { return canMoveToElement; } }
            public XmlAttributeTextNode AttributeText { get { return attributeTextNode; } } 
            public bool SkipValue { get { return skipValue; } }
            public ValueHandle Value { get { Fx.Assert(qnameType != QNameType.Xmlns, ""); return value; } } 
            public int DepthDelta { get { return depthDelta; } } 
            public bool HasContent { get { return hasContent; } }
 
            public XmlNodeType NodeType
            {
                get
                { 
                    return nodeType;
                } 
                set 
                {
                    nodeType = value; 
                }
            }

            public QNameType QNameType 
            {
                get 
                { 
                    return qnameType;
                } 
                set
                {
                    qnameType = value;
                } 
            }
 
            public Namespace Namespace 
            {
                get 
                {
                    return ns;
                }
                set 
                {
                    ns = value; 
                } 
            }
 
            public bool IsAtomicValue
            {
                get
                { 
                    return isAtomicValue;
                } 
                set 
                {
                    isAtomicValue = value; 
                }
            }

            public bool ExitScope 
            {
                get 
                { 
                    return exitScope;
                } 
                set
                {
                    exitScope = value;
                } 
            }
 
            public bool IsEmptyElement 
            {
                get 
                {
                    return isEmptyElement;
                }
                set 
                {
                    isEmptyElement = value; 
                } 
            }
 
            public char QuoteChar
            {
                get
                { 
                    return quoteChar;
                } 
                set 
                {
                    quoteChar = value; 
                }
            }

            public bool IsLocalName(string localName) 
            {
                if (qnameType == QNameType.Normal) 
                { 
                    return this.LocalName == localName;
                } 
                else
                {
                    Fx.Assert(qnameType == QNameType.Xmlns, "");
                    return this.Namespace.Prefix == localName; 
                }
            } 
 
            public bool IsLocalName(XmlDictionaryString localName)
            { 
                if (qnameType == QNameType.Normal)
                {
                    return this.LocalName == localName;
                } 
                else
                { 
                    Fx.Assert(qnameType == QNameType.Xmlns, ""); 
                    return this.Namespace.Prefix == localName;
                } 
            }

            public bool IsNamespaceUri(string ns)
            { 
                if (qnameType == QNameType.Normal)
                { 
                    return this.Namespace.IsUri(ns); 
                }
                else 
                {
                    Fx.Assert(qnameType == QNameType.Xmlns, "");
                    return ns == xmlnsNamespace;
                } 
            }
 
            public bool IsNamespaceUri(XmlDictionaryString ns) 
            {
                if (qnameType == QNameType.Normal) 
                {
                    return this.Namespace.IsUri(ns);
                }
                else 
                {
                    Fx.Assert(qnameType == QNameType.Xmlns, ""); 
                    return ns.Value == xmlnsNamespace; 
                }
            } 

            public bool IsLocalNameAndNamespaceUri(string localName, string ns)
            {
                if (qnameType == QNameType.Normal) 
                {
                    return this.LocalName == localName && this.Namespace.IsUri(ns); 
                } 
                else
                { 
                    Fx.Assert(qnameType == QNameType.Xmlns, "");
                    return this.Namespace.Prefix == localName && ns == xmlnsNamespace;
                }
            } 

            public bool IsLocalNameAndNamespaceUri(XmlDictionaryString localName, XmlDictionaryString ns) 
            { 
                if (qnameType == QNameType.Normal)
                { 
                    return this.LocalName == localName && this.Namespace.IsUri(ns);
                }
                else
                { 
                    Fx.Assert(qnameType == QNameType.Xmlns, "");
                    return this.Namespace.Prefix == localName && ns.Value == xmlnsNamespace; 
                } 
            }
 
            public bool IsPrefixAndLocalName(string prefix, string localName)
            {
                if (qnameType == QNameType.Normal)
                { 
                    return this.Prefix == prefix && this.LocalName == localName;
                } 
                else 
                {
                    Fx.Assert(qnameType == QNameType.Xmlns, ""); 
                    return prefix == xmlns && this.Namespace.Prefix == localName;
                }
            }
 
            public bool TryGetLocalNameAsDictionaryString(out XmlDictionaryString localName)
            { 
                if (qnameType == QNameType.Normal) 
                {
                    return this.LocalName.TryGetDictionaryString(out localName); 
                }
                else
                {
                    Fx.Assert(qnameType == QNameType.Xmlns, ""); 
                    localName = null;
                    return false; 
                } 
            }
 
            public bool TryGetNamespaceUriAsDictionaryString(out XmlDictionaryString ns)
            {
                if (qnameType == QNameType.Normal)
                { 
                    return this.Namespace.Uri.TryGetDictionaryString(out ns);
                } 
                else 
                {
                    Fx.Assert(qnameType == QNameType.Xmlns, ""); 
                    ns = null;
                    return false;
                }
            } 

            public bool TryGetValueAsDictionaryString(out XmlDictionaryString value) 
            { 
                if (qnameType == QNameType.Normal)
                { 
                    return this.Value.TryGetDictionaryString(out value);
                }
                else
                { 
                    Fx.Assert(qnameType == QNameType.Xmlns, "");
                    value = null; 
                    return false; 
                }
            } 

            public string ValueAsString
            {
                get 
                {
                    if (qnameType == QNameType.Normal) 
                    { 
                        return Value.GetString();
                    } 
                    else
                    {
                        Fx.Assert(qnameType == QNameType.Xmlns, "");
                        return Namespace.Uri.GetString(); 
                    }
                } 
            } 
        }
 
        protected class XmlElementNode : XmlNode
        {
            XmlEndElementNode endElementNode;
            int bufferOffset; 

            public XmlElementNode(XmlBufferReader bufferReader) 
                : this(new PrefixHandle(bufferReader), 
                       new StringHandle(bufferReader),
                       new ValueHandle(bufferReader)) 
            {
            }

            XmlElementNode(PrefixHandle prefix, StringHandle localName, ValueHandle value) 
                : base(XmlNodeType.Element,
                       prefix, 
                       localName, 
                       value,
                       XmlNodeFlags.CanGetAttribute|XmlNodeFlags.HasContent, 
                       ReadState.Interactive,
                       null,
                       -1)
            { 
                this.endElementNode = new XmlEndElementNode(prefix, localName, value);
            } 
 
            public XmlEndElementNode EndElement
            { 
                get
                {
                    return endElementNode;
                } 
            }
 
            public int BufferOffset 
            {
                get 
                {
                    return bufferOffset;
                }
                set 
                {
                    bufferOffset = value; 
                } 
            }
 
            public int NameOffset;
            public int NameLength;
        }
 
        protected class XmlAttributeNode : XmlNode
        { 
            public XmlAttributeNode(XmlBufferReader bufferReader) 
                : this(new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader))
            { 
            }

            XmlAttributeNode(PrefixHandle prefix, StringHandle localName, ValueHandle value)
                : base(XmlNodeType.Attribute, 
                       prefix,
                       localName, 
                       value, 
                       XmlNodeFlags.CanGetAttribute|XmlNodeFlags.CanMoveToElement|XmlNodeFlags.HasValue|XmlNodeFlags.AtomicValue,
                       ReadState.Interactive, 
                       new XmlAttributeTextNode(prefix, localName, value),
                       0)
            {
            } 
        }
 
        protected class XmlEndElementNode : XmlNode 
        {
            public XmlEndElementNode(PrefixHandle prefix, StringHandle localName, ValueHandle value) 
                : base(XmlNodeType.EndElement,
                       prefix,
                       localName,
                       value, 
                       XmlNodeFlags.HasContent,
                       ReadState.Interactive, 
                       null, 
                       -1)
            { 
            }
        }

        protected class XmlTextNode : XmlNode 
        {
            protected XmlTextNode(XmlNodeType nodeType, 
                              PrefixHandle prefix, 
                              StringHandle localName,
                              ValueHandle value, 
                              XmlNodeFlags nodeFlags,
                              ReadState readState,
                              XmlAttributeTextNode attributeTextNode,
                              int depthDelta) 
                :
                base(nodeType, prefix, localName, value, nodeFlags, readState, attributeTextNode, depthDelta) 
            { 
            }
        } 

        protected class XmlAtomicTextNode : XmlTextNode
        {
            public XmlAtomicTextNode(XmlBufferReader bufferReader) 
                : base(XmlNodeType.Text,
                       new PrefixHandle(bufferReader), 
                       new StringHandle(bufferReader), 
                       new ValueHandle(bufferReader),
                       XmlNodeFlags.HasValue | XmlNodeFlags.AtomicValue | XmlNodeFlags.SkipValue | XmlNodeFlags.HasContent, 
                       ReadState.Interactive,
                       null,
                       0)
            { 
            }
        } 
 
        protected class XmlComplexTextNode : XmlTextNode
        { 
            public XmlComplexTextNode(XmlBufferReader bufferReader)
                : base(XmlNodeType.Text,
                       new PrefixHandle(bufferReader),
                       new StringHandle(bufferReader), 
                       new ValueHandle(bufferReader),
                       XmlNodeFlags.HasValue | XmlNodeFlags.HasContent, 
                       ReadState.Interactive, 
                       null,
                       0) 
            {
            }
        }
 
        protected class XmlWhitespaceTextNode : XmlTextNode
        { 
            public XmlWhitespaceTextNode(XmlBufferReader bufferReader) 
                : base(XmlNodeType.Whitespace,
                       new PrefixHandle(bufferReader), 
                       new StringHandle(bufferReader),
                       new ValueHandle(bufferReader),
                       XmlNodeFlags.HasValue,
                       ReadState.Interactive, 
                       null,
                       0) 
            { 
            }
        } 

        protected class XmlCDataNode : XmlTextNode
        {
            public XmlCDataNode(XmlBufferReader bufferReader) 
                : base(XmlNodeType.CDATA,
                       new PrefixHandle(bufferReader), 
                       new StringHandle(bufferReader), 
                       new ValueHandle(bufferReader),
                       XmlNodeFlags.HasValue | XmlNodeFlags.HasContent, 
                       ReadState.Interactive,
                       null,
                       0)
            { 
            }
        } 
 
        protected class XmlAttributeTextNode : XmlTextNode
        { 
            public XmlAttributeTextNode(PrefixHandle prefix, StringHandle localName, ValueHandle value)
                : base(XmlNodeType.Text,
                       prefix,
                       localName, 
                       value,
                       XmlNodeFlags.HasValue|XmlNodeFlags.CanGetAttribute|XmlNodeFlags.CanMoveToElement|XmlNodeFlags.AtomicValue|XmlNodeFlags.HasContent, 
                       ReadState.Interactive, 
                       null,
                       1) 
            {
            }
        }
 
        protected class XmlInitialNode : XmlNode
        { 
            public XmlInitialNode(XmlBufferReader bufferReader) 
                : base(XmlNodeType.None,
                       new PrefixHandle(bufferReader), 
                       new StringHandle(bufferReader),
                       new ValueHandle(bufferReader),
                       XmlNodeFlags.None,
                       ReadState.Initial, 
                       null,
                       0) 
            { 
            }
        } 

        protected class XmlDeclarationNode : XmlNode
        {
            public XmlDeclarationNode(XmlBufferReader bufferReader) 
                : base(XmlNodeType.XmlDeclaration,
                       new PrefixHandle(bufferReader), 
                       new StringHandle(bufferReader), 
                       new ValueHandle(bufferReader),
                       XmlNodeFlags.CanGetAttribute, 
                       ReadState.Interactive,
                       null,
                       0)
            { 
            }
        } 
 
        protected class XmlCommentNode : XmlNode
        { 
            public XmlCommentNode(XmlBufferReader bufferReader)
                : base(XmlNodeType.Comment,
                       new PrefixHandle(bufferReader),
                       new StringHandle(bufferReader), 
                       new ValueHandle(bufferReader),
                       XmlNodeFlags.HasValue, 
                       ReadState.Interactive, 
                       null,
                       0) 
            {
            }
        }
 
        protected class XmlEndOfFileNode : XmlNode
        { 
            public XmlEndOfFileNode(XmlBufferReader bufferReader) 
                : base(XmlNodeType.None,
                       new PrefixHandle(bufferReader), 
                       new StringHandle(bufferReader),
                       new ValueHandle(bufferReader),
                       XmlNodeFlags.None,
                       ReadState.EndOfFile, 
                       null,
                       0) 
            { 
            }
        } 

        protected class XmlClosedNode : XmlNode
        {
            public XmlClosedNode(XmlBufferReader bufferReader) 
                : base(XmlNodeType.None,
                       new PrefixHandle(bufferReader), 
                       new StringHandle(bufferReader), 
                       new ValueHandle(bufferReader),
                       XmlNodeFlags.None, 
                       ReadState.Closed,
                       null,
                       0)
            { 
            }
        } 
 
        class AttributeSorter : IComparer
        { 
            object[] indeces;
            XmlAttributeNode[] attributeNodes;
            int attributeCount;
            int attributeIndex1; 
            int attributeIndex2;
 
            public bool Sort(XmlAttributeNode[] attributeNodes, int attributeCount) 
            {
                this.attributeIndex1 = -1; 
                this.attributeIndex2 = -1;
                this.attributeNodes = attributeNodes;
                this.attributeCount = attributeCount;
                bool sorted = Sort(); 
                this.attributeNodes = null;
                this.attributeCount = 0; 
                return sorted; 
            }
 
            public void GetIndeces(out int attributeIndex1, out int attributeIndex2)
            {
                attributeIndex1 = this.attributeIndex1;
                attributeIndex2 = this.attributeIndex2; 
            }
 
            public void Close() 
            {
                if (indeces != null && indeces.Length > 32) 
                {
                    indeces = null;
                }
            } 

            bool Sort() 
            { 
                // Optimistically use the last sort order and check to see if that works.  This helps the case
                // where elements with large numbers of attributes are repeated. 
                if (indeces != null && indeces.Length == attributeCount && IsSorted())
                    return true;

                object[] newIndeces = new object[attributeCount]; 
                for (int i = 0; i < newIndeces.Length; i++)
                    newIndeces[i] = i; 
                this.indeces = newIndeces; 
                Array.Sort(indeces, 0, attributeCount, this);
                return IsSorted(); 
            }

            bool IsSorted()
            { 
                for (int i = 0; i < indeces.Length - 1; i++)
                { 
                    if (Compare(indeces[i], indeces[i + 1]) >= 0) 
                    {
                        attributeIndex1 = (int)indeces[i]; 
                        attributeIndex2 = (int)indeces[i + 1];
                        return false;
                    }
                } 
                return true;
            } 
 
            public int Compare(object obj1, object obj2)
            { 
                int index1 = (int)obj1;
                int index2 = (int)obj2;
                XmlAttributeNode attribute1 = attributeNodes[index1];
                XmlAttributeNode attribute2 = attributeNodes[index2]; 

                int i = CompareQNameType(attribute1.QNameType, attribute2.QNameType); 
                if (i == 0) 
                {
                    QNameType qnameType = attribute1.QNameType; 
                    if (qnameType == QNameType.Normal)
                    {
                        i = attribute1.LocalName.CompareTo(attribute2.LocalName);
                        if (i == 0) 
                        {
                            i = attribute1.Namespace.Uri.CompareTo(attribute2.Namespace.Uri); 
                        } 
                    }
                    else 
                    {
                        Fx.Assert(qnameType == QNameType.Xmlns, "");
                        i = attribute1.Namespace.Prefix.CompareTo(attribute2.Namespace.Prefix);
                    } 
                }
 
                return i; 
            }
 
            public int CompareQNameType(QNameType type1, QNameType type2)
            {
                return (int)type1 - (int)type2;
            } 
        }
 
        class NamespaceManager 
        {
            XmlBufferReader bufferReader; 
            Namespace[] namespaces;
            int nsCount;
            int depth;
            Namespace[] shortPrefixUri; 
            static Namespace emptyNamespace = new Namespace(XmlBufferReader.Empty);
            static Namespace xmlNamespace; 
            XmlAttribute[] attributes; 
            int attributeCount;
            XmlSpace space; 
            string lang;

            public NamespaceManager(XmlBufferReader bufferReader)
            { 
                this.bufferReader = bufferReader;
                this.shortPrefixUri = new Namespace[(int)PrefixHandleType.Max]; 
                this.shortPrefixUri[(int)PrefixHandleType.Empty] = emptyNamespace; 
                this.namespaces = null;
                this.nsCount = 0; 
                this.attributes = null;
                this.attributeCount = 0;
                this.space = XmlSpace.None;
                this.lang = string.Empty; 
                this.depth = 0;
            } 
 
            public void Close()
            { 
                if (namespaces != null && namespaces.Length > 32)
                    namespaces = null;
                if (attributes != null && attributes.Length > 4)
                    attributes = null; 
                lang = string.Empty;
            } 
 
            static public Namespace XmlNamespace
            { 
                get
                {
                    if (xmlNamespace == null)
                    { 
                        byte[] xmlBuffer =
                            { 
                                (byte)'x',(byte)'m',(byte)'l', 
                                (byte)'h',(byte)'t',(byte)'t',(byte)'p',(byte)':',(byte)'/',(byte)'/',(byte)'w',
                                (byte)'w',(byte)'w',(byte)'.',(byte)'w',(byte)'3',(byte)'.',(byte)'o',(byte)'r', 
                                (byte)'g',(byte)'/',(byte)'X',(byte)'M',(byte)'L',(byte)'/',(byte)'1',(byte)'9',
                                (byte)'9',(byte)'8',(byte)'/',(byte)'n',(byte)'a',(byte)'m',(byte)'e',(byte)'s',
                                (byte)'p',(byte)'a',(byte)'c',(byte)'e'
                            }; 
                        Namespace nameSpace = new Namespace(new XmlBufferReader(xmlBuffer));
                        nameSpace.Prefix.SetValue(0, 3); 
                        nameSpace.Uri.SetValue(3, xmlBuffer.Length - 3); 
                        xmlNamespace = nameSpace;
                    } 
                    return xmlNamespace;
                }
            }
 
            static public Namespace EmptyNamespace
            { 
                get 
                {
                    return emptyNamespace; 
                }
            }

            public string XmlLang 
            {
                get 
                { 
                    return lang;
                } 
            }

            public XmlSpace XmlSpace
            { 
                get
                { 
                    return space; 
                }
            } 

            public void Clear()
            {
                if (nsCount != 0) 
                {
                    if (shortPrefixUri != null) 
                    { 
                        for (int i = 0; i < shortPrefixUri.Length; i++)
                        { 
                            shortPrefixUri[i] = null;
                        }
                    }
                    shortPrefixUri[(int)PrefixHandleType.Empty] = emptyNamespace; 
                    nsCount = 0;
                } 
                this.attributeCount = 0; 
                this.space = XmlSpace.None;
                this.lang = string.Empty; 
                this.depth = 0;
            }

            public void EnterScope() 
            {
                depth++; 
            } 

            public void ExitScope() 
            {
                while (nsCount > 0)
                {
                    Namespace nameSpace = namespaces[nsCount - 1]; 
                    if (nameSpace.Depth != depth)
                        break; 
                    PrefixHandleType shortPrefix; 
                    if (nameSpace.Prefix.TryGetShortPrefix(out shortPrefix))
                    { 
                        shortPrefixUri[(int)shortPrefix] = nameSpace.OuterUri;
                    }
                    nsCount--;
                } 
                while (attributeCount > 0)
                { 
                    XmlAttribute attribute = attributes[attributeCount - 1]; 
                    if (attribute.Depth != depth)
                        break; 
                    space = attribute.XmlSpace;
                    lang = attribute.XmlLang;
                    attributeCount--;
                } 
                depth--;
            } 
 
            public void Sign(XmlSigningNodeWriter writer)
            { 
                for (int i = 0; i < nsCount; i++)
                {
                    PrefixHandle prefix = namespaces[i].Prefix;
                    bool found = false; 
                    for (int j = i + 1; j < nsCount; j++)
                    { 
                        if (Equals(prefix, namespaces[j].Prefix)) 
                        {
                            found = true; 
                            break;
                        }
                    }
                    if (!found) 
                    {
                        int prefixOffset, prefixLength; 
                        byte[] prefixBuffer = prefix.GetString(out prefixOffset, out prefixLength); 
                        int nsOffset, nsLength;
                        byte[] nsBuffer = namespaces[i].Uri.GetString(out nsOffset, out nsLength); 
                        writer.WriteXmlnsAttribute(prefixBuffer, prefixOffset, prefixLength, nsBuffer, nsOffset, nsLength);
                    }
                }
            } 

            public void AddLangAttribute(string lang) 
            { 
                AddAttribute();
                this.lang = lang; 
            }

            public void AddSpaceAttribute(XmlSpace space)
            { 
                AddAttribute();
                this.space = space; 
            } 

            void AddAttribute() 
            {
                if (attributes == null)
                {
                    attributes = new XmlAttribute[1]; 
                }
                else if (attributes.Length == attributeCount) 
                { 
                    XmlAttribute[] newAttributes = new XmlAttribute[attributeCount * 2];
                    Array.Copy(attributes, newAttributes, attributeCount); 
                    attributes = newAttributes;
                }
                XmlAttribute attribute = attributes[attributeCount];
                if (attribute == null) 
                {
                    attribute = new XmlAttribute(); 
                    attributes[attributeCount] = attribute; 
                }
                attribute.XmlLang = this.lang; 
                attribute.XmlSpace = this.space;
                attribute.Depth = depth;
                attributeCount++;
            } 

            public void Register(Namespace nameSpace) 
            { 
                PrefixHandleType shortPrefix;
                if (nameSpace.Prefix.TryGetShortPrefix(out shortPrefix)) 
                {
                    nameSpace.OuterUri = shortPrefixUri[(int)shortPrefix];
                    shortPrefixUri[(int)shortPrefix] = nameSpace;
                } 
                else
                { 
                    nameSpace.OuterUri = null; 
                }
            } 

            public Namespace AddNamespace()
            {
                if (namespaces == null) 
                {
                    namespaces = new Namespace[4]; 
                } 
                else if (namespaces.Length == nsCount)
                { 
                    Namespace[] newNamespaces = new Namespace[nsCount * 2];
                    Array.Copy(namespaces, newNamespaces, nsCount);
                    namespaces = newNamespaces;
                } 
                Namespace nameSpace = namespaces[nsCount];
                if (nameSpace == null) 
                { 
                    nameSpace = new Namespace(bufferReader);
                    namespaces[nsCount] = nameSpace; 
                }
                nameSpace.Clear();
                nameSpace.Depth = depth;
                nsCount++; 
                return nameSpace;
            } 
 
            public Namespace LookupNamespace(PrefixHandleType prefix)
            { 
                return shortPrefixUri[(int)prefix];
            }

            public Namespace LookupNamespace(PrefixHandle prefix) 
            {
                PrefixHandleType shortPrefix; 
                if (prefix.TryGetShortPrefix(out shortPrefix)) 
                    return LookupNamespace(shortPrefix);
                for (int i = nsCount - 1; i >= 0; i--) 
                {
                    Namespace nameSpace = namespaces[i];
                    if (nameSpace.Prefix == prefix)
                        return nameSpace; 
                }
                if (prefix.IsXml) 
                    return XmlNamespace; 
                return null;
            } 

            public Namespace LookupNamespace(string prefix)
            {
                PrefixHandleType shortPrefix; 
                if (TryGetShortPrefix(prefix, out shortPrefix))
                    return LookupNamespace(shortPrefix); 
                for (int i = nsCount - 1; i >= 0; i--) 
                {
                    Namespace nameSpace = namespaces[i]; 
                    if (nameSpace.Prefix == prefix)
                        return nameSpace;
                }
                if (prefix == "xml") 
                    return XmlNamespace;
                return null; 
            } 

            bool TryGetShortPrefix(string s, out PrefixHandleType shortPrefix) 
            {
                int length = s.Length;
                if (length == 0)
                { 
                    shortPrefix = PrefixHandleType.Empty;
                    return true; 
                } 
                if (length == 1)
                { 
                    char ch = s[0];
                    if (ch >= 'a' && ch <= 'z')
                    {
                        shortPrefix = PrefixHandle.GetAlphaPrefix(ch - 'a'); 
                        return true;
                    } 
                } 
                shortPrefix = PrefixHandleType.Empty;
                return false; 
            }

            class XmlAttribute
            { 
                XmlSpace space;
                string lang; 
                int depth; 

                public XmlAttribute() 
                {
                }

                public int Depth 
                {
                    get 
                    { 
                        return depth;
                    } 
                    set
                    {
                        depth = value;
                    } 
                }
 
                public string XmlLang 
                {
                    get 
                    {
                        return lang;
                    }
                    set 
                    {
                        lang = value; 
                    } 
                }
 
                public XmlSpace XmlSpace
                {
                    get
                    { 
                        return space;
                    } 
                    set 
                    {
                        space = value; 
                    }
                }
            }
        } 

        protected class Namespace 
        { 
            PrefixHandle prefix;
            StringHandle uri; 
            int depth;
            Namespace outerUri;
            string uriString;
 
            public Namespace(XmlBufferReader bufferReader)
            { 
                this.prefix = new PrefixHandle(bufferReader); 
                this.uri = new StringHandle(bufferReader);
                this.outerUri = null; 
                this.uriString = null;
            }

            public void Clear() 
            {
                this.uriString = null; 
            } 

            public int Depth 
            {
                get
                {
                    return depth; 
                }
                set 
                { 
                    depth = value;
                } 
            }

            public PrefixHandle Prefix
            { 
                get
                { 
                    return prefix; 
                }
            } 

            public bool IsUri(string s)
            {
                Fx.Assert(s != null, ""); 
                if (object.ReferenceEquals(s, uriString))
                    return true; 
                if (uri == s) 
                {
                    uriString = s; 
                    return true;
                }
                return false;
            } 

            public bool IsUri(XmlDictionaryString s) 
            { 
                if (object.ReferenceEquals(s.Value, uriString))
                    return true; 
                if (uri == s)
                {
                    uriString = s.Value;
                    return true; 
                }
                return false; 
            } 

            public StringHandle Uri 
            {
                get
                {
                    return uri; 
                }
            } 
 
            public Namespace OuterUri
            { 
                get
                {
                    return outerUri;
                } 
                set
                { 
                    outerUri = value; 
                }
            } 
        }

        class QuotaNameTable : XmlNameTable
        { 
            XmlDictionaryReader reader;
            XmlNameTable nameTable; 
            int maxCharCount; 
            int charCount;
 
            public QuotaNameTable(XmlDictionaryReader reader, int maxCharCount)
            {
                this.reader = reader;
                this.nameTable = new NameTable(); 
                this.maxCharCount = maxCharCount;
                this.charCount = 0; 
            } 

            public override string Get(char[] chars, int offset, int count) 
            {
                return nameTable.Get(chars, offset, count);
            }
 
            public override string Get(string value)
            { 
                return nameTable.Get(value); 
            }
 
            void Add(int charCount)
            {
                if (charCount > this.maxCharCount - this.charCount)
                    XmlExceptionHelper.ThrowMaxNameTableCharCountExceeded(reader, maxCharCount); 
                this.charCount += charCount;
            } 
 
            public override string Add(char[] chars, int offset, int count)
            { 
                string s = nameTable.Get(chars, offset, count);
                if (s != null)
                    return s;
                Add(count); 
                return nameTable.Add(chars, offset, count);
            } 
 
            public override string Add(string value)
            { 
                string s = nameTable.Get(value);
                if (s != null)
                    return s;
                Add(value.Length); 
                return nameTable.Add(value);
            } 
        } 
    }
} 

// 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