XmlBaseReader.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / Serialization / System / Xml / XmlBaseReader.cs / 1 / 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.IO;
    using System.Xml; 
    using System.Collections;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    using System.Security; 
    using System.Text;
    using System.Globalization; 
    using System.Runtime.Serialization; 
    using System.Collections.Generic;
    using System.Collections.ObjectModel; 

    // 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 (localName == null)
                { 
                    QNameType qnameType = node.QNameType;
                    if (qnameType == QNameType.Normal) 
                    { 
                        localName = node.LocalName.GetString(NameTable);
                    } 
                    else
                    {
                        DiagnosticUtility.DebugAssert(qnameType == QNameType.Xmlns, "");
                        if (node.Namespace.Prefix.IsEmpty) 
                            localName = xmlns;
                        else 
                            localName = node.Namespace.Prefix.GetString(NameTable); 
                    }
                } 

                return 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
                        { 
                            DiagnosticUtility.DebugAssert(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));
        }

        public override bool MoveToAttribute(string name) 
        {
            XmlNode attributeNode = GetAttributeNode(name); 
            if (attributeNode == null) 
                return false;
            MoveToNode(attributeNode); 
            return true;
        }

        public override bool MoveToAttribute(string localName, string namespaceUri) 
        {
            XmlNode attributeNode = GetAttributeNode(localName, namespaceUri); 
            if (attributeNode == null) 
                return false;
            MoveToNode(attributeNode); 
            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 (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 (ns == null)
                {
                    QNameType qnameType = node.QNameType;
                    if (qnameType == QNameType.Normal) 
                    {
                        ns = node.Namespace.Uri.GetString(NameTable); 
                    } 
                    else
                    { 
                        DiagnosticUtility.DebugAssert(qnameType == QNameType.Xmlns, "");
                        ns = xmlnsNamespace;
                    }
                } 
                return 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; 
            }
        } 

        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
                { 
                    DiagnosticUtility.DebugAssert(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
                { 
                    DiagnosticUtility.DebugAssert(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 
            { 
                DiagnosticUtility.DebugAssert(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 { DiagnosticUtility.DebugAssert(qnameType != QNameType.Xmlns, ""); return localName; } }
            public PrefixHandle Prefix { get { DiagnosticUtility.DebugAssert(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 { DiagnosticUtility.DebugAssert(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 
                {
                    DiagnosticUtility.DebugAssert(qnameType == QNameType.Xmlns, ""); 
                    return this.Namespace.Prefix == localName; 
                }
            } 

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

            public bool IsNamespaceUri(string ns) 
            { 
                if (qnameType == QNameType.Normal)
                { 
                    return this.Namespace.IsUri(ns);
                }
                else
                { 
                    DiagnosticUtility.DebugAssert(qnameType == QNameType.Xmlns, "");
                    return ns == xmlnsNamespace; 
                } 
            }
 
            public bool IsNamespaceUri(XmlDictionaryString ns)
            {
                if (qnameType == QNameType.Normal)
                { 
                    return this.Namespace.IsUri(ns);
                } 
                else 
                {
                    DiagnosticUtility.DebugAssert(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
                {
                    DiagnosticUtility.DebugAssert(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 
                { 
                    DiagnosticUtility.DebugAssert(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
                {
                    DiagnosticUtility.DebugAssert(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
                { 
                    DiagnosticUtility.DebugAssert(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
                {
                    DiagnosticUtility.DebugAssert(qnameType == QNameType.Xmlns, "");
                    ns = null; 
                    return false;
                } 
            } 

            public bool TryGetValueAsDictionaryString(out XmlDictionaryString value) 
            {
                if (qnameType == QNameType.Normal)
                {
                    return this.Value.TryGetDictionaryString(out value); 
                }
                else 
                { 
                    DiagnosticUtility.DebugAssert(qnameType == QNameType.Xmlns, "");
                    value = null; 
                    return false;
                }
            }
 
            public string ValueAsString
            { 
                get 
                {
                    if (qnameType == QNameType.Normal) 
                    {
                        return Value.GetString();
                    }
                    else 
                    {
                        DiagnosticUtility.DebugAssert(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
                    { 
                        DiagnosticUtility.DebugAssert(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)
            { 
                DiagnosticUtility.DebugAssert(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.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

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