XmlBinaryReader.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

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

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------
namespace System.Xml
{ 
    using System;
    using System.IO; 
    using System.Runtime; 
    using System.Runtime.Serialization;
    using System.Security; 

    public interface IXmlBinaryReaderInitializer
    {
        void SetInput(byte[] buffer, int offset, int count, 
                            IXmlDictionary dictionary,
                            XmlDictionaryReaderQuotas quotas, 
                            XmlBinaryReaderSession session, 
                            OnXmlDictionaryReaderClose onClose);
        void SetInput(Stream stream, 
                             IXmlDictionary dictionary,
                             XmlDictionaryReaderQuotas quotas,
                             XmlBinaryReaderSession session,
                             OnXmlDictionaryReaderClose onClose); 
    }
 
    class XmlBinaryReader : XmlBaseReader, IXmlBinaryReaderInitializer 
    {
        bool isTextWithEndElement; 
        bool buffered;
        ArrayState arrayState;
        int arrayCount;
        int maxBytesPerRead; 
        XmlBinaryNodeType arrayNodeType;
        OnXmlDictionaryReaderClose onClose; 
 
        public XmlBinaryReader()
        { 
        }

        public void SetInput(byte[] buffer, int offset, int count,
                            IXmlDictionary dictionary, 
                            XmlDictionaryReaderQuotas quotas,
                            XmlBinaryReaderSession session, 
                            OnXmlDictionaryReaderClose onClose) 
        {
            if (buffer == null) 
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("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))); 
            MoveToInitial(quotas, session, onClose);
            BufferReader.SetBuffer(buffer, offset, count, dictionary, session);
            this.buffered = true;
        } 

        public void SetInput(Stream stream, 
                             IXmlDictionary dictionary, 
                             XmlDictionaryReaderQuotas quotas,
                             XmlBinaryReaderSession session, 
                             OnXmlDictionaryReaderClose onClose)
        {
            if (stream == null)
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("stream"); 
            MoveToInitial(quotas, session, onClose);
            BufferReader.SetBuffer(stream, dictionary, session); 
            this.buffered = false; 
        }
 
        void MoveToInitial(XmlDictionaryReaderQuotas quotas, XmlBinaryReaderSession session, OnXmlDictionaryReaderClose onClose)
        {
            MoveToInitial(quotas);
            this.maxBytesPerRead = quotas.MaxBytesPerRead; 
            this.arrayState = ArrayState.None;
            this.onClose = onClose; 
            this.isTextWithEndElement = false; 
        }
 
        public override void Close()
        {
            base.Close();
            OnXmlDictionaryReaderClose onClose = this.onClose; 
            this.onClose = null;
            if (onClose != null) 
            { 
                try
                { 
                    onClose(this);
                }
                catch (Exception e)
                { 
                    if (Fx.IsFatal(e)) throw;
 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(e); 
                }
            } 
        }

        public override string ReadElementContentAsString()
        { 
            if (this.Node.NodeType != XmlNodeType.Element)
                MoveToStartElement(); 
            if (!CanOptimizeReadElementContent()) 
                return base.ReadElementContentAsString();
            string value; 
            switch (GetNodeType())
            {
                case XmlBinaryNodeType.Chars8TextWithEndElement:
                    SkipNodeType(); 
                    value = BufferReader.ReadUTF8String(ReadUInt8());
                    ReadTextWithEndElement(); 
                    break; 
                case XmlBinaryNodeType.DictionaryTextWithEndElement:
                    SkipNodeType(); 
                    value = BufferReader.GetDictionaryString(ReadDictionaryKey()).Value;
                    ReadTextWithEndElement();
                    break;
                default: 
                    value = base.ReadElementContentAsString();
                    break; 
            } 
            if (value.Length > Quotas.MaxStringContentLength)
                XmlExceptionHelper.ThrowMaxStringContentLengthExceeded(this, Quotas.MaxStringContentLength); 
            return value;
        }

        public override bool ReadElementContentAsBoolean() 
        {
            if (this.Node.NodeType != XmlNodeType.Element) 
                MoveToStartElement(); 
            if (!CanOptimizeReadElementContent())
                return base.ReadElementContentAsBoolean(); 
            bool value;
            switch (GetNodeType())
            {
                case XmlBinaryNodeType.TrueTextWithEndElement: 
                    SkipNodeType();
                    value = true; 
                    ReadTextWithEndElement(); 
                    break;
                case XmlBinaryNodeType.FalseTextWithEndElement: 
                    SkipNodeType();
                    value = false;
                    ReadTextWithEndElement();
                    break; 
                case XmlBinaryNodeType.BoolTextWithEndElement:
                    SkipNodeType(); 
                    value = (BufferReader.ReadUInt8() != 0); 
                    ReadTextWithEndElement();
                    break; 
                default:
                    value = base.ReadElementContentAsBoolean();
                    break;
            } 
            return value;
        } 
 
        public override int ReadElementContentAsInt()
        { 
            if (this.Node.NodeType != XmlNodeType.Element)
                MoveToStartElement();
            if (!CanOptimizeReadElementContent())
                return base.ReadElementContentAsInt(); 
            int value;
            switch (GetNodeType()) 
            { 
                case XmlBinaryNodeType.ZeroTextWithEndElement:
                    SkipNodeType(); 
                    value = 0;
                    ReadTextWithEndElement();
                    break;
                case XmlBinaryNodeType.OneTextWithEndElement: 
                    SkipNodeType();
                    value = 1; 
                    ReadTextWithEndElement(); 
                    break;
                case XmlBinaryNodeType.Int8TextWithEndElement: 
                    SkipNodeType();
                    value = BufferReader.ReadInt8();
                    ReadTextWithEndElement();
                    break; 
                case XmlBinaryNodeType.Int16TextWithEndElement:
                    SkipNodeType(); 
                    value = BufferReader.ReadInt16(); 
                    ReadTextWithEndElement();
                    break; 
                case XmlBinaryNodeType.Int32TextWithEndElement:
                    SkipNodeType();
                    value = BufferReader.ReadInt32();
                    ReadTextWithEndElement(); 
                    break;
                default: 
                    value = base.ReadElementContentAsInt(); 
                    break;
            } 
            return value;
        }

        bool CanOptimizeReadElementContent() 
        {
            return (arrayState == ArrayState.None && !Signing); 
        } 

        public override float ReadElementContentAsFloat() 
        {
            if (this.Node.NodeType != XmlNodeType.Element)
                MoveToStartElement();
            if (CanOptimizeReadElementContent() && GetNodeType() == XmlBinaryNodeType.FloatTextWithEndElement) 
            {
                SkipNodeType(); 
                float value = BufferReader.ReadSingle(); 
                ReadTextWithEndElement();
                return value; 
            }
            return base.ReadElementContentAsFloat();
        }
 
        public override double ReadElementContentAsDouble()
        { 
            if (this.Node.NodeType != XmlNodeType.Element) 
                MoveToStartElement();
            if (CanOptimizeReadElementContent() && GetNodeType() == XmlBinaryNodeType.DoubleTextWithEndElement) 
            {
                SkipNodeType();
                double value = BufferReader.ReadDouble();
                ReadTextWithEndElement(); 
                return value;
            } 
            return base.ReadElementContentAsDouble(); 
        }
 
        public override decimal ReadElementContentAsDecimal()
        {
            if (this.Node.NodeType != XmlNodeType.Element)
                MoveToStartElement(); 
            if (CanOptimizeReadElementContent() && GetNodeType() == XmlBinaryNodeType.DecimalTextWithEndElement)
            { 
                SkipNodeType(); 
                decimal value = BufferReader.ReadDecimal();
                ReadTextWithEndElement(); 
                return value;
            }
            return base.ReadElementContentAsDecimal();
        } 

        public override DateTime ReadElementContentAsDateTime() 
        { 
            if (this.Node.NodeType != XmlNodeType.Element)
                MoveToStartElement(); 
            if (CanOptimizeReadElementContent() && GetNodeType() == XmlBinaryNodeType.DateTimeTextWithEndElement)
            {
                SkipNodeType();
                DateTime value = BufferReader.ReadDateTime(); 
                ReadTextWithEndElement();
                return value; 
            } 
            return base.ReadElementContentAsDateTime();
        } 

        public override TimeSpan ReadElementContentAsTimeSpan()
        {
            if (this.Node.NodeType != XmlNodeType.Element) 
                MoveToStartElement();
            if (CanOptimizeReadElementContent() && GetNodeType() == XmlBinaryNodeType.TimeSpanTextWithEndElement) 
            { 
                SkipNodeType();
                TimeSpan value = BufferReader.ReadTimeSpan(); 
                ReadTextWithEndElement();
                return value;
            }
            return base.ReadElementContentAsTimeSpan(); 
        }
 
        public override Guid ReadElementContentAsGuid() 
        {
            if (this.Node.NodeType != XmlNodeType.Element) 
                MoveToStartElement();
            if (CanOptimizeReadElementContent() && GetNodeType() == XmlBinaryNodeType.GuidTextWithEndElement)
            {
                SkipNodeType(); 
                Guid value = BufferReader.ReadGuid();
                ReadTextWithEndElement(); 
                return value; 
            }
            return base.ReadElementContentAsGuid(); 
        }

        public override UniqueId ReadElementContentAsUniqueId()
        { 
            if (this.Node.NodeType != XmlNodeType.Element)
                MoveToStartElement(); 
            if (CanOptimizeReadElementContent() && GetNodeType() == XmlBinaryNodeType.UniqueIdTextWithEndElement) 
            {
                SkipNodeType(); 
                UniqueId value = BufferReader.ReadUniqueId();
                ReadTextWithEndElement();
                return value;
            } 
            return base.ReadElementContentAsUniqueId();
        } 
 
        public override bool TryGetBase64ContentLength(out int length)
        { 
            length = 0;
            if (!buffered)
                return false;
            if (arrayState != ArrayState.None) 
                return false;
            int totalLength; 
            if (!this.Node.Value.TryGetByteArrayLength(out totalLength)) 
                return false;
            int offset = BufferReader.Offset; 
            try
            {
                bool done = false;
                while (!done && !BufferReader.EndOfFile) 
                {
                    XmlBinaryNodeType nodeType = GetNodeType(); 
                    SkipNodeType(); 
                    int actual;
                    switch (nodeType) 
                    {
                        case XmlBinaryNodeType.Bytes8TextWithEndElement:
                            actual = BufferReader.ReadUInt8();
                            done = true; 
                            break;
                        case XmlBinaryNodeType.Bytes16TextWithEndElement: 
                            actual = BufferReader.ReadUInt16(); 
                            done = true;
                            break; 
                        case XmlBinaryNodeType.Bytes32TextWithEndElement:
                            actual = BufferReader.ReadUInt31();
                            done = true;
                            break; 
                        case XmlBinaryNodeType.EndElement:
                            actual = 0; 
                            done = true; 
                            break;
                        case XmlBinaryNodeType.Bytes8Text: 
                            actual = BufferReader.ReadUInt8();
                            break;
                        case XmlBinaryNodeType.Bytes16Text:
                            actual = BufferReader.ReadUInt16(); 
                            break;
                        case XmlBinaryNodeType.Bytes32Text: 
                            actual = BufferReader.ReadUInt31(); 
                            break;
                        default: 
                            // Non-optimal or unexpected node - fallback
                            return false;
                    }
                    BufferReader.Advance(actual); 
                    if (totalLength > int.MaxValue - actual)
                        return false; 
                    totalLength += actual; 
                }
                length = totalLength; 
                return true;
            }
            finally
            { 
                BufferReader.Offset = offset;
            } 
        } 

        void ReadTextWithEndElement() 
        {
            ExitScope();
            ReadNode();
        } 

        XmlAtomicTextNode MoveToAtomicTextWithEndElement() 
        { 
            isTextWithEndElement = true;
            return MoveToAtomicText(); 
        }

        public override bool Read()
        { 
            if (this.Node.ReadState == ReadState.Closed)
                return false; 
            SignNode(); 
            if (isTextWithEndElement)
            { 
                isTextWithEndElement = false;
                MoveToEndElement();
                return true;
            } 
            if (arrayState == ArrayState.Content)
            { 
                if (arrayCount != 0) 
                {
                    MoveToArrayElement(); 
                    return true;
                }
                arrayState = ArrayState.None;
            } 
            if (this.Node.ExitScope)
            { 
                ExitScope(); 
            }
            return ReadNode(); 
        }

        bool ReadNode()
        { 
 		    if (!buffered)
                BufferReader.SetWindow(ElementNode.BufferOffset, this.maxBytesPerRead); 
 
            if (BufferReader.EndOfFile)
            { 
                MoveToEndOfFile();
                return false;
            }
 

            XmlBinaryNodeType nodeType; 
            if (arrayState == ArrayState.None) 
            {
                nodeType = GetNodeType(); 
                SkipNodeType();
            }
            else
            { 
                Fx.Assert(arrayState == ArrayState.Element, "");
                nodeType = arrayNodeType; 
                arrayCount--; 
                arrayState = ArrayState.Content;
            } 

            XmlElementNode elementNode;
            PrefixHandleType prefix;
            switch (nodeType) 
            {
                case XmlBinaryNodeType.ShortElement: 
                    elementNode = EnterScope(); 
                    elementNode.Prefix.SetValue(PrefixHandleType.Empty);
                    ReadName(elementNode.LocalName); 
                    ReadAttributes();
                    elementNode.Namespace = LookupNamespace(PrefixHandleType.Empty);
                    elementNode.BufferOffset = BufferReader.Offset;
                    return true; 
                case XmlBinaryNodeType.Element:
                    elementNode = EnterScope(); 
                    ReadName(elementNode.Prefix); 
                    ReadName(elementNode.LocalName);
                    ReadAttributes(); 
                    elementNode.Namespace = LookupNamespace(elementNode.Prefix);
                    elementNode.BufferOffset = BufferReader.Offset;
                    return true;
                case XmlBinaryNodeType.ShortDictionaryElement: 
                    elementNode = EnterScope();
                    elementNode.Prefix.SetValue(PrefixHandleType.Empty); 
                    ReadDictionaryName(elementNode.LocalName); 
                    ReadAttributes();
                    elementNode.Namespace = LookupNamespace(PrefixHandleType.Empty); 
                    elementNode.BufferOffset = BufferReader.Offset;
                    return true;
                case XmlBinaryNodeType.DictionaryElement:
                    elementNode = EnterScope(); 
                    ReadName(elementNode.Prefix);
                    ReadDictionaryName(elementNode.LocalName); 
                    ReadAttributes(); 
                    elementNode.Namespace = LookupNamespace(elementNode.Prefix);
                    elementNode.BufferOffset = BufferReader.Offset; 
                    return true;
                case XmlBinaryNodeType.PrefixElementA:
                case XmlBinaryNodeType.PrefixElementB:
                case XmlBinaryNodeType.PrefixElementC: 
                case XmlBinaryNodeType.PrefixElementD:
                case XmlBinaryNodeType.PrefixElementE: 
                case XmlBinaryNodeType.PrefixElementF: 
                case XmlBinaryNodeType.PrefixElementG:
                case XmlBinaryNodeType.PrefixElementH: 
                case XmlBinaryNodeType.PrefixElementI:
                case XmlBinaryNodeType.PrefixElementJ:
                case XmlBinaryNodeType.PrefixElementK:
                case XmlBinaryNodeType.PrefixElementL: 
                case XmlBinaryNodeType.PrefixElementM:
                case XmlBinaryNodeType.PrefixElementN: 
                case XmlBinaryNodeType.PrefixElementO: 
                case XmlBinaryNodeType.PrefixElementP:
                case XmlBinaryNodeType.PrefixElementQ: 
                case XmlBinaryNodeType.PrefixElementR:
                case XmlBinaryNodeType.PrefixElementS:
                case XmlBinaryNodeType.PrefixElementT:
                case XmlBinaryNodeType.PrefixElementU: 
                case XmlBinaryNodeType.PrefixElementV:
                case XmlBinaryNodeType.PrefixElementW: 
                case XmlBinaryNodeType.PrefixElementX: 
                case XmlBinaryNodeType.PrefixElementY:
                case XmlBinaryNodeType.PrefixElementZ: 
                    elementNode = EnterScope();
                    prefix = PrefixHandle.GetAlphaPrefix((int)nodeType - (int)XmlBinaryNodeType.PrefixElementA);
                    elementNode.Prefix.SetValue(prefix);
                    ReadName(elementNode.LocalName); 
                    ReadAttributes();
                    elementNode.Namespace = LookupNamespace(prefix); 
                    elementNode.BufferOffset = BufferReader.Offset; 
                    return true;
                case XmlBinaryNodeType.PrefixDictionaryElementA: 
                case XmlBinaryNodeType.PrefixDictionaryElementB:
                case XmlBinaryNodeType.PrefixDictionaryElementC:
                case XmlBinaryNodeType.PrefixDictionaryElementD:
                case XmlBinaryNodeType.PrefixDictionaryElementE: 
                case XmlBinaryNodeType.PrefixDictionaryElementF:
                case XmlBinaryNodeType.PrefixDictionaryElementG: 
                case XmlBinaryNodeType.PrefixDictionaryElementH: 
                case XmlBinaryNodeType.PrefixDictionaryElementI:
                case XmlBinaryNodeType.PrefixDictionaryElementJ: 
                case XmlBinaryNodeType.PrefixDictionaryElementK:
                case XmlBinaryNodeType.PrefixDictionaryElementL:
                case XmlBinaryNodeType.PrefixDictionaryElementM:
                case XmlBinaryNodeType.PrefixDictionaryElementN: 
                case XmlBinaryNodeType.PrefixDictionaryElementO:
                case XmlBinaryNodeType.PrefixDictionaryElementP: 
                case XmlBinaryNodeType.PrefixDictionaryElementQ: 
                case XmlBinaryNodeType.PrefixDictionaryElementR:
                case XmlBinaryNodeType.PrefixDictionaryElementS: 
                case XmlBinaryNodeType.PrefixDictionaryElementT:
                case XmlBinaryNodeType.PrefixDictionaryElementU:
                case XmlBinaryNodeType.PrefixDictionaryElementV:
                case XmlBinaryNodeType.PrefixDictionaryElementW: 
                case XmlBinaryNodeType.PrefixDictionaryElementX:
                case XmlBinaryNodeType.PrefixDictionaryElementY: 
                case XmlBinaryNodeType.PrefixDictionaryElementZ: 
                    elementNode = EnterScope();
                    prefix = PrefixHandle.GetAlphaPrefix((int)nodeType - (int)XmlBinaryNodeType.PrefixDictionaryElementA); 
                    elementNode.Prefix.SetValue(prefix);
                    ReadDictionaryName(elementNode.LocalName);
                    ReadAttributes();
                    elementNode.Namespace = LookupNamespace(prefix); 
                    elementNode.BufferOffset = BufferReader.Offset;
                    return true; 
                case XmlBinaryNodeType.EndElement: 
                    MoveToEndElement();
                    return true; 
                case XmlBinaryNodeType.Comment:
                    ReadName(MoveToComment().Value);
                    return true;
                case XmlBinaryNodeType.EmptyTextWithEndElement: 
                    MoveToAtomicTextWithEndElement().Value.SetValue(ValueHandleType.Empty);
                    if (this.OutsideRootElement) 
                        VerifyWhitespace(); 
                    return true;
                case XmlBinaryNodeType.ZeroTextWithEndElement: 
                    MoveToAtomicTextWithEndElement().Value.SetValue(ValueHandleType.Zero);
                    if (this.OutsideRootElement)
                        VerifyWhitespace();
                    return true; 
                case XmlBinaryNodeType.OneTextWithEndElement:
                    MoveToAtomicTextWithEndElement().Value.SetValue(ValueHandleType.One); 
                    if (this.OutsideRootElement) 
                        VerifyWhitespace();
                    return true; 
                case XmlBinaryNodeType.TrueTextWithEndElement:
                    MoveToAtomicTextWithEndElement().Value.SetValue(ValueHandleType.True);
                    if (this.OutsideRootElement)
                        VerifyWhitespace(); 
                    return true;
                case XmlBinaryNodeType.FalseTextWithEndElement: 
                    MoveToAtomicTextWithEndElement().Value.SetValue(ValueHandleType.False); 
                    if (this.OutsideRootElement)
                        VerifyWhitespace(); 
                    return true;
                case XmlBinaryNodeType.BoolTextWithEndElement:
                    MoveToAtomicTextWithEndElement().Value.SetValue(ReadUInt8() != 0 ? ValueHandleType.True : ValueHandleType.False);
                    if (this.OutsideRootElement) 
                        VerifyWhitespace();
                    return true; 
                case XmlBinaryNodeType.Chars8TextWithEndElement: 
                    if (buffered)
                        ReadText(MoveToAtomicTextWithEndElement(), ValueHandleType.UTF8, ReadUInt8()); 
                    else
                        ReadPartialUTF8Text(true, ReadUInt8());
                    return true;
                case XmlBinaryNodeType.Chars8Text: 
                    if (buffered)
                        ReadText(MoveToComplexText(), ValueHandleType.UTF8, ReadUInt8()); 
                    else 
                        ReadPartialUTF8Text(false, ReadUInt8());
                    return true; 
                case XmlBinaryNodeType.Chars16TextWithEndElement:
                    if (buffered)
                        ReadText(MoveToAtomicTextWithEndElement(), ValueHandleType.UTF8, ReadUInt16());
                    else 
                        ReadPartialUTF8Text(true, ReadUInt16());
                    return true; 
                case XmlBinaryNodeType.Chars16Text: 
                    if (buffered)
                        ReadText(MoveToComplexText(), ValueHandleType.UTF8, ReadUInt16()); 
                    else
                        ReadPartialUTF8Text(false, ReadUInt16());
                    return true;
                case XmlBinaryNodeType.Chars32TextWithEndElement: 
                    if (buffered)
                        ReadText(MoveToAtomicTextWithEndElement(), ValueHandleType.UTF8, ReadUInt31()); 
                    else 
                        ReadPartialUTF8Text(true, ReadUInt31());
                    return true; 
                case XmlBinaryNodeType.Chars32Text:
                    if (buffered)
                        ReadText(MoveToComplexText(), ValueHandleType.UTF8, ReadUInt31());
                    else 
                        ReadPartialUTF8Text(false, ReadUInt31());
                    return true; 
                case XmlBinaryNodeType.UnicodeChars8TextWithEndElement: 
                    ReadUnicodeText(true, ReadUInt8());
                    return true; 
                case XmlBinaryNodeType.UnicodeChars8Text:
                    ReadUnicodeText(false, ReadUInt8());
                    return true;
                case XmlBinaryNodeType.UnicodeChars16TextWithEndElement: 
                    ReadUnicodeText(true, ReadUInt16());
                    return true; 
                case XmlBinaryNodeType.UnicodeChars16Text: 
                    ReadUnicodeText(false, ReadUInt16());
                    return true; 
                case XmlBinaryNodeType.UnicodeChars32TextWithEndElement:
                    ReadUnicodeText(true, ReadUInt31());
                    return true;
                case XmlBinaryNodeType.UnicodeChars32Text: 
                    ReadUnicodeText(false, ReadUInt31());
                    return true; 
                case XmlBinaryNodeType.Bytes8TextWithEndElement: 
                    if (buffered)
                        ReadBinaryText(MoveToAtomicTextWithEndElement(), ReadUInt8()); 
                    else
                        ReadPartialBinaryText(true, ReadUInt8());
                    return true;
                case XmlBinaryNodeType.Bytes8Text: 
                    if (buffered)
                        ReadBinaryText(MoveToComplexText(), ReadUInt8()); 
                    else 
                        ReadPartialBinaryText(false, ReadUInt8());
                    return true; 
                case XmlBinaryNodeType.Bytes16TextWithEndElement:
                    if (buffered)
                        ReadBinaryText(MoveToAtomicTextWithEndElement(), ReadUInt16());
                    else 
                        ReadPartialBinaryText(true, ReadUInt16());
                    return true; 
                case XmlBinaryNodeType.Bytes16Text: 
                    if (buffered)
                        ReadBinaryText(MoveToComplexText(), ReadUInt16()); 
                    else
                        ReadPartialBinaryText(false, ReadUInt16());
                    return true;
                case XmlBinaryNodeType.Bytes32TextWithEndElement: 
                    if (buffered)
                        ReadBinaryText(MoveToAtomicTextWithEndElement(), ReadUInt31()); 
                    else 
                        ReadPartialBinaryText(true, ReadUInt31());
                    return true; 
                case XmlBinaryNodeType.Bytes32Text:
                    if (buffered)
                        ReadBinaryText(MoveToComplexText(), ReadUInt31());
                    else 
                        ReadPartialBinaryText(false, ReadUInt31());
                    return true; 
                case XmlBinaryNodeType.DictionaryTextWithEndElement: 
                    MoveToAtomicTextWithEndElement().Value.SetDictionaryValue(ReadDictionaryKey());
                    return true; 
                case XmlBinaryNodeType.UniqueIdTextWithEndElement:
                    ReadText(MoveToAtomicTextWithEndElement(), ValueHandleType.UniqueId, ValueHandleLength.UniqueId);
                    return true;
                case XmlBinaryNodeType.GuidTextWithEndElement: 
                    ReadText(MoveToAtomicTextWithEndElement(), ValueHandleType.Guid, ValueHandleLength.Guid);
                    return true; 
                case XmlBinaryNodeType.DecimalTextWithEndElement: 
                    ReadText(MoveToAtomicTextWithEndElement(), ValueHandleType.Decimal, ValueHandleLength.Decimal);
                    return true; 
                case XmlBinaryNodeType.Int8TextWithEndElement:
                    ReadText(MoveToAtomicTextWithEndElement(), ValueHandleType.Int8, ValueHandleLength.Int8);
                    return true;
                case XmlBinaryNodeType.Int16TextWithEndElement: 
                    ReadText(MoveToAtomicTextWithEndElement(), ValueHandleType.Int16, ValueHandleLength.Int16);
                    return true; 
                case XmlBinaryNodeType.Int32TextWithEndElement: 
                    ReadText(MoveToAtomicTextWithEndElement(), ValueHandleType.Int32, ValueHandleLength.Int32);
                    return true; 
                case XmlBinaryNodeType.Int64TextWithEndElement:
                    ReadText(MoveToAtomicTextWithEndElement(), ValueHandleType.Int64, ValueHandleLength.Int64);
                    return true;
                case XmlBinaryNodeType.UInt64TextWithEndElement: 
                    ReadText(MoveToAtomicTextWithEndElement(), ValueHandleType.UInt64, ValueHandleLength.UInt64);
                    return true; 
                case XmlBinaryNodeType.FloatTextWithEndElement: 
                    ReadText(MoveToAtomicTextWithEndElement(), ValueHandleType.Single, ValueHandleLength.Single);
                    return true; 
                case XmlBinaryNodeType.DoubleTextWithEndElement:
                    ReadText(MoveToAtomicTextWithEndElement(), ValueHandleType.Double, ValueHandleLength.Double);
                    return true;
                case XmlBinaryNodeType.TimeSpanTextWithEndElement: 
                    ReadText(MoveToAtomicTextWithEndElement(), ValueHandleType.TimeSpan, ValueHandleLength.TimeSpan);
                    return true; 
                case XmlBinaryNodeType.DateTimeTextWithEndElement: 
                    ReadText(MoveToAtomicTextWithEndElement(), ValueHandleType.DateTime, ValueHandleLength.DateTime);
                    return true; 
                case XmlBinaryNodeType.QNameDictionaryTextWithEndElement:
                    BufferReader.ReadQName(MoveToAtomicTextWithEndElement().Value);
                    return true;
                case XmlBinaryNodeType.Array: 
                    ReadArray();
                    return true; 
                default: 
                    BufferReader.ReadValue(nodeType, MoveToComplexText().Value);
                    return true; 
            }
        }

        void VerifyWhitespace() 
        {
            if (!this.Node.Value.IsWhitespace()) 
                XmlExceptionHelper.ThrowInvalidBinaryFormat(this); 
        }
 
        void ReadAttributes()
        {
            XmlBinaryNodeType nodeType = GetNodeType();
            if (nodeType < XmlBinaryNodeType.MinAttribute || nodeType > XmlBinaryNodeType.MaxAttribute) 
                return;
            ReadAttributes2(); 
        } 

        void ReadAttributes2() 
        {
            int startOffset = 0;
            if (buffered)
                startOffset = BufferReader.Offset; 

            while (true) 
            { 
                XmlAttributeNode attributeNode;
                Namespace nameSpace; 
                PrefixHandleType prefix;
                XmlBinaryNodeType nodeType = GetNodeType();
                switch (nodeType)
                { 
                    case XmlBinaryNodeType.ShortAttribute:
                        SkipNodeType(); 
                        attributeNode = AddAttribute(); 
                        attributeNode.Prefix.SetValue(PrefixHandleType.Empty);
                        ReadName(attributeNode.LocalName); 
                        ReadAttributeText(attributeNode.AttributeText);
                        break;
                    case XmlBinaryNodeType.Attribute:
                        SkipNodeType(); 
                        attributeNode = AddAttribute();
                        ReadName(attributeNode.Prefix); 
                        ReadName(attributeNode.LocalName); 
                        ReadAttributeText(attributeNode.AttributeText);
                        FixXmlAttribute(attributeNode); 
                        break;
                    case XmlBinaryNodeType.ShortDictionaryAttribute:
                        SkipNodeType();
                        attributeNode = AddAttribute(); 
                        attributeNode.Prefix.SetValue(PrefixHandleType.Empty);
                        ReadDictionaryName(attributeNode.LocalName); 
                        ReadAttributeText(attributeNode.AttributeText); 
                        break;
                    case XmlBinaryNodeType.DictionaryAttribute: 
                        SkipNodeType();
                        attributeNode = AddAttribute();
                        ReadName(attributeNode.Prefix);
                        ReadDictionaryName(attributeNode.LocalName); 
                        ReadAttributeText(attributeNode.AttributeText);
                        break; 
                    case XmlBinaryNodeType.XmlnsAttribute: 
                        SkipNodeType();
                        nameSpace = AddNamespace(); 
                        ReadName(nameSpace.Prefix);
                        ReadName(nameSpace.Uri);
                        attributeNode = AddXmlnsAttribute(nameSpace);
                        break; 
                    case XmlBinaryNodeType.ShortXmlnsAttribute:
                        SkipNodeType(); 
                        nameSpace = AddNamespace(); 
                        nameSpace.Prefix.SetValue(PrefixHandleType.Empty);
                        ReadName(nameSpace.Uri); 
                        attributeNode = AddXmlnsAttribute(nameSpace);
                        break;
                    case XmlBinaryNodeType.ShortDictionaryXmlnsAttribute:
                        SkipNodeType(); 
                        nameSpace = AddNamespace();
                        nameSpace.Prefix.SetValue(PrefixHandleType.Empty); 
                        ReadDictionaryName(nameSpace.Uri); 
                        attributeNode = AddXmlnsAttribute(nameSpace);
                        break; 
                    case XmlBinaryNodeType.DictionaryXmlnsAttribute:
                        SkipNodeType();
                        nameSpace = AddNamespace();
                        ReadName(nameSpace.Prefix); 
                        ReadDictionaryName(nameSpace.Uri);
                        attributeNode = AddXmlnsAttribute(nameSpace); 
                        break; 
                    case XmlBinaryNodeType.PrefixDictionaryAttributeA:
                    case XmlBinaryNodeType.PrefixDictionaryAttributeB: 
                    case XmlBinaryNodeType.PrefixDictionaryAttributeC:
                    case XmlBinaryNodeType.PrefixDictionaryAttributeD:
                    case XmlBinaryNodeType.PrefixDictionaryAttributeE:
                    case XmlBinaryNodeType.PrefixDictionaryAttributeF: 
                    case XmlBinaryNodeType.PrefixDictionaryAttributeG:
                    case XmlBinaryNodeType.PrefixDictionaryAttributeH: 
                    case XmlBinaryNodeType.PrefixDictionaryAttributeI: 
                    case XmlBinaryNodeType.PrefixDictionaryAttributeJ:
                    case XmlBinaryNodeType.PrefixDictionaryAttributeK: 
                    case XmlBinaryNodeType.PrefixDictionaryAttributeL:
                    case XmlBinaryNodeType.PrefixDictionaryAttributeM:
                    case XmlBinaryNodeType.PrefixDictionaryAttributeN:
                    case XmlBinaryNodeType.PrefixDictionaryAttributeO: 
                    case XmlBinaryNodeType.PrefixDictionaryAttributeP:
                    case XmlBinaryNodeType.PrefixDictionaryAttributeQ: 
                    case XmlBinaryNodeType.PrefixDictionaryAttributeR: 
                    case XmlBinaryNodeType.PrefixDictionaryAttributeS:
                    case XmlBinaryNodeType.PrefixDictionaryAttributeT: 
                    case XmlBinaryNodeType.PrefixDictionaryAttributeU:
                    case XmlBinaryNodeType.PrefixDictionaryAttributeV:
                    case XmlBinaryNodeType.PrefixDictionaryAttributeW:
                    case XmlBinaryNodeType.PrefixDictionaryAttributeX: 
                    case XmlBinaryNodeType.PrefixDictionaryAttributeY:
                    case XmlBinaryNodeType.PrefixDictionaryAttributeZ: 
                        SkipNodeType(); 
                        attributeNode = AddAttribute();
                        prefix = PrefixHandle.GetAlphaPrefix((int)nodeType - (int)XmlBinaryNodeType.PrefixDictionaryAttributeA); 
                        attributeNode.Prefix.SetValue(prefix);
                        ReadDictionaryName(attributeNode.LocalName);
                        ReadAttributeText(attributeNode.AttributeText);
                        break; 
                    case XmlBinaryNodeType.PrefixAttributeA:
                    case XmlBinaryNodeType.PrefixAttributeB: 
                    case XmlBinaryNodeType.PrefixAttributeC: 
                    case XmlBinaryNodeType.PrefixAttributeD:
                    case XmlBinaryNodeType.PrefixAttributeE: 
                    case XmlBinaryNodeType.PrefixAttributeF:
                    case XmlBinaryNodeType.PrefixAttributeG:
                    case XmlBinaryNodeType.PrefixAttributeH:
                    case XmlBinaryNodeType.PrefixAttributeI: 
                    case XmlBinaryNodeType.PrefixAttributeJ:
                    case XmlBinaryNodeType.PrefixAttributeK: 
                    case XmlBinaryNodeType.PrefixAttributeL: 
                    case XmlBinaryNodeType.PrefixAttributeM:
                    case XmlBinaryNodeType.PrefixAttributeN: 
                    case XmlBinaryNodeType.PrefixAttributeO:
                    case XmlBinaryNodeType.PrefixAttributeP:
                    case XmlBinaryNodeType.PrefixAttributeQ:
                    case XmlBinaryNodeType.PrefixAttributeR: 
                    case XmlBinaryNodeType.PrefixAttributeS:
                    case XmlBinaryNodeType.PrefixAttributeT: 
                    case XmlBinaryNodeType.PrefixAttributeU: 
                    case XmlBinaryNodeType.PrefixAttributeV:
                    case XmlBinaryNodeType.PrefixAttributeW: 
                    case XmlBinaryNodeType.PrefixAttributeX:
                    case XmlBinaryNodeType.PrefixAttributeY:
                    case XmlBinaryNodeType.PrefixAttributeZ:
                        SkipNodeType(); 
                        attributeNode = AddAttribute();
                        prefix = PrefixHandle.GetAlphaPrefix((int)nodeType - (int)XmlBinaryNodeType.PrefixAttributeA); 
                        attributeNode.Prefix.SetValue(prefix); 
                        ReadName(attributeNode.LocalName);
                        ReadAttributeText(attributeNode.AttributeText); 
                        break;
                    default:
                        if (buffered && (BufferReader.Offset - startOffset) > this.maxBytesPerRead)
                            XmlExceptionHelper.ThrowMaxBytesPerReadExceeded(this, this.maxBytesPerRead); 
                        ProcessAttributes();
                        return; 
                } 
            }
        } 

        void ReadText(XmlTextNode textNode, ValueHandleType type, int length)
        {
            int offset = BufferReader.ReadBytes(length); 
            textNode.Value.SetValue(type, offset, length);
            if (this.OutsideRootElement) 
                VerifyWhitespace(); 
        }
 
        void ReadBinaryText(XmlTextNode textNode, int length)
        {
            ReadText(textNode, ValueHandleType.Base64, length);
        } 

        void ReadPartialUTF8Text(bool withEndElement, int length) 
        { 
            // The maxBytesPerRead includes the quota for the XmlBinaryNodeType.TextNode, so we need
            // to account for that. 
            const int maxTextNodeLength = 5;
            int maxLength = Math.Max(this.maxBytesPerRead - maxTextNodeLength, 0);
            if (length <= maxLength)
            { 
                if (withEndElement)
                    ReadText(MoveToAtomicTextWithEndElement(), ValueHandleType.UTF8, length); 
                else 
                    ReadText(MoveToComplexText(), ValueHandleType.UTF8, length);
            } 
            else
            {
                // We also need to make sure we have enough room to insert a new XmlBinaryNodeType.TextNode
                // for the split data. 
                int actual = Math.Max(maxLength - maxTextNodeLength, 0);
                int offset = BufferReader.ReadBytes(actual); 
 
                // We need to make sure we don't split a utf8  character, so scan backwards for a
                // character boundary.  We'll actually always push off at least one character since 
                // although we find the character boundary, we don't bother to figure out if we have
                // all the bytes that comprise the character.
                int i;
                for (i = offset + actual - 1; i >= offset; i--) 
                {
                    byte b = BufferReader.GetByte(i); 
                    // The first byte of UTF8 character sequence has either the high bit off, or the 
                    // two high bits set.
                    if ((b & 0x80) == 0 || (b & 0xC0) == 0xC0) 
                        break;
                }

                // Move any split characters so we can insert the node 
                int byteCount = (offset + actual - i);
 
                // Include the split characters in the count 
                BufferReader.Offset = BufferReader.Offset - byteCount;
                actual -= byteCount; 
                MoveToComplexText().Value.SetValue(ValueHandleType.UTF8, offset, actual);
                if (this.OutsideRootElement)
                    VerifyWhitespace();
 
                XmlBinaryNodeType nodeType = (withEndElement ? XmlBinaryNodeType.Chars32TextWithEndElement : XmlBinaryNodeType.Chars32Text);
                InsertNode(nodeType, length - actual); 
            } 
        }
 
        void ReadUnicodeText(bool withEndElement, int length)
        {
            if ((length & 1) != 0)
                XmlExceptionHelper.ThrowInvalidBinaryFormat(this); 
            if (buffered)
            { 
                if (withEndElement) 
                {
                    ReadText(MoveToAtomicTextWithEndElement(), ValueHandleType.Unicode, length); 
                }
                else
                {
                    ReadText(MoveToComplexText(), ValueHandleType.Unicode, length); 
                }
            } 
            else 
            {
                ReadPartialUnicodeText(withEndElement, length); 
            }
        }

        void ReadPartialUnicodeText(bool withEndElement, int length) 
        {
            // The maxBytesPerRead includes the quota for the XmlBinaryNodeType.TextNode, so we need 
            // to account for that. 
            const int maxTextNodeLength = 5;
            int maxLength = Math.Max(this.maxBytesPerRead - maxTextNodeLength, 0); 
            if (length <= maxLength)
            {
                if (withEndElement)
                    ReadText(MoveToAtomicTextWithEndElement(), ValueHandleType.Unicode, length); 
                else
                    ReadText(MoveToComplexText(), ValueHandleType.Unicode, length); 
            } 
            else
            { 
                // We also need to make sure we have enough room to insert a new XmlBinaryNodeType.TextNode
                // for the split data.
                int actual = Math.Max(maxLength - maxTextNodeLength, 0);
 
                // Make sure we break on a char boundary
                if ((actual & 1) != 0) 
                    actual--; 

                int offset = BufferReader.ReadBytes(actual); 

                // We need to make sure we don't split a unicode surrogate character
                int byteCount = 0;
                char ch = (char) BufferReader.GetInt16(offset + actual - sizeof(char)); 
                // If the last char is a high surrogate char, then move back
                if (ch >= 0xD800 && ch < 0xDC00) 
                    byteCount = sizeof(char); 

                // Include the split characters in the count 
                BufferReader.Offset = BufferReader.Offset - byteCount;
                actual -= byteCount;
                MoveToComplexText().Value.SetValue(ValueHandleType.Unicode, offset, actual);
                if (this.OutsideRootElement) 
                    VerifyWhitespace();
 
                XmlBinaryNodeType nodeType = (withEndElement ? XmlBinaryNodeType.UnicodeChars32TextWithEndElement : XmlBinaryNodeType.UnicodeChars32Text); 
                InsertNode(nodeType, length - actual);
            } 
        }

        void ReadPartialBinaryText(bool withEndElement, int length)
        { 
            const int nodeLength = 5;
            int maxBytesPerRead = Math.Max(this.maxBytesPerRead - nodeLength, 0); 
            if (length <= maxBytesPerRead) 
            {
                if (withEndElement) 
                    ReadText(MoveToAtomicTextWithEndElement(), ValueHandleType.Base64, length);
                else
                    ReadText(MoveToComplexText(), ValueHandleType.Base64, length);
            } 
            else
            { 
                int actual = maxBytesPerRead; 
                if (actual > 3)
                    actual -= (actual % 3); 
                ReadText(MoveToComplexText(), ValueHandleType.Base64, actual);
                XmlBinaryNodeType nodeType = (withEndElement ? XmlBinaryNodeType.Bytes32TextWithEndElement : XmlBinaryNodeType.Bytes32Text);
                InsertNode(nodeType, length - actual);
            } 
        }
 
        void InsertNode(XmlBinaryNodeType nodeType, int length) 
        {
            byte[] buffer = new byte[5]; 
            buffer[0] = (byte)nodeType;
            buffer[1] = (byte)length;
            length >>= 8;
            buffer[2] = (byte)length; 
            length >>= 8;
            buffer[3] = (byte)length; 
            length >>= 8; 
            buffer[4] = (byte)length;
            BufferReader.InsertBytes(buffer, 0, buffer.Length); 
        }

        void ReadAttributeText(XmlAttributeTextNode textNode)
        { 
            XmlBinaryNodeType nodeType = GetNodeType();
            SkipNodeType(); 
            BufferReader.ReadValue(nodeType, textNode.Value); 
        }
 
        void ReadName(ValueHandle value)
        {
            int length = ReadMultiByteUInt31();
            int offset = BufferReader.ReadBytes(length); 
            value.SetValue(ValueHandleType.UTF8, offset, length);
        } 
 
        void ReadName(StringHandle handle)
        { 
            int length = ReadMultiByteUInt31();
            int offset = BufferReader.ReadBytes(length);
            handle.SetValue(offset, length);
        } 

        void ReadName(PrefixHandle prefix) 
        { 
            int length = ReadMultiByteUInt31();
            int offset = BufferReader.ReadBytes(length); 
            prefix.SetValue(offset, length);
        }

        void ReadDictionaryName(StringHandle s) 
        {
            int key = ReadDictionaryKey(); 
            s.SetValue(key); 
        }
 
        XmlBinaryNodeType GetNodeType()
        {
            return BufferReader.GetNodeType();
        } 

        void SkipNodeType() 
        { 
            BufferReader.SkipNodeType();
        } 

        int ReadDictionaryKey()
        {
            return BufferReader.ReadDictionaryKey(); 
        }
 
        int ReadMultiByteUInt31() 
        {
            return BufferReader.ReadMultiByteUInt31(); 
        }

        int ReadUInt8()
        { 
            return BufferReader.ReadUInt8();
        } 
 
        int ReadUInt16()
        { 
            return BufferReader.ReadUInt16();
        }

        int ReadUInt31() 
        {
            return BufferReader.ReadUInt31(); 
        } 

        bool IsValidArrayType(XmlBinaryNodeType nodeType) 
        {
            switch (nodeType)
            {
                case XmlBinaryNodeType.BoolTextWithEndElement: 
                case XmlBinaryNodeType.Int16TextWithEndElement:
                case XmlBinaryNodeType.Int32TextWithEndElement: 
                case XmlBinaryNodeType.Int64TextWithEndElement: 
                case XmlBinaryNodeType.FloatTextWithEndElement:
                case XmlBinaryNodeType.DoubleTextWithEndElement: 
                case XmlBinaryNodeType.DecimalTextWithEndElement:
                case XmlBinaryNodeType.DateTimeTextWithEndElement:
                case XmlBinaryNodeType.TimeSpanTextWithEndElement:
                case XmlBinaryNodeType.GuidTextWithEndElement: 
                    return true;
                default: 
                    return false; 
            }
        } 

        void ReadArray()
        {
            if (GetNodeType() == XmlBinaryNodeType.Array) // Prevent recursion 
                XmlExceptionHelper.ThrowInvalidBinaryFormat(this);
            ReadNode(); // ReadStartElement 
            if (this.Node.NodeType != XmlNodeType.Element) 
                XmlExceptionHelper.ThrowInvalidBinaryFormat(this);
            if (GetNodeType() == XmlBinaryNodeType.Array) // Prevent recursion 
                XmlExceptionHelper.ThrowInvalidBinaryFormat(this);
            ReadNode(); // ReadEndElement
            if (this.Node.NodeType != XmlNodeType.EndElement)
                XmlExceptionHelper.ThrowInvalidBinaryFormat(this); 
            arrayState = ArrayState.Element;
            arrayNodeType = GetNodeType(); 
            if (!IsValidArrayType(arrayNodeType)) 
                XmlExceptionHelper.ThrowInvalidBinaryFormat(this);
            SkipNodeType(); 
            arrayCount = ReadMultiByteUInt31();
            if (arrayCount == 0)
                XmlExceptionHelper.ThrowInvalidBinaryFormat(this);
            MoveToArrayElement(); 
        }
 
        void MoveToArrayElement() 
        {
            arrayState = ArrayState.Element; 
            MoveToNode(ElementNode);
        }

        void SkipArrayElements(int count) 
        {
            arrayCount -= count; 
            if (arrayCount == 0) 
            {
                arrayState = ArrayState.None; 
                ExitScope();
                ReadNode();
            }
        } 

        public override bool IsStartArray(out Type type) 
        { 
            type = null;
            if (arrayState != ArrayState.Element) 
                return false;
            switch (arrayNodeType)
            {
                case XmlBinaryNodeType.BoolTextWithEndElement: 
                    type = typeof(bool);
                    break; 
                case XmlBinaryNodeType.Int16TextWithEndElement: 
                    type = typeof(Int16);
                    break; 
                case XmlBinaryNodeType.Int32TextWithEndElement:
                    type = typeof(Int32);
                    break;
                case XmlBinaryNodeType.Int64TextWithEndElement: 
                    type = typeof(Int64);
                    break; 
                case XmlBinaryNodeType.FloatTextWithEndElement: 
                    type = typeof(float);
                    break; 
                case XmlBinaryNodeType.DoubleTextWithEndElement:
                    type = typeof(double);
                    break;
                case XmlBinaryNodeType.DecimalTextWithEndElement: 
                    type = typeof(decimal);
                    break; 
                case XmlBinaryNodeType.DateTimeTextWithEndElement: 
                    type = typeof(DateTime);
                    break; 
                case XmlBinaryNodeType.GuidTextWithEndElement:
                    type = typeof(Guid);
                    break;
                case XmlBinaryNodeType.TimeSpanTextWithEndElement: 
                    type = typeof(TimeSpan);
                    break; 
                case XmlBinaryNodeType.UniqueIdTextWithEndElement: 
                    type = typeof(UniqueId);
                    break; 
                default:
                    return false;
            }
            return true; 
        }
 
        public override bool TryGetArrayLength(out int count) 
        {
            count = 0; 
            if (!buffered)
                return false;
            if (arrayState != ArrayState.Element)
                return false; 
            count = arrayCount;
            return true; 
        } 

        bool IsStartArray(string localName, string namespaceUri, XmlBinaryNodeType nodeType) 
        {
            return IsStartElement(localName, namespaceUri) && arrayState == ArrayState.Element && arrayNodeType == nodeType && !Signing;
        }
 
        bool IsStartArray(XmlDictionaryString localName, XmlDictionaryString namespaceUri, XmlBinaryNodeType nodeType)
        { 
            return IsStartElement(localName, namespaceUri) && arrayState == ArrayState.Element && arrayNodeType == nodeType && !Signing; 
        }
 
        void CheckArray(Array array, int offset, int count)
        {
            if (array == null)
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("array")); 
            if (offset < 0)
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.ValueMustBeNonNegative))); 
            if (offset > array.Length) 
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.OffsetExceedsBufferSize, array.Length)));
            if (count < 0) 
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.ValueMustBeNonNegative)));
            if (count > array.Length - offset)
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.SizeExceedsRemainingBufferSpace, array.Length - offset)));
        } 

        // bool 
        [Fx.Tag.SecurityNote(Critical = "Contains unsafe code.", 
            Safe = "Unsafe code is effectively encapsulated, all inputs are validated.")]
        [SecuritySafeCritical] 
        unsafe int ReadArray(bool[] array, int offset, int count)
        {
            CheckArray(array, offset, count);
            int actual = Math.Min(count, arrayCount); 
            fixed (bool* items = &array[offset])
            { 
                BufferReader.UnsafeReadArray((byte*)items, (byte*)&items[actual]); 
            }
            SkipArrayElements(actual); 
            return actual;
        }

        public override int ReadArray(string localName, string namespaceUri, bool[] array, int offset, int count) 
        {
            if (IsStartArray(localName, namespaceUri, XmlBinaryNodeType.BoolTextWithEndElement)) 
                return ReadArray(array, offset, count); 
            return base.ReadArray(localName, namespaceUri, array, offset, count);
        } 

        public override int ReadArray(XmlDictionaryString localName, XmlDictionaryString namespaceUri, bool[] array, int offset, int count)
        {
            if (IsStartArray(localName, namespaceUri, XmlBinaryNodeType.BoolTextWithEndElement)) 
                return ReadArray(array, offset, count);
            return base.ReadArray(localName, namespaceUri, array, offset, count); 
        } 

        // Int16 
        [Fx.Tag.SecurityNote(Critical = "Contains unsafe code.",
            Safe = "Unsafe code is effectively encapsulated, all inputs are validated.")]
        [SecuritySafeCritical]
        unsafe int ReadArray(Int16[] array, int offset, int count) 
        {
            CheckArray(array, offset, count); 
            int actual = Math.Min(count, arrayCount); 
            fixed (Int16* items = &array[offset])
            { 
                BufferReader.UnsafeReadArray((byte*)items, (byte*)&items[actual]);
            }
            SkipArrayElements(actual);
            return actual; 
        }
 
        public override int ReadArray(string localName, string namespaceUri, Int16[] array, int offset, int count) 
        {
            if (IsStartArray(localName, namespaceUri, XmlBinaryNodeType.Int16TextWithEndElement) && BitConverter.IsLittleEndian) 
                return ReadArray(array, offset, count);
            return base.ReadArray(localName, namespaceUri, array, offset, count);
        }
 
        public override int ReadArray(XmlDictionaryString localName, XmlDictionaryString namespaceUri, Int16[] array, int offset, int count)
        { 
            if (IsStartArray(localName, namespaceUri, XmlBinaryNodeType.Int16TextWithEndElement) && BitConverter.IsLittleEndian) 
                return ReadArray(array, offset, count);
            return base.ReadArray(localName, namespaceUri, array, offset, count); 
        }

        // Int32
        [Fx.Tag.SecurityNote(Critical = "Contains unsafe code.", 
            Safe = "Unsafe code is effectively encapsulated, all inputs are validated.")]
        [SecuritySafeCritical] 
        unsafe int ReadArray(Int32[] array, int offset, int count) 
        {
            CheckArray(array, offset, count); 
            int actual = Math.Min(count, arrayCount);
            fixed (Int32* items = &array[offset])
            {
                BufferReader.UnsafeReadArray((byte*)items, (byte*)&items[actual]); 
            }
            SkipArrayElements(actual); 
            return actual; 
        }
 
        public override int ReadArray(string localName, string namespaceUri, Int32[] array, int offset, int count)
        {
            if (IsStartArray(localName, namespaceUri, XmlBinaryNodeType.Int32TextWithEndElement) && BitConverter.IsLittleEndian)
                return ReadArray(array, offset, count); 
            return base.ReadArray(localName, namespaceUri, array, offset, count);
        } 
 
        public override int ReadArray(XmlDictionaryString localName, XmlDictionaryString namespaceUri, Int32[] array, int offset, int count)
        { 
            if (IsStartArray(localName, namespaceUri, XmlBinaryNodeType.Int32TextWithEndElement) && BitConverter.IsLittleEndian)
                return ReadArray(array, offset, count);
            return base.ReadArray(localName, namespaceUri, array, offset, count);
        } 

        // Int64 
        [Fx.Tag.SecurityNote(Critical = "Contains unsafe code.", 
            Safe = "Unsafe code is effectively encapsulated, all inputs are validated.")]
        [SecuritySafeCritical] 
        unsafe int ReadArray(Int64[] array, int offset, int count)
        {
            CheckArray(array, offset, count);
            int actual = Math.Min(count, arrayCount); 
            fixed (Int64* items = &array[offset])
            { 
                BufferReader.UnsafeReadArray((byte*)items, (byte*)&items[actual]); 
            }
            SkipArrayElements(actual); 
            return actual;
        }

        public override int ReadArray(string localName, string namespaceUri, Int64[] array, int offset, int count) 
        {
            if (IsStartArray(localName, namespaceUri, XmlBinaryNodeType.Int64TextWithEndElement) && BitConverter.IsLittleEndian) 
                return ReadArray(array, offset, count); 
            return base.ReadArray(localName, namespaceUri, array, offset, count);
        } 

        public override int ReadArray(XmlDictionaryString localName, XmlDictionaryString namespaceUri, Int64[] array, int offset, int count)
        {
            if (IsStartArray(localName, namespaceUri, XmlBinaryNodeType.Int64TextWithEndElement) && BitConverter.IsLittleEndian) 
                return ReadArray(array, offset, count);
            return base.ReadArray(localName, namespaceUri, array, offset, count); 
        } 

        // float 
        [Fx.Tag.SecurityNote(Critical = "Contains unsafe code.",
            Safe = "Unsafe code is effectively encapsulated, all inputs are validated.")]
        [SecuritySafeCritical]
        unsafe int ReadArray(float[] array, int offset, int count) 
        {
            CheckArray(array, offset, count); 
            int actual = Math.Min(count, arrayCount); 
            fixed (float* items = &array[offset])
            { 
                BufferReader.UnsafeReadArray((byte*)items, (byte*)&items[actual]);
            }
            SkipArrayElements(actual);
            return actual; 
        }
 
        public override int ReadArray(string localName, string namespaceUri, float[] array, int offset, int count) 
        {
            if (IsStartArray(localName, namespaceUri, XmlBinaryNodeType.FloatTextWithEndElement)) 
                return ReadArray(array, offset, count);
            return base.ReadArray(localName, namespaceUri, array, offset, count);
        }
 
        public override int ReadArray(XmlDictionaryString localName, XmlDictionaryString namespaceUri, float[] array, int offset, int count)
        { 
            if (IsStartArray(localName, namespaceUri, XmlBinaryNodeType.FloatTextWithEndElement)) 
                return ReadArray(array, offset, count);
            return base.ReadArray(localName, namespaceUri, array, offset, count); 
        }

        // double
        [Fx.Tag.SecurityNote(Critical = "Contains unsafe code.", 
            Safe = "Unsafe code is effectively encapsulated, all inputs are validated.")]
        [SecuritySafeCritical] 
        unsafe int ReadArray(double[] array, int offset, int count) 
        {
            CheckArray(array, offset, count); 
            int actual = Math.Min(count, arrayCount);
            fixed (double* items = &array[offset])
            {
                BufferReader.UnsafeReadArray((byte*)items, (byte*)&items[actual]); 
            }
            SkipArrayElements(actual); 
            return actual; 
        }
 
        public override int ReadArray(string localName, string namespaceUri, double[] array, int offset, int count)
        {
            if (IsStartArray(localName, namespaceUri, XmlBinaryNodeType.DoubleTextWithEndElement))
                return ReadArray(array, offset, count); 
            return base.ReadArray(localName, namespaceUri, array, offset, count);
        } 
 
        public override int ReadArray(XmlDictionaryString localName, XmlDictionaryString namespaceUri, double[] array, int offset, int count)
        { 
            if (IsStartArray(localName, namespaceUri, XmlBinaryNodeType.DoubleTextWithEndElement))
                return ReadArray(array, offset, count);
            return base.ReadArray(localName, namespaceUri, array, offset, count);
        } 

        // decimal 
        [Fx.Tag.SecurityNote(Critical = "Contains unsafe code.", 
            Safe = "Unsafe code is effectively encapsulated, all inputs are validated.")]
        [SecuritySafeCritical] 
        unsafe int ReadArray(decimal[] array, int offset, int count)
        {
            CheckArray(array, offset, count);
            int actual = Math.Min(count, arrayCount); 
            fixed (decimal* items = &array[offset])
            { 
                BufferReader.UnsafeReadArray((byte*)items, (byte*)&items[actual]); 
            }
            SkipArrayElements(actual); 
            return actual;
        }

        public override int ReadArray(string localName, string namespaceUri, decimal[] array, int offset, int count) 
        {
            if (IsStartArray(localName, namespaceUri, XmlBinaryNodeType.DecimalTextWithEndElement)) 
                return ReadArray(array, offset, count); 
            return base.ReadArray(localName, namespaceUri, array, offset, count);
        } 

        public override int ReadArray(XmlDictionaryString localName, XmlDictionaryString namespaceUri, decimal[] array, int offset, int count)
        {
            if (IsStartArray(localName, namespaceUri, XmlBinaryNodeType.DecimalTextWithEndElement)) 
                return ReadArray(array, offset, count);
            return base.ReadArray(localName, namespaceUri, array, offset, count); 
        } 

        // DateTime 
        int ReadArray(DateTime[] array, int offset, int count)
        {
            CheckArray(array, offset, count);
            int actual = Math.Min(count, arrayCount); 
            for (int i = 0; i < actual; i++)
            { 
                array[offset + i] = BufferReader.ReadDateTime(); 
            }
            SkipArrayElements(actual); 
            return actual;
        }

        public override int ReadArray(string localName, string namespaceUri, DateTime[] array, int offset, int count) 
        {
            if (IsStartArray(localName, namespaceUri, XmlBinaryNodeType.DateTimeTextWithEndElement)) 
                return ReadArray(array, offset, count); 
            return base.ReadArray(localName, namespaceUri, array, offset, count);
        } 

        public override int ReadArray(XmlDictionaryString localName, XmlDictionaryString namespaceUri, DateTime[] array, int offset, int count)
        {
            if (IsStartArray(localName, namespaceUri, XmlBinaryNodeType.DateTimeTextWithEndElement)) 
                return ReadArray(array, offset, count);
            return base.ReadArray(localName, namespaceUri, array, offset, count); 
        } 

        // Guid 
        int ReadArray(Guid[] array, int offset, int count)
        {
            CheckArray(array, offset, count);
            int actual = Math.Min(count, arrayCount); 
            for (int i = 0; i < actual; i++)
            { 
                array[offset + i] = BufferReader.ReadGuid(); 
            }
            SkipArrayElements(actual); 
            return actual;
        }

        public override int ReadArray(string localName, string namespaceUri, Guid[] array, int offset, int count) 
        {
            if (IsStartArray(localName, namespaceUri, XmlBinaryNodeType.GuidTextWithEndElement)) 
                return ReadArray(array, offset, count); 
            return base.ReadArray(localName, namespaceUri, array, offset, count);
        } 

        public override int ReadArray(XmlDictionaryString localName, XmlDictionaryString namespaceUri, Guid[] array, int offset, int count)
        {
            if (IsStartArray(localName, namespaceUri, XmlBinaryNodeType.GuidTextWithEndElement)) 
                return ReadArray(array, offset, count);
            return base.ReadArray(localName, namespaceUri, array, offset, count); 
        } 

        // TimeSpan 
        int ReadArray(TimeSpan[] array, int offset, int count)
        {
            CheckArray(array, offset, count);
            int actual = Math.Min(count, arrayCount); 
            for (int i = 0; i < actual; i++)
            { 
                array[offset + i] = BufferReader.ReadTimeSpan(); 
            }
            SkipArrayElements(actual); 
            return actual;
        }

        public override int ReadArray(string localName, string namespaceUri, TimeSpan[] array, int offset, int count) 
        {
            if (IsStartArray(localName, namespaceUri, XmlBinaryNodeType.TimeSpanTextWithEndElement)) 
                return ReadArray(array, offset, count); 
            return base.ReadArray(localName, namespaceUri, array, offset, count);
        } 

        public override int ReadArray(XmlDictionaryString localName, XmlDictionaryString namespaceUri, TimeSpan[] array, int offset, int count)
        {
            if (IsStartArray(localName, namespaceUri, XmlBinaryNodeType.TimeSpanTextWithEndElement)) 
                return ReadArray(array, offset, count);
            return base.ReadArray(localName, namespaceUri, array, offset, count); 
        } 

        enum ArrayState 
        {
            None,
            Element,
            Content 
        }
 
        protected override XmlSigningNodeWriter CreateSigningNodeWriter() 
        {
            return new XmlSigningNodeWriter(false); 
        }
    }
}

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


                        

Link Menu

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