protected unsafe void WriteCommentOrPi()

in src/dotnet-svcutil/lib/src/FrameworkFork/Microsoft.Xml/Xml/Core/XmlRawTextWriterGenerator.cxx [1184:1927]


        protected unsafe void WriteCommentOrPi( string text, int stopChar ) {
            if ( text.Length == 0 ) {
                if ( bufPos >= bufLen ) {
                    FlushBuffer();
                }
                return;
            }
            // write text
            fixed ( char * pSrcBegin = text )
            fixed ( _BUFFER_TYPE * pDstBegin = _BUFFER ) {
                char * pSrc = pSrcBegin;
                char * pSrcEnd = pSrcBegin + text.Length;
                _BUFFER_TYPE * pDst = pDstBegin + bufPos;

                int ch = 0;
                for (;;) {
                    _BUFFER_TYPE * pDstEnd = pDst + ( pSrcEnd - pSrc );
                    if ( pDstEnd > pDstBegin + bufLen ) {
                        pDstEnd = pDstBegin + bufLen;
                    }

#ifdef _XML_UTF8_TEXT_WRITER
                    while ( pDst < pDstEnd && ( XMLCHARTYPE_ISTEXT( ( ch = *pSrc ) ) && ch != stopChar && ch <= 0x7F ) ) {
#else
                    while ( pDst < pDstEnd && ( XMLCHARTYPE_ISTEXT( ( ch = *pSrc ) ) && ch != stopChar ) ) {
#endif
                        *pDst = (_BUFFER_TYPE)ch;
                        pDst++;
                        pSrc++;
                    }

                    Debug.Assert( pSrc <= pSrcEnd );

                    // end of value
                    if ( pSrc >= pSrcEnd ) {
                        break;
                    }

                    // end of buffer
                    if ( pDst >= pDstEnd ) {
                        bufPos = (int)(pDst - pDstBegin);
                        FlushBuffer();
                        pDst = pDstBegin + 1;
                        continue;
                    }

                    // handle special characters
                    switch ( ch ) {
                        case '-':
                            *pDst = (_BUFFER_TYPE) '-';
                            pDst++;
                            if ( ch == stopChar ) {
                                // Insert space between adjacent dashes or before comment's end dashes
                                if ( pSrc + 1 == pSrcEnd || *(pSrc + 1)== '-' ) {
                                    *pDst = (_BUFFER_TYPE) ' ';
                                    pDst++;
                                }
                            }
                            break;
                        case '?':
                            *pDst = (_BUFFER_TYPE) '?';
                            pDst++;
                            if ( ch == stopChar ) {
                                // Processing instruction: insert space between adjacent '?' and '>' 
                                if ( pSrc + 1 < pSrcEnd && *(pSrc + 1)== '>' ) {
                                    *pDst = (_BUFFER_TYPE) ' ';
                                    pDst++;
                                }
                            }
                            break;
                        case ']':
                            *pDst = (_BUFFER_TYPE) ']';
                            pDst++;
                            break;
                        case (char)0xD:
                            if ( newLineHandling == NewLineHandling.Replace ) {
                                // Normalize "\r\n", or "\r" to NewLineChars
                                if ( pSrc[1] == '\n' ) {
                                    pSrc++;
                                }
                                pDst = WriteNewLine( pDst );
                            }
                            else {
                                *pDst = (_BUFFER_TYPE)ch;
                                pDst++;
                            }
                            break;
                        case (char)0xA:
                            if ( newLineHandling == NewLineHandling.Replace ) {
                                pDst = WriteNewLine( pDst );
                            }
                            else {
                                *pDst = (_BUFFER_TYPE)ch;
                                pDst++;
                            }
                            break;
                        case '<':
                        case '&':
                        case (char)0x9:
                            *pDst = (_BUFFER_TYPE)ch;
                            pDst++;
                            break;
                        default:
                            _ENCODE_CHAR(false);
                            continue;
                    }
                    pSrc++;
                }
                bufPos = (int)(pDst - pDstBegin);
            }
        }

        protected unsafe void WriteCDataSection( string text ) {
            if ( text.Length == 0 ) {
                if ( bufPos >= bufLen ) {
                    FlushBuffer();
                }
                return;
            }
            // write text
            fixed ( char * pSrcBegin = text )
            fixed ( _BUFFER_TYPE * pDstBegin = _BUFFER ) {
                char * pSrc = pSrcBegin;
                char * pSrcEnd = pSrcBegin + text.Length;
                _BUFFER_TYPE * pDst = pDstBegin + bufPos;

                int ch = 0;
                for (;;) {
                    _BUFFER_TYPE * pDstEnd = pDst + ( pSrcEnd - pSrc );
                    if ( pDstEnd > pDstBegin + bufLen ) {
                        pDstEnd = pDstBegin + bufLen;
                    }

#ifdef _XML_UTF8_TEXT_WRITER
                    while ( pDst < pDstEnd && ( XMLCHARTYPE_ISATTRIBUTEVALUECHAR( ( ch = *pSrc ) ) && ch != ']' && ch <= 0x7F ) ) {
#else
                    while ( pDst < pDstEnd && ( XMLCHARTYPE_ISATTRIBUTEVALUECHAR( ( ch = *pSrc ) ) && ch != ']' ) ) {
#endif
                        *pDst = (_BUFFER_TYPE)ch;
                        pDst++;
                        pSrc++;
                    }

                    Debug.Assert( pSrc <= pSrcEnd );

                    // end of value
                    if ( pSrc >= pSrcEnd ) {
                        break;
                    }

                    // end of buffer
                    if ( pDst >= pDstEnd ) {
                        bufPos = (int)(pDst - pDstBegin);
                        FlushBuffer();
                        pDst = pDstBegin + 1;
                        continue;
                    }

                    // handle special characters
                    switch ( ch ) {
                        case '>':
                            if ( hadDoubleBracket && pDst[-1] == (_BUFFER_TYPE) ']') {   // pDst[-1] will always correct - there is a padding character at _BUFFER[0]
                                // The characters "]]>" were found within the CData text
                                pDst = RawEndCData( pDst );
                                pDst = RawStartCData( pDst );
                            }
                            *pDst = (_BUFFER_TYPE) '>';
                            pDst++;
                            break;
                        case ']':
                            if ( pDst[-1] == (_BUFFER_TYPE)']' ) {   // pDst[-1] will always correct - there is a padding character at _BUFFER[0]
                                hadDoubleBracket = true;
                            }
                            else {
                                hadDoubleBracket = false;
                            }
                            *pDst = (_BUFFER_TYPE)']';
                            pDst++;
                            break;
                        case (char)0xD:
                            if ( newLineHandling == NewLineHandling.Replace ) {
                                // Normalize "\r\n", or "\r" to NewLineChars
                                if ( pSrc[1] == '\n' ) {
                                    pSrc++;
                                }
                                pDst = WriteNewLine( pDst );
                            }
                            else {
                                *pDst = (_BUFFER_TYPE)ch;
                                pDst++;
                            }
                            break;
                        case (char)0xA:
                            if ( newLineHandling == NewLineHandling.Replace ) {
                                pDst = WriteNewLine( pDst );
                            }
                            else {
                                *pDst = (_BUFFER_TYPE)ch;
                                pDst++;
                            }
                            break;
                        case '&':
                        case '<':
                        case '"':
                        case '\'':
                        case (char)0x9:
                            *pDst = (_BUFFER_TYPE)ch;
                            pDst++;
                            break;
                        default:
                            _ENCODE_CHAR(false);
                            continue;
                    }
                    pSrc++;
                }
                bufPos = (int)(pDst - pDstBegin);
            }
        }

#ifdef _XML_UTF8_TEXT_WRITER
        // Returns true if UTF8 encoded byte is first of four bytes that encode a surrogate pair.
        // To do this, detect the bit pattern 11110xxx.
        private static bool IsSurrogateByte( byte b ) {
            return (b & 0xF8) == 0xF0;
        }
#endif

        private static unsafe _BUFFER_TYPE* EncodeSurrogate( char* pSrc, char* pSrcEnd, _BUFFER_TYPE* pDst ) {
            Debug.Assert( XmlCharType.IsSurrogate( *pSrc ) );

            int ch = *pSrc;
            if ( ch <= XmlCharType.SurHighEnd ) {
                if ( pSrc + 1 < pSrcEnd ) {
                    int lowChar = pSrc[1];
                    if ( lowChar >= XmlCharType.SurLowStart ) {
#ifdef _XML_UTF8_TEXT_WRITER
                        // Calculate Unicode scalar value for easier manipulations (see section 3.7 in Unicode spec)
                        // The scalar value repositions surrogate values to start at 0x10000.
                        
                        ch = XmlCharType.CombineSurrogateChar( lowChar, ch );

                        pDst[0] = (byte)( 0xF0 | ( ch >> 18 ) );
                        pDst[1] = (byte)( 0x80 | ( ch >> 12 ) & 0x3F );
                        pDst[2] = (byte)( 0x80 | ( ch >> 6  ) & 0x3F );
                        pDst[3] = (byte)( 0x80 | ch & 0x3F);
                        pDst += 4;
#else
                        pDst[0] = (char)ch;
                        pDst[1] = (char)lowChar;
                        pDst += 2;
#endif
                        return pDst;
                    }
                    throw XmlConvert.CreateInvalidSurrogatePairException( (char)lowChar, (char)ch );
                }
                throw new ArgumentException( Res.GetString( Res.Xml_InvalidSurrogateMissingLowChar ) );
            }
            throw XmlConvert.CreateInvalidHighSurrogateCharException( (char)ch );
        }

        private unsafe _BUFFER_TYPE* InvalidXmlChar( int ch, _BUFFER_TYPE* pDst, bool entitize ) {
            Debug.Assert( !xmlCharType.IsWhiteSpace( (char)ch ) );
            Debug.Assert( !xmlCharType.IsAttributeValueChar( (char)ch ) );

            if ( checkCharacters ) {
                // This method will never be called on surrogates, so it is ok to pass in '\0' to the CreateInvalidCharException
                throw XmlConvert.CreateInvalidCharException( (char)ch, '\0' );
            }
            else {
                if ( entitize ) {
                    return CharEntity( pDst, (char)ch );
                }
                else {
#ifdef _XML_UTF8_TEXT_WRITER
                    if ( ch < 0x80 ) {
#endif
                        *pDst = (_BUFFER_TYPE)ch;
                        pDst++;
#ifdef _XML_UTF8_TEXT_WRITER
                    }
                    else {
                        pDst = EncodeMultibyteUTF8( ch, pDst );
                    }
#endif
                    return pDst;
                }
            }
        }

        internal unsafe void EncodeChar(ref char* pSrc, char*pSrcEnd, ref _BUFFER_TYPE* pDst) {
            int ch = *pSrc;
            _ENCODE_CHAR(false);
        }

#ifdef _XML_UTF8_TEXT_WRITER
        internal static unsafe byte* EncodeMultibyteUTF8( int ch, byte* pDst ) {
            Debug.Assert( ch >= 0x80 && !XmlCharType.IsSurrogate( ch ) );

            /* UTF8-2: If ch is in 0x80-0x7ff range, then use 2 bytes to encode it */ \
            if ( ch < 0x800 ) {    
                *pDst = (byte)( unchecked((sbyte)0xC0) | (ch >> 6) );   
            }   
            /* UTF8-3: If ch is anything else, then default to using 3 bytes to encode it. */   
            else {     
                *pDst = (byte)( unchecked((sbyte)0xE0) | ( ch >> 12 ) );    
                pDst++;

                *pDst = (byte)( unchecked((sbyte)0x80) | ( ch >> 6 ) & 0x3F);   
            }   
            pDst++;
            *pDst = (byte)( 0x80 | ch & 0x3F );   
            return pDst + 1;
        }

        // Encode *pSrc as a sequence of UTF8 bytes.  Write the bytes to pDst and return an updated pointer.
        internal static unsafe void CharToUTF8( ref char * pSrc, char * pSrcEnd, ref byte * pDst ) {
            int ch = *pSrc;
            if ( ch <= 0x7F ) {
                *pDst = (byte)ch;
                pDst++;
                pSrc++;
            }
            else if ( XmlCharType.IsSurrogate( ch ) ) { 
                pDst = EncodeSurrogate( pSrc, pSrcEnd, pDst ); 
                pSrc += 2; 
            } 
            else { 
                pDst = EncodeMultibyteUTF8( ch, pDst ); 
                pSrc++; 
            }
        }

#endif

#ifdef _XML_ENCODED_TEXT_WRITER

        protected void ChangeTextContentMark( bool value ) {
            Debug.Assert( inTextContent != value );
            Debug.Assert( inTextContent || ((lastMarkPos & 1) == 0) );
            inTextContent = value;
            if ( lastMarkPos + 1 == textContentMarks.Length ) {
                GrowTextContentMarks();
            }
            textContentMarks[++lastMarkPos] = this.bufPos;
        }

        private void GrowTextContentMarks() {
            Debug.Assert( lastMarkPos + 1 == textContentMarks.Length );
            int[] newTextContentMarks = new int[ textContentMarks.Length * 2 ];
            Array.Copy( textContentMarks, newTextContentMarks, textContentMarks.Length );
            textContentMarks = newTextContentMarks;
        }

#endif
       
        // Write NewLineChars to the specified buffer position and return an updated position.
        protected unsafe _BUFFER_TYPE * WriteNewLine( _BUFFER_TYPE * pDst ) {
            fixed ( _BUFFER_TYPE * pDstBegin = _BUFFER ) {
                bufPos = (int) (pDst - pDstBegin);
                // Let RawText do the real work
                RawText( newLineChars );
                return pDstBegin + bufPos;
            }
        }

        // Following methods do not check whether pDst is beyond the bufSize because the buffer was allocated with a OVERFLOW to accomodate
        // for the writes of small constant-length string as below.

        // Entitize '<' as "&lt;".  Return an updated pointer.
        protected static unsafe _BUFFER_TYPE * LtEntity( _BUFFER_TYPE * pDst ) {
            pDst[0] = (_BUFFER_TYPE)'&'; 
            pDst[1] = (_BUFFER_TYPE)'l'; 
            pDst[2] = (_BUFFER_TYPE)'t'; 
            pDst[3] = (_BUFFER_TYPE)';';
            return pDst + 4;
        }

        // Entitize '>' as "&gt;".  Return an updated pointer.
        protected static unsafe _BUFFER_TYPE * GtEntity( _BUFFER_TYPE * pDst ) {
            pDst[0] = (_BUFFER_TYPE)'&'; 
            pDst[1] = (_BUFFER_TYPE)'g'; 
            pDst[2] = (_BUFFER_TYPE)'t'; 
            pDst[3] = (_BUFFER_TYPE)';';
            return pDst + 4;
        }

        // Entitize '&' as "&amp;".  Return an updated pointer.
        protected static unsafe _BUFFER_TYPE * AmpEntity( _BUFFER_TYPE * pDst ) {
            pDst[0] = (_BUFFER_TYPE)'&'; 
            pDst[1] = (_BUFFER_TYPE)'a'; 
            pDst[2] = (_BUFFER_TYPE)'m'; 
            pDst[3] = (_BUFFER_TYPE)'p'; 
            pDst[4] = (_BUFFER_TYPE)';';
            return pDst + 5;
        }

        // Entitize '"' as "&quot;".  Return an updated pointer.
        protected static unsafe _BUFFER_TYPE * QuoteEntity( _BUFFER_TYPE * pDst ) {
            pDst[0] = (_BUFFER_TYPE)'&'; 
            pDst[1] = (_BUFFER_TYPE)'q'; 
            pDst[2] = (_BUFFER_TYPE)'u'; 
            pDst[3] = (_BUFFER_TYPE)'o'; 
            pDst[4] = (_BUFFER_TYPE)'t'; 
            pDst[5] = (_BUFFER_TYPE)';';
            return pDst + 6;
        }

        // Entitize '\t' as "&#x9;".  Return an updated pointer.
        protected static unsafe _BUFFER_TYPE * TabEntity( _BUFFER_TYPE * pDst ) {
            pDst[0] = (_BUFFER_TYPE)'&'; 
            pDst[1] = (_BUFFER_TYPE)'#'; 
            pDst[2] = (_BUFFER_TYPE)'x'; 
            pDst[3] = (_BUFFER_TYPE)'9'; 
            pDst[4] = (_BUFFER_TYPE)';';
            return pDst + 5;
        }

        // Entitize 0xa as "&#xA;".  Return an updated pointer.
        protected static unsafe _BUFFER_TYPE * LineFeedEntity( _BUFFER_TYPE * pDst ) {
            pDst[0] = (_BUFFER_TYPE)'&'; 
            pDst[1] = (_BUFFER_TYPE)'#'; 
            pDst[2] = (_BUFFER_TYPE)'x'; 
            pDst[3] = (_BUFFER_TYPE)'A'; 
            pDst[4] = (_BUFFER_TYPE)';';
            return pDst + 5;
        }

        // Entitize 0xd as "&#xD;".  Return an updated pointer.
        protected static unsafe _BUFFER_TYPE * CarriageReturnEntity( _BUFFER_TYPE * pDst ) {
            pDst[0] = (_BUFFER_TYPE)'&'; 
            pDst[1] = (_BUFFER_TYPE)'#'; 
            pDst[2] = (_BUFFER_TYPE)'x'; 
            pDst[3] = (_BUFFER_TYPE)'D'; 
            pDst[4] = (_BUFFER_TYPE)';';
            return pDst + 5;
        }

        private static unsafe _BUFFER_TYPE * CharEntity( _BUFFER_TYPE * pDst, char ch ) {
            string s = ((int)ch).ToString( "X",NumberFormatInfo.InvariantInfo );
            pDst[0] = (_BUFFER_TYPE)'&'; 
            pDst[1] = (_BUFFER_TYPE)'#'; 
            pDst[2] = (_BUFFER_TYPE)'x'; 
            pDst += 3;
            
            fixed ( char *pSrc = s ) {
                char *pS = pSrc;
                while ( ( *pDst++ = (_BUFFER_TYPE)*pS++ ) != 0 );
            }

            pDst[-1] = (_BUFFER_TYPE)';';
            return pDst;
        }

        // Write "<![CDATA[" to the specified buffer.  Return an updated pointer.
        protected static unsafe _BUFFER_TYPE * RawStartCData( _BUFFER_TYPE * pDst ) {
            pDst[0] = (_BUFFER_TYPE)'<'; 
            pDst[1] = (_BUFFER_TYPE)'!'; 
            pDst[2] = (_BUFFER_TYPE)'['; 
            pDst[3] = (_BUFFER_TYPE)'C'; 
            pDst[4] = (_BUFFER_TYPE)'D';
            pDst[5] = (_BUFFER_TYPE)'A'; 
            pDst[6] = (_BUFFER_TYPE)'T'; 
            pDst[7] = (_BUFFER_TYPE)'A'; 
            pDst[8] = (_BUFFER_TYPE)'[';
            return pDst + 9;
        }

        // Write "]]>" to the specified buffer.  Return an updated pointer.
        protected static unsafe _BUFFER_TYPE * RawEndCData( _BUFFER_TYPE * pDst ) {
            pDst[0] = (_BUFFER_TYPE)']'; 
            pDst[1] = (_BUFFER_TYPE)']'; 
            pDst[2] = (_BUFFER_TYPE)'>';
            return pDst + 3;
        }

        protected unsafe void ValidateContentChars( string chars, string propertyName, bool allowOnlyWhitespace ) {
            if ( allowOnlyWhitespace ) {
                if ( !xmlCharType.IsOnlyWhitespace( chars ) ) {
                    throw new ArgumentException( Res.GetString( Res.Xml_IndentCharsNotWhitespace, propertyName ) );
                }
            }
            else {
                string error = null;
                for ( int i = 0; i < chars.Length; i++ ) {
                    if ( !xmlCharType.IsTextChar( chars[i] ) ) {
                        switch ( chars[i] ) {
                            case '\n':
                            case '\r':
                            case '\t':
                                continue;
                            case '<':
                            case '&':
                            case ']':
                                error = Res.GetString( Res.Xml_InvalidCharacter, XmlException.BuildCharExceptionArgs( chars, i ) );
                                goto Error;
                            default:
                                if ( XmlCharType.IsHighSurrogate(chars[i]) ) {
                                    if ( i + 1 < chars.Length ) {
                                        if ( XmlCharType.IsLowSurrogate(chars[i + 1])  ) {
                                            i++;
                                            continue;
                                        }
                                    }
                                    error = Res.GetString( Res.Xml_InvalidSurrogateMissingLowChar );
                                    goto Error;
                                }
                                else if ( XmlCharType.IsLowSurrogate(chars[i]) ) {
                                    error = Res.GetString( Res.Xml_InvalidSurrogateHighChar, ((uint)chars[i]).ToString( "X", CultureInfo.InvariantCulture ) );
                                    goto Error;
                                }
                                continue;
                        }
                    }
                }
                return;

            Error:
                throw new ArgumentException( Res.GetString( Res.Xml_InvalidCharsInIndent, new string[] { propertyName, error } ) );
            }
        }
    }

    // Same as base text writer class except that elements, attributes, comments, and pi's are indented.
    internal class _CLASS_NAME_INDENT : _CLASS_NAME {
//
// Fields
//
        protected int       indentLevel;
        protected bool      newLineOnAttributes;
        protected string    indentChars;

        protected bool      mixedContent;
        private BitStack    mixedContentStack;

        protected ConformanceLevel conformanceLevel = ConformanceLevel.Auto;

//
// Constructors
//

#ifdef _XML_ENCODED_TEXT_WRITER
        public _CLASS_NAME_INDENT( TextWriter writer, XmlWriterSettings settings ) : base( writer, settings ) {
            Init( settings );
        }
#endif

        public _CLASS_NAME_INDENT( Stream stream, XmlWriterSettings settings ) : base( stream, settings ) {
            Init( settings );
        }

//
// XmlWriter methods
//
        public override XmlWriterSettings Settings {
            get {
                XmlWriterSettings settings = base.Settings;

                settings.ReadOnly = false;
                settings.Indent = true;
                settings.IndentChars = indentChars;
                settings.NewLineOnAttributes = newLineOnAttributes;
                settings.ReadOnly = true;

                return settings;
            }
        }

        public override void WriteDocType( string name, string pubid, string sysid, string subset ) {
            // Add indentation
            if ( !mixedContent && base.textPos != base.bufPos) {
                WriteIndent();
            }
            base.WriteDocType( name, pubid, sysid, subset );
        }

        public override void WriteStartElement( string prefix, string localName, string ns ) {
            Debug.Assert( localName != null && localName.Length != 0 && prefix != null && ns != null );

            // Add indentation
            if ( !mixedContent && base.textPos != base.bufPos) {
                WriteIndent();
            }
            indentLevel++;
            mixedContentStack.PushBit( mixedContent );

            base.WriteStartElement( prefix, localName, ns );
        }

        internal override void StartElementContent() {
            // If this is the root element and we're writing a document
            //   do not inherit the mixedContent flag into the root element.
            //   This is to allow for whitespace nodes on root level
            //   without disabling indentation for the whole document.
            if (indentLevel == 1 && conformanceLevel == ConformanceLevel.Document) {
                mixedContent = false;
            }
            else {
                mixedContent = mixedContentStack.PeekBit();
            }
            base.StartElementContent();
        }

        internal override void OnRootElement(ConformanceLevel currentConformanceLevel) { 
            // Just remember the current conformance level
            conformanceLevel = currentConformanceLevel;
        }

        internal override void WriteEndElement(string prefix, string localName, string ns) {
            // Add indentation
            indentLevel--;
            if ( !mixedContent && base.contentPos != base.bufPos ) {
                // There was content, so try to indent
                if ( base.textPos != base.bufPos ) {
                    WriteIndent();
                }
            }
            mixedContent = mixedContentStack.PopBit();

            base.WriteEndElement( prefix, localName, ns );
        }

        internal override void WriteFullEndElement(string prefix, string localName, string ns) {
            // Add indentation
            indentLevel--;
            if ( !mixedContent && base.contentPos != base.bufPos ) {
                // There was content, so try to indent
                if ( base.textPos != base.bufPos ) {
                    WriteIndent();
                }
            }
            mixedContent = mixedContentStack.PopBit();

            base.WriteFullEndElement( prefix, localName, ns );
        }

        // Same as base class, plus possible indentation.
        public override void WriteStartAttribute( string prefix, string localName, string ns ) {
            // Add indentation
            if ( newLineOnAttributes ) {
                WriteIndent();
            }

            base.WriteStartAttribute( prefix, localName, ns );
        }

        public override void WriteCData( string text ) {
            mixedContent = true;
            base.WriteCData( text );
        }
    
        public override void WriteComment( string text ) {
            if ( !mixedContent && base.textPos != base.bufPos ) {
                WriteIndent();
            }

            base.WriteComment( text );
        }

        public override void WriteProcessingInstruction( string target, string text ) {
            if ( !mixedContent && base.textPos != base.bufPos ) {
                WriteIndent();
            }

            base.WriteProcessingInstruction( target, text );
        }

        public override void WriteEntityRef( string name ) {
            mixedContent = true;
            base.WriteEntityRef( name );
        }

        public override void WriteCharEntity( char ch ) {
            mixedContent = true;
            base.WriteCharEntity( ch );
        }

        public override void WriteSurrogateCharEntity( char lowChar, char highChar ) {
            mixedContent = true;
            base.WriteSurrogateCharEntity( lowChar, highChar );
        }

        public override void WriteWhitespace( string ws ) {
            mixedContent = true;
            base.WriteWhitespace( ws );
        }

        public override void WriteString( string text ) {
            mixedContent = true;
            base.WriteString( text );
        }

        public override void WriteChars( char[] buffer, int index, int count ) {
            mixedContent = true;
            base.WriteChars( buffer, index, count );
        }

        public override void WriteRaw( char[] buffer, int index, int count ) {
            mixedContent = true;
            base.WriteRaw( buffer, index, count );
        }

        public override void WriteRaw( string data ) {
            mixedContent = true;
            base.WriteRaw( data );
        }

        public override void WriteBase64( byte[] buffer, int index, int count ) {
            mixedContent = true;
            base.WriteBase64( buffer, index, count );
        }

//
// Private methods
//
        private void Init( XmlWriterSettings settings ) {
            indentLevel = 0;
            indentChars = settings.IndentChars;
            newLineOnAttributes = settings.NewLineOnAttributes;
            mixedContentStack = new BitStack();

            // check indent characters that they are valid XML characters
            if ( base.checkCharacters ) {
                if ( newLineOnAttributes ) {
                    base.ValidateContentChars( indentChars, "IndentChars", true );
                    base.ValidateContentChars( newLineChars, "NewLineChars", true );
                }
                else {
                    base.ValidateContentChars( indentChars, "IndentChars", false );
                    if ( base.newLineHandling != NewLineHandling.Replace ) {
                        base.ValidateContentChars( newLineChars, "NewLineChars", false );
                    }
                }
            }
        }

        // Add indentation to output.  Write newline and then repeat IndentChars for each indent level.
        private void WriteIndent() {
            RawText( base.newLineChars );
            for ( int i = indentLevel; i > 0; i-- ) {
                RawText( indentChars );
            }
        }
    }
}