XmlCharCheckingReader.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Xml / System / Xml / Core / XmlCharCheckingReader.cs / 1305376 / XmlCharCheckingReader.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
 
using System; 
using System.Xml;
using System.Diagnostics; 
using System.Collections;
using System.Collections.Generic;

namespace System.Xml { 

    // 
    // XmlCharCheckingReaderWithNS 
    //
    internal class XmlCharCheckingReader : XmlWrappingReader { 
//
// Private types
//
        enum State { 
            Initial,
            InReadBinary, 
            Error, 
            Interactive,  // Interactive means other than ReadState.Initial and ReadState.Error; still needs to call
                          // underlying XmlReader to find out if the reported ReadState should be Interactive or EndOfFile 
            // NOTE: There is no Closed state here, which is a cause of bugs SQL BU Defect Tracking #533397 and #530403. They were resolved as Won't Fix because they are breaking changes.
        };

// 
// Fields
// 
        State state; 

        // settings 
        bool checkCharacters;
        bool ignoreWhitespace;
        bool ignoreComments;
        bool ignorePis; 
        DtdProcessing dtdProcessing; // -1 means do nothing
 
        XmlNodeType     lastNodeType; 
        XmlCharType     xmlCharType;
 
        ReadContentAsBinaryHelper   readBinaryHelper;

//
// Constructor 
//
        internal XmlCharCheckingReader( XmlReader reader, bool checkCharacters, bool ignoreWhitespace, bool ignoreComments, bool ignorePis, DtdProcessing dtdProcessing ) 
            : base( reader ) { 

            Debug.Assert( checkCharacters || ignoreWhitespace || ignoreComments || ignorePis || (int)dtdProcessing != -1 ); 

            state = State.Initial;

            this.checkCharacters = checkCharacters; 
            this.ignoreWhitespace = ignoreWhitespace;
            this.ignoreComments = ignoreComments; 
            this.ignorePis = ignorePis; 
            this.dtdProcessing = dtdProcessing;
 
            lastNodeType = XmlNodeType.None;

            if ( checkCharacters ) {
                xmlCharType = XmlCharType.Instance; 
            }
        } 
 
//
// XmlReader implementation 
//
        public override XmlReaderSettings Settings {
            get {
                XmlReaderSettings settings = reader.Settings; 
                if ( settings == null ) {
                    settings = new XmlReaderSettings(); 
                } 
                else {
                    settings = settings.Clone(); 
                }

                if ( checkCharacters ) {
                    settings.CheckCharacters = true; 
                }
                if ( ignoreWhitespace ) { 
                    settings.IgnoreWhitespace = true; 
                }
                if ( ignoreComments ) { 
                    settings.IgnoreComments = true;
                }
                if ( ignorePis ) {
                    settings.IgnoreProcessingInstructions = true; 
                }
                if ( (int)dtdProcessing != -1 ) { 
                    settings.DtdProcessing = dtdProcessing; 
                }
                settings.ReadOnly = true; 
                return settings;
            }
        }
 
        public override bool MoveToAttribute( string name ) {
            if ( state == State.InReadBinary ) { 
                FinishReadBinary(); 
            }
            return base.reader.MoveToAttribute( name ); 
        }

        public override bool MoveToAttribute( string name, string ns ) {
            if ( state == State.InReadBinary ) { 
                FinishReadBinary();
            } 
            return base.reader.MoveToAttribute( name, ns ); 
        }
 
        public override void MoveToAttribute( int i ) {
            if ( state == State.InReadBinary ) {
                FinishReadBinary();
            } 
            base.reader.MoveToAttribute( i );
        } 
 
        public override bool MoveToFirstAttribute() {
            if ( state == State.InReadBinary ) { 
                FinishReadBinary();
            }
            return base.reader.MoveToFirstAttribute();
        } 

        public override bool MoveToNextAttribute() { 
            if ( state == State.InReadBinary ) { 
                FinishReadBinary();
            } 
            return base.reader.MoveToNextAttribute();
        }

        public override bool MoveToElement() { 
            if ( state == State.InReadBinary ) {
                FinishReadBinary(); 
            } 
            return base.reader.MoveToElement();
        } 

        public override bool Read() {

            switch ( state ) { 
                case State.Initial:
                    state = State.Interactive; 
                    if ( base.reader.ReadState == ReadState.Initial ) { 
                        goto case State.Interactive;
                    } 
                    break;

                case State.Error:
                    return false; 

                case State.InReadBinary: 
                    FinishReadBinary(); 
                    state = State.Interactive;
                    goto case State.Interactive; 

                case State.Interactive:
                    if ( !base.reader.Read() ) {
                        return false; 
                    }
                    break; 
 
                default:
                    Debug.Assert( false ); 
                    return false;
            }

            XmlNodeType nodeType = base.reader.NodeType; 

            if ( !checkCharacters ) { 
                switch ( nodeType ) { 
                    case XmlNodeType.Comment:
                        if ( ignoreComments ) { 
                            return Read();
                        }
                        break;
                    case XmlNodeType.Whitespace: 
                        if ( ignoreWhitespace ) {
                            return Read(); 
                        } 
                        break;
                    case XmlNodeType.ProcessingInstruction: 
                        if ( ignorePis ) {
                            return Read();
                        }
                        break; 
                    case XmlNodeType.DocumentType:
                        if ( dtdProcessing == DtdProcessing.Prohibit ) { 
                            Throw( Res.Xml_DtdIsProhibitedEx, string.Empty ); 
                        }
                        else if ( dtdProcessing == DtdProcessing.Ignore ) { 
                            return Read();
                        }
                        break;
                } 
                return true;
            } 
            else { 
                switch ( nodeType ) {
                    case XmlNodeType.Element: 
                        if ( checkCharacters ) {
                            // check element name
                            ValidateQName( base.reader.Prefix, base.reader.LocalName );
 
                            // check values of attributes
                            if ( base.reader.MoveToFirstAttribute() ) { 
                                do { 
                                    ValidateQName( base.reader.Prefix, base.reader.LocalName );
                                    CheckCharacters( base.reader.Value ); 
                                } while ( base.reader.MoveToNextAttribute() );

                                base.reader.MoveToElement();
                            } 
                        }
                        break; 
 
                    case XmlNodeType.Text:
                    case XmlNodeType.CDATA: 
                        if ( checkCharacters ) {
                            CheckCharacters( base.reader.Value );
                        }
                        break; 

                    case XmlNodeType.EntityReference: 
                        if ( checkCharacters ) { 
                            // check name
                            ValidateQName( base.reader.Name ); 
                        }
                        break;

                    case XmlNodeType.ProcessingInstruction: 
                        if ( ignorePis ) {
                            return Read(); 
                        } 
                        if ( checkCharacters ) {
                            ValidateQName( base.reader.Name ); 
                            CheckCharacters( base.reader.Value );
                        }
                        break;
 
                    case XmlNodeType.Comment:
                        if ( ignoreComments ) { 
                            return Read(); 
                        }
                        if ( checkCharacters ) { 
                            CheckCharacters( base.reader.Value );
                        }
                        break;
 
                    case XmlNodeType.DocumentType:
                        if ( dtdProcessing == DtdProcessing.Prohibit ) { 
                            Throw( Res.Xml_DtdIsProhibitedEx, string.Empty ); 
                        }
                        else if ( dtdProcessing == DtdProcessing.Ignore ) { 
                            return Read();
                        }
                        if ( checkCharacters ) {
                            ValidateQName( base.reader.Name ); 
                            CheckCharacters( base.reader.Value );
 
                            string str; 
                            str = base.reader.GetAttribute( "SYSTEM" );
                            if ( str != null ) { 
                                CheckCharacters( str );
                            }

                            str = base.reader.GetAttribute( "PUBLIC" ); 
                            if ( str != null ) {
                                int i; 
                                if ( ( i = xmlCharType.IsPublicId( str ) ) >= 0 ) { 
                                    Throw( Res.Xml_InvalidCharacter, XmlException.BuildCharExceptionArgs( str, i ) );
                                } 
                            }
                        }
                        break;
 
                    case XmlNodeType.Whitespace:
                        if ( ignoreWhitespace ) { 
                            return Read(); 
                        }
                        if ( checkCharacters ) { 
                            CheckWhitespace( base.reader.Value );
                        }
                        break;
 
                    case XmlNodeType.SignificantWhitespace:
                        if ( checkCharacters ) { 
                            CheckWhitespace( base.reader.Value ); 
                        }
                        break; 

                    case XmlNodeType.EndElement:
                        if ( checkCharacters ) {
                            ValidateQName( base.reader.Prefix, base.reader.LocalName ); 
                        }
                        break; 
 
                    default:
                        break; 
                }
                lastNodeType = nodeType;
                return true;
            } 
        }
 
        public override ReadState ReadState { 
            get {
                switch ( state ) { 
                    case State.Initial:
                        return base.reader.ReadState == ReadState.Closed ? ReadState.Closed : ReadState.Initial;
                    case State.Error:
                        return ReadState.Error; 
                    case State.InReadBinary:
                    case State.Interactive: 
                    default: 
                        return base.reader.ReadState;
                } 
            }
        }

        public override bool ReadAttributeValue() { 
            if ( state == State.InReadBinary ) {
                FinishReadBinary(); 
            } 
            return base.reader.ReadAttributeValue();
        } 

        public override bool CanReadBinaryContent {
            get {
                return true; 
            }
        } 
 
        public override int ReadContentAsBase64( byte[] buffer, int index, int count ) {
 
            if (ReadState != ReadState.Interactive) {
                return 0;
            }
 
            if ( state != State.InReadBinary ) {
                // forward ReadBase64Chunk calls into the base (wrapped) reader if possible, i.e. if it can read binary and we 
                // should not check characters 
                if ( base.CanReadBinaryContent && ( !checkCharacters ) ) {
                    readBinaryHelper = null; 
                    state = State.InReadBinary;
                    return base.ReadContentAsBase64( buffer, index, count );
                }
                // the wrapped reader cannot read chunks or we are on an element where we should check characters or ignore white spaces 
                else {
                    readBinaryHelper = ReadContentAsBinaryHelper.CreateOrReset( readBinaryHelper, this ); 
                } 
            }
            else { 
                // forward calls into wrapped reader
                if ( readBinaryHelper == null ) {
                    return base.ReadContentAsBase64( buffer, index, count );
                } 
            }
 
            // turn off InReadBinary state in order to have a normal Read() behavior when called from readBinaryHelper 
            state = State.Interactive;
 
            // call to the helper
            int readCount = readBinaryHelper.ReadContentAsBase64(buffer, index, count);

            // turn on InReadBinary in again and return 
            state = State.InReadBinary;
            return readCount; 
        } 

        public override int ReadContentAsBinHex( byte[] buffer, int index, int count ) { 

            if (ReadState != ReadState.Interactive) {
                return 0;
            } 

            if ( state != State.InReadBinary ) { 
                // forward ReadBinHexChunk calls into the base (wrapped) reader if possible, i.e. if it can read chunks and we 
                // should not check characters
                if ( base.CanReadBinaryContent && ( !checkCharacters ) ) { 
                    readBinaryHelper = null;
                    state = State.InReadBinary;
                    return base.ReadContentAsBinHex( buffer, index, count );
                } 
                // the wrapped reader cannot read chunks or we are on an element where we should check characters or ignore white spaces
                else { 
                    readBinaryHelper = ReadContentAsBinaryHelper.CreateOrReset( readBinaryHelper, this ); 
                }
            } 
            else {
                // forward calls into wrapped reader
                if ( readBinaryHelper == null ) {
                    return base.ReadContentAsBinHex( buffer, index, count ); 
                }
            } 
 
            // turn off InReadBinary state in order to have a normal Read() behavior when called from readBinaryHelper
            state = State.Interactive; 

            // call to the helper
            int readCount = readBinaryHelper.ReadContentAsBinHex(buffer, index, count);
 
            // turn on InReadBinary in again and return
            state = State.InReadBinary; 
            return readCount; 
        }
 
        public override int ReadElementContentAsBase64( byte[] buffer, int index, int count ) {
            // check arguments
            if (buffer == null) {
                throw new ArgumentNullException("buffer"); 
            }
            if (count < 0) { 
                throw new ArgumentOutOfRangeException("count"); 
            }
            if (index < 0) { 
                throw new ArgumentOutOfRangeException("index");
            }
            if (buffer.Length - index < count) {
                throw new ArgumentOutOfRangeException("count"); 
            }
 
            if (ReadState != ReadState.Interactive) { 
                return 0;
            } 

            if ( state != State.InReadBinary ) {
                // forward ReadBase64Chunk calls into the base (wrapped) reader if possible, i.e. if it can read binary and we
                // should not check characters 
                if ( base.CanReadBinaryContent && ( !checkCharacters ) ) {
                    readBinaryHelper = null; 
                    state = State.InReadBinary; 
                    return base.ReadElementContentAsBase64( buffer, index, count );
                } 
                // the wrapped reader cannot read chunks or we are on an element where we should check characters or ignore white spaces
                else {
                    readBinaryHelper = ReadContentAsBinaryHelper.CreateOrReset( readBinaryHelper, this );
                } 
            }
            else { 
                // forward calls into wrapped reader 
                if ( readBinaryHelper == null ) {
                    return base.ReadElementContentAsBase64( buffer, index, count ); 
                }
            }

            // turn off InReadBinary state in order to have a normal Read() behavior when called from readBinaryHelper 
            state = State.Interactive;
 
            // call to the helper 
            int readCount = readBinaryHelper.ReadElementContentAsBase64(buffer, index, count);
 
            // turn on InReadBinary in again and return
            state = State.InReadBinary;
            return readCount;
        } 

        public override int ReadElementContentAsBinHex( byte[] buffer, int index, int count ) { 
            // check arguments 
            if (buffer == null) {
                throw new ArgumentNullException("buffer"); 
            }
            if (count < 0) {
                throw new ArgumentOutOfRangeException("count");
            } 
            if (index < 0) {
                throw new ArgumentOutOfRangeException("index"); 
            } 
            if (buffer.Length - index < count) {
                throw new ArgumentOutOfRangeException("count"); 
            }
            if (ReadState != ReadState.Interactive) {
                return 0;
            } 

            if ( state != State.InReadBinary ) { 
                // forward ReadBinHexChunk calls into the base (wrapped) reader if possible, i.e. if it can read chunks and we 
                // should not check characters
                if ( base.CanReadBinaryContent && ( !checkCharacters ) ) { 
                    readBinaryHelper = null;
                    state = State.InReadBinary;
                    return base.ReadElementContentAsBinHex( buffer, index, count );
                } 
                // the wrapped reader cannot read chunks or we are on an element where we should check characters or ignore white spaces
                else { 
                    readBinaryHelper = ReadContentAsBinaryHelper.CreateOrReset( readBinaryHelper, this ); 
                }
            } 
            else {
                // forward calls into wrapped reader
                if ( readBinaryHelper == null ) {
                    return base.ReadElementContentAsBinHex( buffer, index, count ); 
                }
            } 
 
            // turn off InReadBinary state in order to have a normal Read() behavior when called from readBinaryHelper
            state = State.Interactive; 

            // call to the helper
            int readCount = readBinaryHelper.ReadElementContentAsBinHex(buffer, index, count);
 
            // turn on InReadBinary in again and return
            state = State.InReadBinary; 
            return readCount; 
        }
 
//
// Private methods and properties
//
 
        private void Throw( string res, string arg ) {
            state = State.Error; 
            throw new XmlException( res, arg, (IXmlLineInfo)null ); 
        }
 
        private void Throw( string res, string[] args ) {
            state = State.Error;
            throw new XmlException( res, args, (IXmlLineInfo)null );
        } 

        private void CheckWhitespace( string value ) { 
            int i; 
            if ( ( i = xmlCharType.IsOnlyWhitespaceWithPos( value ) ) != -1 ) {
                Throw( Res.Xml_InvalidWhitespaceCharacter, XmlException.BuildCharExceptionArgs( value, i ) ); 
            }
        }

        private void ValidateQName( string name ) { 
            string prefix, localName;
            ValidateNames.ParseQNameThrow( name, out prefix, out localName ); 
        } 

        private void ValidateQName( string prefix, string localName ) { 
            try {
                if ( prefix.Length > 0 ) {
                    ValidateNames.ParseNCNameThrow( prefix );
                } 
                ValidateNames.ParseNCNameThrow( localName );
            } 
            catch { 
                state = State.Error;
                throw; 
            }
        }

        private void CheckCharacters( string value ) { 
            XmlConvert.VerifyCharData( value, ExceptionType.ArgumentException, ExceptionType.XmlException );
        } 
 
        private void FinishReadBinary() {
            state = State.Interactive; 
            if ( readBinaryHelper != null ) {
                readBinaryHelper.Finish();
            }
        } 
    }
 
    // 
    // XmlCharCheckingReaderWithNS
    // 
    internal class XmlCharCheckingReaderWithNS : XmlCharCheckingReader, IXmlNamespaceResolver {

        internal IXmlNamespaceResolver readerAsNSResolver;
 
        internal XmlCharCheckingReaderWithNS( XmlReader reader, IXmlNamespaceResolver readerAsNSResolver, bool checkCharacters, bool ignoreWhitespace, bool ignoreComments, bool ignorePis, DtdProcessing dtdProcessing )
            : base( reader, checkCharacters, ignoreWhitespace, ignoreComments, ignorePis, dtdProcessing ) { 
            Debug.Assert( readerAsNSResolver != null ); 
            this.readerAsNSResolver = readerAsNSResolver;
        } 
//
// IXmlNamespaceResolver
//
        IDictionary IXmlNamespaceResolver.GetNamespacesInScope( XmlNamespaceScope scope ) { 
            return readerAsNSResolver.GetNamespacesInScope( scope );
        } 
 
        string IXmlNamespaceResolver.LookupNamespace( string prefix ) {
            return readerAsNSResolver.LookupNamespace( prefix ); 
        }

        string IXmlNamespaceResolver.LookupPrefix( string namespaceName ) {
            return readerAsNSResolver.LookupPrefix( namespaceName ); 
        }
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
 
using System; 
using System.Xml;
using System.Diagnostics; 
using System.Collections;
using System.Collections.Generic;

namespace System.Xml { 

    // 
    // XmlCharCheckingReaderWithNS 
    //
    internal class XmlCharCheckingReader : XmlWrappingReader { 
//
// Private types
//
        enum State { 
            Initial,
            InReadBinary, 
            Error, 
            Interactive,  // Interactive means other than ReadState.Initial and ReadState.Error; still needs to call
                          // underlying XmlReader to find out if the reported ReadState should be Interactive or EndOfFile 
            // NOTE: There is no Closed state here, which is a cause of bugs SQL BU Defect Tracking #533397 and #530403. They were resolved as Won't Fix because they are breaking changes.
        };

// 
// Fields
// 
        State state; 

        // settings 
        bool checkCharacters;
        bool ignoreWhitespace;
        bool ignoreComments;
        bool ignorePis; 
        DtdProcessing dtdProcessing; // -1 means do nothing
 
        XmlNodeType     lastNodeType; 
        XmlCharType     xmlCharType;
 
        ReadContentAsBinaryHelper   readBinaryHelper;

//
// Constructor 
//
        internal XmlCharCheckingReader( XmlReader reader, bool checkCharacters, bool ignoreWhitespace, bool ignoreComments, bool ignorePis, DtdProcessing dtdProcessing ) 
            : base( reader ) { 

            Debug.Assert( checkCharacters || ignoreWhitespace || ignoreComments || ignorePis || (int)dtdProcessing != -1 ); 

            state = State.Initial;

            this.checkCharacters = checkCharacters; 
            this.ignoreWhitespace = ignoreWhitespace;
            this.ignoreComments = ignoreComments; 
            this.ignorePis = ignorePis; 
            this.dtdProcessing = dtdProcessing;
 
            lastNodeType = XmlNodeType.None;

            if ( checkCharacters ) {
                xmlCharType = XmlCharType.Instance; 
            }
        } 
 
//
// XmlReader implementation 
//
        public override XmlReaderSettings Settings {
            get {
                XmlReaderSettings settings = reader.Settings; 
                if ( settings == null ) {
                    settings = new XmlReaderSettings(); 
                } 
                else {
                    settings = settings.Clone(); 
                }

                if ( checkCharacters ) {
                    settings.CheckCharacters = true; 
                }
                if ( ignoreWhitespace ) { 
                    settings.IgnoreWhitespace = true; 
                }
                if ( ignoreComments ) { 
                    settings.IgnoreComments = true;
                }
                if ( ignorePis ) {
                    settings.IgnoreProcessingInstructions = true; 
                }
                if ( (int)dtdProcessing != -1 ) { 
                    settings.DtdProcessing = dtdProcessing; 
                }
                settings.ReadOnly = true; 
                return settings;
            }
        }
 
        public override bool MoveToAttribute( string name ) {
            if ( state == State.InReadBinary ) { 
                FinishReadBinary(); 
            }
            return base.reader.MoveToAttribute( name ); 
        }

        public override bool MoveToAttribute( string name, string ns ) {
            if ( state == State.InReadBinary ) { 
                FinishReadBinary();
            } 
            return base.reader.MoveToAttribute( name, ns ); 
        }
 
        public override void MoveToAttribute( int i ) {
            if ( state == State.InReadBinary ) {
                FinishReadBinary();
            } 
            base.reader.MoveToAttribute( i );
        } 
 
        public override bool MoveToFirstAttribute() {
            if ( state == State.InReadBinary ) { 
                FinishReadBinary();
            }
            return base.reader.MoveToFirstAttribute();
        } 

        public override bool MoveToNextAttribute() { 
            if ( state == State.InReadBinary ) { 
                FinishReadBinary();
            } 
            return base.reader.MoveToNextAttribute();
        }

        public override bool MoveToElement() { 
            if ( state == State.InReadBinary ) {
                FinishReadBinary(); 
            } 
            return base.reader.MoveToElement();
        } 

        public override bool Read() {

            switch ( state ) { 
                case State.Initial:
                    state = State.Interactive; 
                    if ( base.reader.ReadState == ReadState.Initial ) { 
                        goto case State.Interactive;
                    } 
                    break;

                case State.Error:
                    return false; 

                case State.InReadBinary: 
                    FinishReadBinary(); 
                    state = State.Interactive;
                    goto case State.Interactive; 

                case State.Interactive:
                    if ( !base.reader.Read() ) {
                        return false; 
                    }
                    break; 
 
                default:
                    Debug.Assert( false ); 
                    return false;
            }

            XmlNodeType nodeType = base.reader.NodeType; 

            if ( !checkCharacters ) { 
                switch ( nodeType ) { 
                    case XmlNodeType.Comment:
                        if ( ignoreComments ) { 
                            return Read();
                        }
                        break;
                    case XmlNodeType.Whitespace: 
                        if ( ignoreWhitespace ) {
                            return Read(); 
                        } 
                        break;
                    case XmlNodeType.ProcessingInstruction: 
                        if ( ignorePis ) {
                            return Read();
                        }
                        break; 
                    case XmlNodeType.DocumentType:
                        if ( dtdProcessing == DtdProcessing.Prohibit ) { 
                            Throw( Res.Xml_DtdIsProhibitedEx, string.Empty ); 
                        }
                        else if ( dtdProcessing == DtdProcessing.Ignore ) { 
                            return Read();
                        }
                        break;
                } 
                return true;
            } 
            else { 
                switch ( nodeType ) {
                    case XmlNodeType.Element: 
                        if ( checkCharacters ) {
                            // check element name
                            ValidateQName( base.reader.Prefix, base.reader.LocalName );
 
                            // check values of attributes
                            if ( base.reader.MoveToFirstAttribute() ) { 
                                do { 
                                    ValidateQName( base.reader.Prefix, base.reader.LocalName );
                                    CheckCharacters( base.reader.Value ); 
                                } while ( base.reader.MoveToNextAttribute() );

                                base.reader.MoveToElement();
                            } 
                        }
                        break; 
 
                    case XmlNodeType.Text:
                    case XmlNodeType.CDATA: 
                        if ( checkCharacters ) {
                            CheckCharacters( base.reader.Value );
                        }
                        break; 

                    case XmlNodeType.EntityReference: 
                        if ( checkCharacters ) { 
                            // check name
                            ValidateQName( base.reader.Name ); 
                        }
                        break;

                    case XmlNodeType.ProcessingInstruction: 
                        if ( ignorePis ) {
                            return Read(); 
                        } 
                        if ( checkCharacters ) {
                            ValidateQName( base.reader.Name ); 
                            CheckCharacters( base.reader.Value );
                        }
                        break;
 
                    case XmlNodeType.Comment:
                        if ( ignoreComments ) { 
                            return Read(); 
                        }
                        if ( checkCharacters ) { 
                            CheckCharacters( base.reader.Value );
                        }
                        break;
 
                    case XmlNodeType.DocumentType:
                        if ( dtdProcessing == DtdProcessing.Prohibit ) { 
                            Throw( Res.Xml_DtdIsProhibitedEx, string.Empty ); 
                        }
                        else if ( dtdProcessing == DtdProcessing.Ignore ) { 
                            return Read();
                        }
                        if ( checkCharacters ) {
                            ValidateQName( base.reader.Name ); 
                            CheckCharacters( base.reader.Value );
 
                            string str; 
                            str = base.reader.GetAttribute( "SYSTEM" );
                            if ( str != null ) { 
                                CheckCharacters( str );
                            }

                            str = base.reader.GetAttribute( "PUBLIC" ); 
                            if ( str != null ) {
                                int i; 
                                if ( ( i = xmlCharType.IsPublicId( str ) ) >= 0 ) { 
                                    Throw( Res.Xml_InvalidCharacter, XmlException.BuildCharExceptionArgs( str, i ) );
                                } 
                            }
                        }
                        break;
 
                    case XmlNodeType.Whitespace:
                        if ( ignoreWhitespace ) { 
                            return Read(); 
                        }
                        if ( checkCharacters ) { 
                            CheckWhitespace( base.reader.Value );
                        }
                        break;
 
                    case XmlNodeType.SignificantWhitespace:
                        if ( checkCharacters ) { 
                            CheckWhitespace( base.reader.Value ); 
                        }
                        break; 

                    case XmlNodeType.EndElement:
                        if ( checkCharacters ) {
                            ValidateQName( base.reader.Prefix, base.reader.LocalName ); 
                        }
                        break; 
 
                    default:
                        break; 
                }
                lastNodeType = nodeType;
                return true;
            } 
        }
 
        public override ReadState ReadState { 
            get {
                switch ( state ) { 
                    case State.Initial:
                        return base.reader.ReadState == ReadState.Closed ? ReadState.Closed : ReadState.Initial;
                    case State.Error:
                        return ReadState.Error; 
                    case State.InReadBinary:
                    case State.Interactive: 
                    default: 
                        return base.reader.ReadState;
                } 
            }
        }

        public override bool ReadAttributeValue() { 
            if ( state == State.InReadBinary ) {
                FinishReadBinary(); 
            } 
            return base.reader.ReadAttributeValue();
        } 

        public override bool CanReadBinaryContent {
            get {
                return true; 
            }
        } 
 
        public override int ReadContentAsBase64( byte[] buffer, int index, int count ) {
 
            if (ReadState != ReadState.Interactive) {
                return 0;
            }
 
            if ( state != State.InReadBinary ) {
                // forward ReadBase64Chunk calls into the base (wrapped) reader if possible, i.e. if it can read binary and we 
                // should not check characters 
                if ( base.CanReadBinaryContent && ( !checkCharacters ) ) {
                    readBinaryHelper = null; 
                    state = State.InReadBinary;
                    return base.ReadContentAsBase64( buffer, index, count );
                }
                // the wrapped reader cannot read chunks or we are on an element where we should check characters or ignore white spaces 
                else {
                    readBinaryHelper = ReadContentAsBinaryHelper.CreateOrReset( readBinaryHelper, this ); 
                } 
            }
            else { 
                // forward calls into wrapped reader
                if ( readBinaryHelper == null ) {
                    return base.ReadContentAsBase64( buffer, index, count );
                } 
            }
 
            // turn off InReadBinary state in order to have a normal Read() behavior when called from readBinaryHelper 
            state = State.Interactive;
 
            // call to the helper
            int readCount = readBinaryHelper.ReadContentAsBase64(buffer, index, count);

            // turn on InReadBinary in again and return 
            state = State.InReadBinary;
            return readCount; 
        } 

        public override int ReadContentAsBinHex( byte[] buffer, int index, int count ) { 

            if (ReadState != ReadState.Interactive) {
                return 0;
            } 

            if ( state != State.InReadBinary ) { 
                // forward ReadBinHexChunk calls into the base (wrapped) reader if possible, i.e. if it can read chunks and we 
                // should not check characters
                if ( base.CanReadBinaryContent && ( !checkCharacters ) ) { 
                    readBinaryHelper = null;
                    state = State.InReadBinary;
                    return base.ReadContentAsBinHex( buffer, index, count );
                } 
                // the wrapped reader cannot read chunks or we are on an element where we should check characters or ignore white spaces
                else { 
                    readBinaryHelper = ReadContentAsBinaryHelper.CreateOrReset( readBinaryHelper, this ); 
                }
            } 
            else {
                // forward calls into wrapped reader
                if ( readBinaryHelper == null ) {
                    return base.ReadContentAsBinHex( buffer, index, count ); 
                }
            } 
 
            // turn off InReadBinary state in order to have a normal Read() behavior when called from readBinaryHelper
            state = State.Interactive; 

            // call to the helper
            int readCount = readBinaryHelper.ReadContentAsBinHex(buffer, index, count);
 
            // turn on InReadBinary in again and return
            state = State.InReadBinary; 
            return readCount; 
        }
 
        public override int ReadElementContentAsBase64( byte[] buffer, int index, int count ) {
            // check arguments
            if (buffer == null) {
                throw new ArgumentNullException("buffer"); 
            }
            if (count < 0) { 
                throw new ArgumentOutOfRangeException("count"); 
            }
            if (index < 0) { 
                throw new ArgumentOutOfRangeException("index");
            }
            if (buffer.Length - index < count) {
                throw new ArgumentOutOfRangeException("count"); 
            }
 
            if (ReadState != ReadState.Interactive) { 
                return 0;
            } 

            if ( state != State.InReadBinary ) {
                // forward ReadBase64Chunk calls into the base (wrapped) reader if possible, i.e. if it can read binary and we
                // should not check characters 
                if ( base.CanReadBinaryContent && ( !checkCharacters ) ) {
                    readBinaryHelper = null; 
                    state = State.InReadBinary; 
                    return base.ReadElementContentAsBase64( buffer, index, count );
                } 
                // the wrapped reader cannot read chunks or we are on an element where we should check characters or ignore white spaces
                else {
                    readBinaryHelper = ReadContentAsBinaryHelper.CreateOrReset( readBinaryHelper, this );
                } 
            }
            else { 
                // forward calls into wrapped reader 
                if ( readBinaryHelper == null ) {
                    return base.ReadElementContentAsBase64( buffer, index, count ); 
                }
            }

            // turn off InReadBinary state in order to have a normal Read() behavior when called from readBinaryHelper 
            state = State.Interactive;
 
            // call to the helper 
            int readCount = readBinaryHelper.ReadElementContentAsBase64(buffer, index, count);
 
            // turn on InReadBinary in again and return
            state = State.InReadBinary;
            return readCount;
        } 

        public override int ReadElementContentAsBinHex( byte[] buffer, int index, int count ) { 
            // check arguments 
            if (buffer == null) {
                throw new ArgumentNullException("buffer"); 
            }
            if (count < 0) {
                throw new ArgumentOutOfRangeException("count");
            } 
            if (index < 0) {
                throw new ArgumentOutOfRangeException("index"); 
            } 
            if (buffer.Length - index < count) {
                throw new ArgumentOutOfRangeException("count"); 
            }
            if (ReadState != ReadState.Interactive) {
                return 0;
            } 

            if ( state != State.InReadBinary ) { 
                // forward ReadBinHexChunk calls into the base (wrapped) reader if possible, i.e. if it can read chunks and we 
                // should not check characters
                if ( base.CanReadBinaryContent && ( !checkCharacters ) ) { 
                    readBinaryHelper = null;
                    state = State.InReadBinary;
                    return base.ReadElementContentAsBinHex( buffer, index, count );
                } 
                // the wrapped reader cannot read chunks or we are on an element where we should check characters or ignore white spaces
                else { 
                    readBinaryHelper = ReadContentAsBinaryHelper.CreateOrReset( readBinaryHelper, this ); 
                }
            } 
            else {
                // forward calls into wrapped reader
                if ( readBinaryHelper == null ) {
                    return base.ReadElementContentAsBinHex( buffer, index, count ); 
                }
            } 
 
            // turn off InReadBinary state in order to have a normal Read() behavior when called from readBinaryHelper
            state = State.Interactive; 

            // call to the helper
            int readCount = readBinaryHelper.ReadElementContentAsBinHex(buffer, index, count);
 
            // turn on InReadBinary in again and return
            state = State.InReadBinary; 
            return readCount; 
        }
 
//
// Private methods and properties
//
 
        private void Throw( string res, string arg ) {
            state = State.Error; 
            throw new XmlException( res, arg, (IXmlLineInfo)null ); 
        }
 
        private void Throw( string res, string[] args ) {
            state = State.Error;
            throw new XmlException( res, args, (IXmlLineInfo)null );
        } 

        private void CheckWhitespace( string value ) { 
            int i; 
            if ( ( i = xmlCharType.IsOnlyWhitespaceWithPos( value ) ) != -1 ) {
                Throw( Res.Xml_InvalidWhitespaceCharacter, XmlException.BuildCharExceptionArgs( value, i ) ); 
            }
        }

        private void ValidateQName( string name ) { 
            string prefix, localName;
            ValidateNames.ParseQNameThrow( name, out prefix, out localName ); 
        } 

        private void ValidateQName( string prefix, string localName ) { 
            try {
                if ( prefix.Length > 0 ) {
                    ValidateNames.ParseNCNameThrow( prefix );
                } 
                ValidateNames.ParseNCNameThrow( localName );
            } 
            catch { 
                state = State.Error;
                throw; 
            }
        }

        private void CheckCharacters( string value ) { 
            XmlConvert.VerifyCharData( value, ExceptionType.ArgumentException, ExceptionType.XmlException );
        } 
 
        private void FinishReadBinary() {
            state = State.Interactive; 
            if ( readBinaryHelper != null ) {
                readBinaryHelper.Finish();
            }
        } 
    }
 
    // 
    // XmlCharCheckingReaderWithNS
    // 
    internal class XmlCharCheckingReaderWithNS : XmlCharCheckingReader, IXmlNamespaceResolver {

        internal IXmlNamespaceResolver readerAsNSResolver;
 
        internal XmlCharCheckingReaderWithNS( XmlReader reader, IXmlNamespaceResolver readerAsNSResolver, bool checkCharacters, bool ignoreWhitespace, bool ignoreComments, bool ignorePis, DtdProcessing dtdProcessing )
            : base( reader, checkCharacters, ignoreWhitespace, ignoreComments, ignorePis, dtdProcessing ) { 
            Debug.Assert( readerAsNSResolver != null ); 
            this.readerAsNSResolver = readerAsNSResolver;
        } 
//
// IXmlNamespaceResolver
//
        IDictionary IXmlNamespaceResolver.GetNamespacesInScope( XmlNamespaceScope scope ) { 
            return readerAsNSResolver.GetNamespacesInScope( scope );
        } 
 
        string IXmlNamespaceResolver.LookupNamespace( string prefix ) {
            return readerAsNSResolver.LookupNamespace( prefix ); 
        }

        string IXmlNamespaceResolver.LookupPrefix( string namespaceName ) {
            return readerAsNSResolver.LookupPrefix( namespaceName ); 
        }
    } 
} 

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