Example #1
0
 private void SetupReadContentAsBinaryState(ParsingFunction inReadBinaryFunction)
 {
     if (_parsingFunction == ParsingFunction.PartialTextValue)
     {
         _incReadState = IncrementalReadState.ReadContentAsBinary_OnPartialValue;
     }
     else
     {
         _incReadState = IncrementalReadState.ReadContentAsBinary_OnCachedValue;
         _nextNextParsingFunction = _nextParsingFunction;
         _nextParsingFunction = _parsingFunction;
     }
     _readValueOffset = 0;
     _parsingFunction = inReadBinaryFunction;
 }
Example #2
0
        private int ReadContentAsBinary(byte[] buffer, int index, int count)
        {
            Debug.Assert(_incReadDecoder != null);

            if (_incReadState == IncrementalReadState.ReadContentAsBinary_End)
            {
                return 0;
            }

            _incReadDecoder.SetNextOutputBuffer(buffer, index, count);

            for (; ;)
            {
                // read what is already cached in curNode
                int charsRead = 0;
                try
                {
                    charsRead = _curNode.CopyToBinary(_incReadDecoder, _readValueOffset);
                }
                // add line info to the exception
                catch (XmlException e)
                {
                    _curNode.AdjustLineInfo(_readValueOffset, _ps.eolNormalized, ref _incReadLineInfo);
                    ReThrow(e, _incReadLineInfo.lineNo, _incReadLineInfo.linePos);
                }
                _readValueOffset += charsRead;

                if (_incReadDecoder.IsFull)
                {
                    return _incReadDecoder.DecodedCount;
                }

                // if on partial value, read the rest of it
                if (_incReadState == IncrementalReadState.ReadContentAsBinary_OnPartialValue)
                {
                    _curNode.SetValue(string.Empty);

                    // read next chunk of text
                    bool endOfValue = false;
                    int startPos = 0;
                    int endPos = 0;
                    while (!_incReadDecoder.IsFull && !endOfValue)
                    {
                        int orChars = 0;

                        // store current line info and parse more text
                        _incReadLineInfo.Set(_ps.LineNo, _ps.LinePos);
                        endOfValue = ParseText(out startPos, out endPos, ref orChars);

                        try
                        {
                            charsRead = _incReadDecoder.Decode(_ps.chars, startPos, endPos - startPos);
                        }
                        // add line info to the exception
                        catch (XmlException e)
                        {
                            ReThrow(e, _incReadLineInfo.lineNo, _incReadLineInfo.linePos);
                        }
                        startPos += charsRead;
                    }
                    _incReadState = endOfValue ? IncrementalReadState.ReadContentAsBinary_OnCachedValue : IncrementalReadState.ReadContentAsBinary_OnPartialValue;
                    _readValueOffset = 0;

                    if (_incReadDecoder.IsFull)
                    {
                        _curNode.SetValue(_ps.chars, startPos, endPos - startPos);
                        // adjust line info for the chunk that has been already decoded
                        AdjustLineInfo(_ps.chars, startPos - charsRead, startPos, _ps.eolNormalized, ref _incReadLineInfo);
                        _curNode.SetLineInfo(_incReadLineInfo.lineNo, _incReadLineInfo.linePos);
                        return _incReadDecoder.DecodedCount;
                    }
                }

                // reset to normal state so we can call Read() to move forward
                ParsingFunction tmp = _parsingFunction;
                _parsingFunction = _nextParsingFunction;
                _nextParsingFunction = _nextNextParsingFunction;

                // move to next textual node in the element content; throw on sub elements
                if (!MoveToNextContentNode(true))
                {
                    SetupReadContentAsBinaryState(tmp);
                    _incReadState = IncrementalReadState.ReadContentAsBinary_End;
                    return _incReadDecoder.DecodedCount;
                }
                SetupReadContentAsBinaryState(tmp);
                _incReadLineInfo.Set(_curNode.LineNo, _curNode.LinePos);
            }
        }
Example #3
0
        private void InitIncrementalRead(IncrementalReadDecoder decoder)
        {
            ResetAttributes();

            decoder.Reset();
            _incReadDecoder = decoder;
            _incReadState = IncrementalReadState.Text;
            _incReadDepth = 1;
            _incReadLeftStartPos = _ps.charPos;
            _incReadLeftEndPos = _ps.charPos;
            _incReadLineInfo.Set(_ps.LineNo, _ps.LinePos);

            _parsingFunction = ParsingFunction.InIncrementalRead;
        }
Example #4
0
        private int IncrementalRead()
        {
            int charsDecoded = 0;

        OuterContinue:
            int charsLeft = _incReadLeftEndPos - _incReadLeftStartPos;
            if (charsLeft > 0)
            {
                int count;
                try
                {
                    count = _incReadDecoder.Decode(_ps.chars, _incReadLeftStartPos, charsLeft);
                }
                catch (XmlException e)
                {
                    ReThrow(e, (int)_incReadLineInfo.lineNo, (int)_incReadLineInfo.linePos);
                    return 0;
                }
                if (count < charsLeft)
                {
                    _incReadLeftStartPos += count;
                    _incReadLineInfo.linePos += count; // we have never more then 1 line cached
                    return count;
                }
                else
                {
                    _incReadLeftStartPos = 0;
                    _incReadLeftEndPos = 0;
                    _incReadLineInfo.linePos += count;
                    if (_incReadDecoder.IsFull)
                    {
                        return count;
                    }
                }
            }

            int startPos = 0;
            int pos = 0;

            for (;;)
            {
                switch (_incReadState)
                {
                    case IncrementalReadState.Text:
                    case IncrementalReadState.Attributes:
                    case IncrementalReadState.AttributeValue:
                        break;
                    case IncrementalReadState.PI:
                        if (ParsePIValue(out startPos, out pos))
                        {
                            Debug.Assert(XmlConvert.StrEqual(_ps.chars, _ps.charPos - 2, 2, "?>"));
                            _ps.charPos -= 2;
                            _incReadState = IncrementalReadState.Text;
                        }
                        goto Append;
                    case IncrementalReadState.Comment:
                        if (ParseCDataOrComment(XmlNodeType.Comment, out startPos, out pos))
                        {
                            Debug.Assert(XmlConvert.StrEqual(_ps.chars, _ps.charPos - 3, 3, "-->"));
                            _ps.charPos -= 3;
                            _incReadState = IncrementalReadState.Text;
                        }
                        goto Append;
                    case IncrementalReadState.CDATA:
                        if (ParseCDataOrComment(XmlNodeType.CDATA, out startPos, out pos))
                        {
                            Debug.Assert(XmlConvert.StrEqual(_ps.chars, _ps.charPos - 3, 3, "]]>"));
                            _ps.charPos -= 3;
                            _incReadState = IncrementalReadState.Text;
                        }
                        goto Append;
                    case IncrementalReadState.EndElement:
                        _parsingFunction = ParsingFunction.PopElementContext;
                        _nextParsingFunction = (_index > 0 || _fragmentType != XmlNodeType.Document) ? ParsingFunction.ElementContent
                                                                                                    : ParsingFunction.DocumentContent;
                        _outerReader.Read();
                        _incReadState = IncrementalReadState.End;
                        goto case IncrementalReadState.End;
                    case IncrementalReadState.End:
                        return charsDecoded;
                    case IncrementalReadState.ReadData:
                        if (ReadData() == 0)
                        {
                            ThrowUnclosedElements();
                        }
                        _incReadState = IncrementalReadState.Text;
                        startPos = _ps.charPos;
                        pos = startPos;
                        break;
                    default:
                        Debug.Assert(false);
                        break;
                }
                Debug.Assert(_incReadState == IncrementalReadState.Text ||
                              _incReadState == IncrementalReadState.Attributes ||
                              _incReadState == IncrementalReadState.AttributeValue);

                char[] chars = _ps.chars;
                startPos = _ps.charPos;
                pos = startPos;

                for (;;)
                {
                    _incReadLineInfo.Set(_ps.LineNo, _ps.LinePos);

                    char c;
                    unsafe
                    {
                        if (_incReadState == IncrementalReadState.Attributes)
                        {
                            while (_xmlCharType.IsAttributeValueChar(c = chars[pos]) && c != '/')
                            {
                                pos++;
                            }
                        }
                        else
                        {
                            while (_xmlCharType.IsAttributeValueChar(c = chars[pos]))
                            {
                                pos++;
                            }
                        }
                    }

                    if (chars[pos] == '&' || chars[pos] == (char)0x9)
                    {
                        pos++;
                        continue;
                    }

                    if (pos - startPos > 0)
                    {
                        goto AppendAndUpdateCharPos;
                    }

                    switch (chars[pos])
                    {
                        // eol
                        case (char)0xA:
                            pos++;
                            OnNewLine(pos);
                            continue;
                        case (char)0xD:
                            if (chars[pos + 1] == (char)0xA)
                            {
                                pos += 2;
                            }
                            else if (pos + 1 < _ps.charsUsed)
                            {
                                pos++;
                            }
                            else
                            {
                                goto ReadData;
                            }
                            OnNewLine(pos);
                            continue;
                        // some tag 
                        case '<':
                            if (_incReadState != IncrementalReadState.Text)
                            {
                                pos++;
                                continue;
                            }
                            if (_ps.charsUsed - pos < 2)
                            {
                                goto ReadData;
                            }
                            switch (chars[pos + 1])
                            {
                                // pi
                                case '?':
                                    pos += 2;
                                    _incReadState = IncrementalReadState.PI;
                                    goto AppendAndUpdateCharPos;
                                // comment
                                case '!':
                                    if (_ps.charsUsed - pos < 4)
                                    {
                                        goto ReadData;
                                    }
                                    if (chars[pos + 2] == '-' && chars[pos + 3] == '-')
                                    {
                                        pos += 4;
                                        _incReadState = IncrementalReadState.Comment;
                                        goto AppendAndUpdateCharPos;
                                    }
                                    if (_ps.charsUsed - pos < 9)
                                    {
                                        goto ReadData;
                                    }
                                    if (XmlConvert.StrEqual(chars, pos + 2, 7, "[CDATA["))
                                    {
                                        pos += 9;
                                        _incReadState = IncrementalReadState.CDATA;
                                        goto AppendAndUpdateCharPos;
                                    }
                                    else
                                    {
                                        ;//Throw( );
                                    }
                                    break;
                                // end tag
                                case '/':
                                    {
                                        Debug.Assert(_ps.charPos - pos == 0);
                                        Debug.Assert(_ps.charPos - startPos == 0);

                                        int colonPos;
                                        // ParseQName can flush the buffer, so we need to update the startPos, pos and chars after calling it
                                        int endPos = ParseQName(true, 2, out colonPos);
                                        if (XmlConvert.StrEqual(chars, _ps.charPos + 2, endPos - _ps.charPos - 2, _curNode.GetNameWPrefix(_nameTable)) &&
                                            (_ps.chars[endPos] == '>' || _xmlCharType.IsWhiteSpace(_ps.chars[endPos])))
                                        {
                                            if (--_incReadDepth > 0)
                                            {
                                                pos = endPos + 1;
                                                continue;
                                            }

                                            _ps.charPos = endPos;
                                            if (_xmlCharType.IsWhiteSpace(_ps.chars[endPos]))
                                            {
                                                EatWhitespaces(null);
                                            }
                                            if (_ps.chars[_ps.charPos] != '>')
                                            {
                                                ThrowUnexpectedToken(">");
                                            }
                                            _ps.charPos++;

                                            _incReadState = IncrementalReadState.EndElement;
                                            goto OuterContinue;
                                        }
                                        else
                                        {
                                            pos = endPos;
                                            startPos = _ps.charPos;
                                            chars = _ps.chars;
                                            continue;
                                        }
                                    }
                                // start tag
                                default:
                                    {
                                        Debug.Assert(_ps.charPos - pos == 0);
                                        Debug.Assert(_ps.charPos - startPos == 0);

                                        int colonPos;
                                        // ParseQName can flush the buffer, so we need to update the startPos, pos and chars after calling it
                                        int endPos = ParseQName(true, 1, out colonPos);
                                        if (XmlConvert.StrEqual(_ps.chars, _ps.charPos + 1, endPos - _ps.charPos - 1, _curNode.localName) &&
                                            (_ps.chars[endPos] == '>' || _ps.chars[endPos] == '/' || _xmlCharType.IsWhiteSpace(_ps.chars[endPos])))
                                        {
                                            _incReadDepth++;
                                            _incReadState = IncrementalReadState.Attributes;
                                            pos = endPos;
                                            goto AppendAndUpdateCharPos;
                                        }
                                        pos = endPos;
                                        startPos = _ps.charPos;
                                        chars = _ps.chars;
                                        continue;
                                    }
                            }
                            break;
                        // end of start tag
                        case '/':
                            if (_incReadState == IncrementalReadState.Attributes)
                            {
                                if (_ps.charsUsed - pos < 2)
                                {
                                    goto ReadData;
                                }
                                if (chars[pos + 1] == '>')
                                {
                                    _incReadState = IncrementalReadState.Text;
                                    _incReadDepth--;
                                }
                            }
                            pos++;
                            continue;
                        // end of start tag
                        case '>':
                            if (_incReadState == IncrementalReadState.Attributes)
                            {
                                _incReadState = IncrementalReadState.Text;
                            }
                            pos++;
                            continue;
                        case '"':
                        case '\'':
                            switch (_incReadState)
                            {
                                case IncrementalReadState.AttributeValue:
                                    if (chars[pos] == _curNode.quoteChar)
                                    {
                                        _incReadState = IncrementalReadState.Attributes;
                                    }
                                    break;
                                case IncrementalReadState.Attributes:
                                    _curNode.quoteChar = chars[pos];
                                    _incReadState = IncrementalReadState.AttributeValue;
                                    break;
                            }
                            pos++;
                            continue;
                        default:
                            // end of buffer
                            if (pos == _ps.charsUsed)
                            {
                                goto ReadData;
                            }
                            // surrogate chars or invalid chars are ignored
                            else
                            {
                                pos++;
                                continue;
                            }
                    }
                }

            ReadData:
                _incReadState = IncrementalReadState.ReadData;

            AppendAndUpdateCharPos:
                _ps.charPos = pos;

            Append:
                // decode characters
                int charsParsed = pos - startPos;
                if (charsParsed > 0)
                {
                    int count;
                    try
                    {
                        count = _incReadDecoder.Decode(_ps.chars, startPos, charsParsed);
                    }
                    catch (XmlException e)
                    {
                        ReThrow(e, (int)_incReadLineInfo.lineNo, (int)_incReadLineInfo.linePos);
                        return 0;
                    }
                    Debug.Assert(count == charsParsed || _incReadDecoder.IsFull, "Check if decoded consumed all characters unless it's full.");
                    charsDecoded += count;
                    if (_incReadDecoder.IsFull)
                    {
                        _incReadLeftStartPos = startPos + count;
                        _incReadLeftEndPos = pos;
                        _incReadLineInfo.linePos += count; // we have never more than 1 line cached
                        return charsDecoded;
                    }
                }
            }
        }
Example #5
0
        // Iterates over Value property and copies it into the provided buffer
        public override int ReadValueChunk(char[] buffer, int index, int count)
        {
            // throw on elements
            if (!XmlReader.HasValueInternal(_curNode.type))
            {
                throw new InvalidOperationException(SR.Format(SR.Xml_InvalidReadValueChunk, _curNode.type));
            }
            // check arguments
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(count));
            }
            if (index < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(index));
            }
            if (buffer.Length - index < count)
            {
                throw new ArgumentOutOfRangeException(nameof(count));
            }

            // first call of ReadValueChunk -> initialize incremental read state
            if (_parsingFunction != ParsingFunction.InReadValueChunk)
            {
                if (_readState != ReadState.Interactive)
                {
                    return 0;
                }
                if (_parsingFunction == ParsingFunction.PartialTextValue)
                {
                    _incReadState = IncrementalReadState.ReadValueChunk_OnPartialValue;
                }
                else
                {
                    _incReadState = IncrementalReadState.ReadValueChunk_OnCachedValue;
                    _nextNextParsingFunction = _nextParsingFunction;
                    _nextParsingFunction = _parsingFunction;
                }
                _parsingFunction = ParsingFunction.InReadValueChunk;
                _readValueOffset = 0;
            }

            if (count == 0)
            {
                return 0;
            }

            // read what is already cached in curNode
            int readCount = 0;
            int read = _curNode.CopyTo(_readValueOffset, buffer, index + readCount, count - readCount);
            readCount += read;
            _readValueOffset += read;

            if (readCount == count)
            {
                // take care of surrogate pairs spanning between buffers
                char ch = buffer[index + count - 1];
                if (XmlCharType.IsHighSurrogate(ch))
                {
                    readCount--;
                    _readValueOffset--;
                    if (readCount == 0)
                    {
                        Throw(SR.Xml_NotEnoughSpaceForSurrogatePair);
                    }
                }
                return readCount;
            }

            // if on partial value, read the rest of it
            if (_incReadState == IncrementalReadState.ReadValueChunk_OnPartialValue)
            {
                _curNode.SetValue(string.Empty);

                // read next chunk of text
                bool endOfValue = false;
                int startPos = 0;
                int endPos = 0;
                while (readCount < count && !endOfValue)
                {
                    int orChars = 0;
                    endOfValue = ParseText(out startPos, out endPos, ref orChars);

                    int copyCount = count - readCount;
                    if (copyCount > endPos - startPos)
                    {
                        copyCount = endPos - startPos;
                    }
                    BlockCopyChars(_ps.chars, startPos, buffer, (index + readCount), copyCount);

                    readCount += copyCount;
                    startPos += copyCount;
                }

                _incReadState = endOfValue ? IncrementalReadState.ReadValueChunk_OnCachedValue : IncrementalReadState.ReadValueChunk_OnPartialValue;

                if (readCount == count)
                {
                    char ch = buffer[index + count - 1];
                    if (XmlCharType.IsHighSurrogate(ch))
                    {
                        readCount--;
                        startPos--;
                        if (readCount == 0)
                        {
                            Throw(SR.Xml_NotEnoughSpaceForSurrogatePair);
                        }
                    }
                }

                _readValueOffset = 0;
                _curNode.SetValue(_ps.chars, startPos, endPos - startPos);
            }
            return readCount;
        }
Example #6
0
 private void FinishOtherValueIterator()
 {
     switch (_parsingFunction)
     {
         case ParsingFunction.InReadAttributeValue:
             // do nothing, correct value is already in curNode
             break;
         case ParsingFunction.InReadValueChunk:
             if (_incReadState == IncrementalReadState.ReadValueChunk_OnPartialValue)
             {
                 FinishPartialValue();
                 _incReadState = IncrementalReadState.ReadValueChunk_OnCachedValue;
             }
             else
             {
                 if (_readValueOffset > 0)
                 {
                     _curNode.SetValue(_curNode.StringValue.Substring(_readValueOffset));
                     _readValueOffset = 0;
                 }
             }
             break;
         case ParsingFunction.InReadContentAsBinary:
         case ParsingFunction.InReadElementContentAsBinary:
             switch (_incReadState)
             {
                 case IncrementalReadState.ReadContentAsBinary_OnPartialValue:
                     FinishPartialValue();
                     _incReadState = IncrementalReadState.ReadContentAsBinary_OnCachedValue;
                     break;
                 case IncrementalReadState.ReadContentAsBinary_OnCachedValue:
                     if (_readValueOffset > 0)
                     {
                         _curNode.SetValue(_curNode.StringValue.Substring(_readValueOffset));
                         _readValueOffset = 0;
                     }
                     break;
                 case IncrementalReadState.ReadContentAsBinary_End:
                     _curNode.SetValue(string.Empty);
                     break;
             }
             break;
     }
 }
Example #7
0
        private void ParseDtdFromParserContext() {
            Debug.Assert( dtdInfo == null && fragmentParserContext != null && fragmentParserContext.HasDtdInfo );

            IDtdParser dtdParser = DtdParser.Create();

            // Parse DTD
            dtdInfo = dtdParser.ParseFreeFloatingDtd(fragmentParserContext.BaseURI, fragmentParserContext.DocTypeName, fragmentParserContext.PublicId,
                                                     fragmentParserContext.SystemId, fragmentParserContext.InternalSubset, new DtdParserProxy( this ) );

#if SILVERLIGHT // Needed only for XmlTextReader or XmlValidatingReader
            if (dtdInfo.HasDefaultAttributes || dtdInfo.HasNonCDataAttributes) {
#else
            if ( ( validatingReaderCompatFlag || !v1Compat ) && ( dtdInfo.HasDefaultAttributes || dtdInfo.HasNonCDataAttributes ) ) {
#endif
                addDefaultAttributesAndNormalize = true;
            }
        }

        bool InitReadContentAsBinary() {
            Debug.Assert( parsingFunction != ParsingFunction.InReadContentAsBinary );

            if ( parsingFunction == ParsingFunction.InReadValueChunk ) {
                throw new InvalidOperationException( Res.GetString( Res.Xml_MixingReadValueChunkWithBinary ) );
            }
            if ( parsingFunction == ParsingFunction.InIncrementalRead ) {
                throw new InvalidOperationException( Res.GetString( Res.Xml_MixingV1StreamingWithV2Binary ) );
            }

            if ( !XmlReader.IsTextualNode( curNode.type ) ) {
                if ( !MoveToNextContentNode( false ) ) {
                    return false;
                }
            }

            SetupReadContentAsBinaryState( ParsingFunction.InReadContentAsBinary );
            incReadLineInfo.Set( curNode.LineNo, curNode.LinePos );
            return true;
        }

        bool InitReadElementContentAsBinary() {
            Debug.Assert( parsingFunction != ParsingFunction.InReadElementContentAsBinary );
            Debug.Assert( curNode.type == XmlNodeType.Element );

            bool isEmpty = curNode.IsEmptyElement;

            // move to content or off the empty element
            outerReader.Read();
            if ( isEmpty ) {
                return false;
            }

            // make sure we are on a content node
            if ( !MoveToNextContentNode( false ) ) {
                if ( curNode.type != XmlNodeType.EndElement ) {
                    Throw( Res.Xml_InvalidNodeType, curNode.type.ToString() );
                }
                // move off end element
                outerReader.Read();
                return false;
            }
            SetupReadContentAsBinaryState( ParsingFunction.InReadElementContentAsBinary );
            incReadLineInfo.Set( curNode.LineNo, curNode.LinePos );
            return true;
        }

        bool MoveToNextContentNode( bool moveIfOnContentNode ) {
            do {
                switch ( curNode.type ) {
                    case XmlNodeType.Attribute:
                        return !moveIfOnContentNode;
                    case XmlNodeType.Text:
                    case XmlNodeType.Whitespace:
                    case XmlNodeType.SignificantWhitespace:
                    case XmlNodeType.CDATA:
                        if ( !moveIfOnContentNode ) {
                            return true;
                        }
                        break;
                    case XmlNodeType.ProcessingInstruction:
                    case XmlNodeType.Comment:
                    case XmlNodeType.EndEntity:
                        // skip comments, pis and end entity nodes
                        break;
                    case XmlNodeType.EntityReference:
                        outerReader.ResolveEntity();
                        break;
                    default:
                        return false;
                }
                moveIfOnContentNode = false;
            } while ( outerReader.Read() );
            return false;
        }

        void SetupReadContentAsBinaryState( ParsingFunction inReadBinaryFunction ) {
            if ( parsingFunction == ParsingFunction.PartialTextValue ) {
                incReadState = IncrementalReadState.ReadContentAsBinary_OnPartialValue;
            }
            else {
                incReadState = IncrementalReadState.ReadContentAsBinary_OnCachedValue;
                nextNextParsingFunction = nextParsingFunction;
                nextParsingFunction = parsingFunction;
            }
            readValueOffset = 0;
            parsingFunction = inReadBinaryFunction;
        }

        void SetupFromParserContext( XmlParserContext context, XmlReaderSettings settings ) {
            Debug.Assert( context != null );

            // setup nameTable
            XmlNameTable nt = settings.NameTable;
            nameTableFromSettings = ( nt != null );

            // get name table from namespace manager in XmlParserContext, if available; 
            if ( context.NamespaceManager != null ) {
                // must be the same as XmlReaderSettings.NameTable, or null
                if ( nt != null && nt != context.NamespaceManager.NameTable ) {
                    throw new XmlException( Res.Xml_NametableMismatch );
                }
                // get the namespace manager from context
                namespaceManager = context.NamespaceManager;
                xmlContext.defaultNamespace = namespaceManager.LookupNamespace( string.Empty );

                // get the nametable from ns manager
                nt = namespaceManager.NameTable;

                Debug.Assert( nt != null );
                Debug.Assert( context.NameTable == null || context.NameTable == nt, "This check should have been done in XmlParserContext constructor." );
            } 
            // get name table directly from XmlParserContext
            else if ( context.NameTable != null ) {
                // must be the same as XmlReaderSettings.NameTable, or null
                if ( nt != null && nt != context.NameTable ) {
                    throw new XmlException( Res.Xml_NametableMismatch, string.Empty );
                }
                nt = context.NameTable;
            }
            // no nametable provided -> create a new one
            else if ( nt == null ) {
                nt = new NameTable();
                Debug.Assert( nameTableFromSettings == false );
            }
            nameTable = nt;

            // make sure we have namespace manager
            if ( namespaceManager == null ) {
                namespaceManager = new XmlNamespaceManager( nt );
            }

            // copy xml:space and xml:lang
            xmlContext.xmlSpace = context.XmlSpace;
            xmlContext.xmlLang = context.XmlLang;
        }
 void SetupReadContentAsBinaryState( ParsingFunction inReadBinaryFunction ) {
     if ( parsingFunction == ParsingFunction.PartialTextValue ) {
         incReadState = IncrementalReadState.ReadContentAsBinary_OnPartialValue;
     }
     else {
         incReadState = IncrementalReadState.ReadContentAsBinary_OnCachedValue;
         nextNextParsingFunction = nextParsingFunction;
         nextParsingFunction = parsingFunction;
     }
     readValueOffset = 0;
     parsingFunction = inReadBinaryFunction;
 }
        // Iterates over Value property and copies it into the provided buffer
        public override int ReadValueChunk( char[] buffer, int index, int count ) {
            // throw on elements
            if ( !XmlReader.HasValueInternal( curNode.type ) ) {
                throw new InvalidOperationException( Res.GetString( Res.Xml_InvalidReadValueChunk, curNode.type ) ) ;
            }
            // 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" );
            }

            // first call of ReadValueChunk -> initialize incremental read state
            if ( parsingFunction != ParsingFunction.InReadValueChunk ) {
                if ( readState != ReadState.Interactive ) {
                    return 0;
                }
                if ( parsingFunction == ParsingFunction.PartialTextValue ) {
                    incReadState = IncrementalReadState.ReadValueChunk_OnPartialValue;
                }
                else {
                    incReadState = IncrementalReadState.ReadValueChunk_OnCachedValue;
                    nextNextParsingFunction = nextParsingFunction;
                    nextParsingFunction = parsingFunction;
                }
                parsingFunction = ParsingFunction.InReadValueChunk;
                readValueOffset = 0;
            }

            if ( count == 0 ) {
                return 0;
            }

            // read what is already cached in curNode
            int readCount = 0;
            int read = curNode.CopyTo( readValueOffset, buffer, index + readCount, count - readCount );
            readCount += read;
            readValueOffset += read;

            if ( readCount == count ) {
                // take care of suppogate pairs spanning between buffers
                char ch = buffer[index + count - 1];
                if ( ch >= SurHighStart && ch <= SurHighEnd ) {
                    readCount--;
                    readValueOffset--;
                    if ( readCount == 0 ) {
                        Throw( Res.Xml_NotEnoughSpaceForSurrogatePair );
                    }
                }
                return readCount;
            }

            // if on partial value, read the rest of it
            if ( incReadState == IncrementalReadState.ReadValueChunk_OnPartialValue ) {
                curNode.SetValue( string.Empty );

                // read next chunk of text
                bool endOfValue = false;
                int startPos = 0;
                int endPos = 0;
                while ( readCount < count && !endOfValue ) {
                    int orChars = 0;
                    endOfValue = ParseText( out startPos, out endPos, ref orChars );

                    int copyCount = count - readCount;
                    if ( copyCount > endPos - startPos ) {
                        copyCount = endPos - startPos;
                    }
                    Buffer.BlockCopy( ps.chars, startPos * 2, buffer, ( index + readCount ) * 2, copyCount * 2 ); 

                    readCount += copyCount;
                    startPos += copyCount;
                }

				incReadState = endOfValue ? IncrementalReadState.ReadValueChunk_OnCachedValue : IncrementalReadState.ReadValueChunk_OnPartialValue;

                if ( readCount == count ) {
                    char ch = buffer[index + count - 1];
                    if ( ch >= SurHighStart && ch <= SurHighEnd ) {
                        readCount--;
                        startPos--;
                        if ( readCount == 0 ) {
                            Throw( Res.Xml_NotEnoughSpaceForSurrogatePair );
                        }
                    }
                }

                readValueOffset = 0;
                curNode.SetValue( ps.chars, startPos, endPos - startPos );
            }
            return readCount;
        }
Example #10
0
        // Iterates over Value property and copies it into the provided buffer
        public override int ReadValueChunk(char[] buffer, int index, int count)
        {
            // throw on elements
            if (!XmlReader.HasValueInternal(curNode.type))
            {
                throw new InvalidOperationException(Res.GetString(Res.Xml_InvalidReadValueChunk, curNode.type));
            }

            // 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");
            }

            // first call of ReadValueChunk -> initialize incremental read state
            if (parsingFunction != ParsingFunction.InReadValueChunk)
            {
                if (readState != ReadState.Interactive)
                {
                    return 0;
                }

                if (parsingFunction == ParsingFunction.PartialTextValue)
                {
                    incReadState = IncrementalReadState.ReadValueChunk_OnPartialValue;
                }
                else
                {
                    incReadState = IncrementalReadState.ReadValueChunk_OnCachedValue;
                    nextNextParsingFunction = nextParsingFunction;
                    nextParsingFunction = parsingFunction;
                }

                parsingFunction = ParsingFunction.InReadValueChunk;
                readValueOffset = 0;
            }

            // read what is already cached in curNode
            int readCount = 0;
            int read = curNode.CopyTo(readValueOffset, buffer, index + readCount, count - readCount);
            readCount += read;
            readValueOffset += read;

            if (readCount == count)
            {
                return readCount;
            }

            // if on partial value, read the rest of it
            if (incReadState == IncrementalReadState.ReadValueChunk_OnPartialValue)
            {
                curNode.SetValue("");

                // read next chunk of text
                bool endOfValue = false;
                int startPos = 0;
                int endPos = 0;
                while (readCount < count && !endOfValue)
                {
                    int orChars = 0;
                    endOfValue = ParseText(out startPos, out endPos, ref orChars);

                    int copyCount = count - readCount;
                    if (copyCount > endPos - startPos)
                    {
                        copyCount = endPos - startPos;
                    }

                    Array.Copy(ps.chars, startPos, buffer, (index + readCount), copyCount);

                    readCount += copyCount;
                    startPos += copyCount;
                }

                incReadState = endOfValue ? IncrementalReadState.ReadValueChunk_OnCachedValue : IncrementalReadState.ReadValueChunk_OnPartialValue;
                readValueOffset = 0;

                curNode.SetValue(ps.chars, startPos, endPos - startPos);
            }

            return readCount;
        }
Example #11
0
 void FinishOtherValueIterator()
 {
     switch (parsingFunction)
     {
         case ParsingFunction.InReadAttributeValue:
             // do nothing, correct value is already in curNode
             break;
         case ParsingFunction.InReadValueChunk:
             if (incReadState == IncrementalReadState.ReadValueChunk_OnPartialValue)
             {
                 FinishPartialValue();
                 incReadState = IncrementalReadState.ReadValueChunk_OnCachedValue;
             }
             else
             {
                 if (readValueOffset > 0)
                 {
                     curNode.SetValue(curNode.StringValue.Substring(readValueOffset));
                     readValueOffset = 0;
                 }
             }
             break;
     }
 }