private void OnEof() { Debug.Assert(_ps.isEof); _curNode = _nodes[0]; _curNode.Clear(XmlNodeType.None); _curNode.SetLineInfo(_ps.LineNo, _ps.LinePos); _parsingFunction = ParsingFunction.Eof; _readState = ReadState.EndOfFile; _reportedEncoding = null; }
private bool ParseAttributeValueChunk() { char[] chars = _ps.chars; int pos = _ps.charPos; _curNode = AddNode(_index + _attrCount + 1, _index + 2); _curNode.SetLineInfo(_ps.LineNo, _ps.LinePos); if (_emptyEntityInAttributeResolved) { _curNode.SetValueNode(XmlNodeType.Text, string.Empty); _emptyEntityInAttributeResolved = false; return true; } Debug.Assert(_stringBuilder.Length == 0); for (;;) { unsafe { while (_xmlCharType.IsAttributeValueChar(chars[pos])) pos++; } switch (chars[pos]) { // eol D case (char)0xD: Debug.Assert(_ps.eolNormalized, "Entity replacement text for attribute values should be EOL-normalized!"); pos++; continue; // eol A, tab case (char)0xA: case (char)0x9: if (_normalize) { chars[pos] = (char)0x20; // CDATA normalization of 0xA and 0x9 } pos++; continue; case '"': case '\'': case '>': pos++; continue; // attribute values cannot contain '<' case '<': Throw(pos, SR.Xml_BadAttributeChar, XmlException.BuildCharExceptionArgs('<', '\0')); break; // entity reference case '&': if (pos - _ps.charPos > 0) { _stringBuilder.Append(chars, _ps.charPos, pos - _ps.charPos); } _ps.charPos = pos; // expand char entities but not general entities switch (HandleEntityReference(true, EntityExpandType.OnlyCharacter, out pos)) { case EntityType.CharacterDec: case EntityType.CharacterHex: case EntityType.CharacterNamed: chars = _ps.chars; if (_normalize && _xmlCharType.IsWhiteSpace(chars[_ps.charPos]) && pos - _ps.charPos == 1) { chars[_ps.charPos] = (char)0x20; // CDATA normalization of character references in entities } break; case EntityType.Unexpanded: if (_stringBuilder.Length == 0) { _curNode.lineInfo.linePos++; _ps.charPos++; _curNode.SetNamedNode(XmlNodeType.EntityReference, ParseEntityName()); return true; } else { goto ReturnText; } default: Debug.Assert(false, "We should never get to this point."); break; } chars = _ps.chars; continue; default: // end of buffer if (pos == _ps.charsUsed) { goto ReadData; } // surrogate chars else { char ch = chars[pos]; if (XmlCharType.IsHighSurrogate(ch)) { if (pos + 1 == _ps.charsUsed) { goto ReadData; } pos++; if (XmlCharType.IsLowSurrogate(chars[pos])) { pos++; continue; } } ThrowInvalidChar(chars, _ps.charsUsed, pos); break; } } ReadData: if (pos - _ps.charPos > 0) { _stringBuilder.Append(chars, _ps.charPos, pos - _ps.charPos); _ps.charPos = pos; } // read new characters into the buffer if (ReadData() == 0) { if (_stringBuilder.Length > 0) { goto ReturnText; } else { if (HandleEntityEnd(false)) { SetupEndEntityNodeInAttribute(); return true; } else { Debug.Assert(false, "We should never get to this point."); } } } pos = _ps.charPos; chars = _ps.chars; } ReturnText: if (pos - _ps.charPos > 0) { _stringBuilder.Append(chars, _ps.charPos, pos - _ps.charPos); _ps.charPos = pos; } _curNode.SetValueNode(XmlNodeType.Text, _stringBuilder.ToString()); _stringBuilder.Length = 0; return true; }
// Reset the state of the reader so the reader is ready to parse another XML document from the same stream. internal void ResetState() { Debug.Assert(_v1Compat, "XmlTextReaderImpl.ResetState cannot be called on reader created via XmlReader.Create."); if (_fragment) { Throw(new InvalidOperationException(SR.Xml_InvalidResetStateCall)); } if (_readState == ReadState.Initial) { return; } // Clear ResetAttributes(); while (_namespaceManager.PopScope()) ; while (InEntity) { HandleEntityEnd(true); } // Init _readState = ReadState.Initial; _parsingFunction = ParsingFunction.SwitchToInteractiveXmlDecl; _nextParsingFunction = ParsingFunction.DocumentContent; _curNode = _nodes[0]; _curNode.Clear(XmlNodeType.None); _curNode.SetLineInfo(0, 0); _index = 0; _rootElementParsed = false; _charactersInDocument = 0; _charactersFromEntities = 0; _afterResetState = true; }
// This constructor is used when creating XmlTextReaderImpl reader via "XmlReader.Create(..)" private XmlTextReaderImpl(XmlResolver resolver, XmlReaderSettings settings, XmlParserContext context) { _useAsync = settings.Async; _v1Compat = false; _outerReader = this; _xmlContext = new XmlContext(); // create or get nametable and namespace manager from XmlParserContext XmlNameTable nt = settings.NameTable; if (context == null) { if (nt == null) { nt = new NameTable(); Debug.Assert(_nameTableFromSettings == false); } else { _nameTableFromSettings = true; } _nameTable = nt; _namespaceManager = new XmlNamespaceManager(nt); } else { SetupFromParserContext(context, settings); nt = _nameTable; } nt.Add(string.Empty); _xml = nt.Add("xml"); _xmlNs = nt.Add("xmlns"); _xmlResolver = resolver; Debug.Assert(_index == 0); _nodes = new NodeData[NodesInitialSize]; _nodes[0] = new NodeData(); _curNode = _nodes[0]; _stringBuilder = new StringBuilder(); // Needed only for XmlTextReader (reporting of entities) _entityHandling = EntityHandling.ExpandEntities; _xmlResolverIsSet = settings.IsXmlResolverSet; _whitespaceHandling = (settings.IgnoreWhitespace) ? WhitespaceHandling.Significant : WhitespaceHandling.All; _normalize = true; _ignorePIs = settings.IgnoreProcessingInstructions; _ignoreComments = settings.IgnoreComments; _checkCharacters = settings.CheckCharacters; _lineNumberOffset = settings.LineNumberOffset; _linePositionOffset = settings.LinePositionOffset; _ps.lineNo = _lineNumberOffset + 1; _ps.lineStartPos = -_linePositionOffset - 1; _curNode.SetLineInfo(_ps.LineNo - 1, _ps.LinePos - 1); _dtdProcessing = settings.DtdProcessing; _maxCharactersInDocument = settings.MaxCharactersInDocument; _maxCharactersFromEntities = settings.MaxCharactersFromEntities; _charactersInDocument = 0; _charactersFromEntities = 0; _fragmentParserContext = context; _parsingFunction = ParsingFunction.SwitchToInteractiveXmlDecl; _nextParsingFunction = ParsingFunction.DocumentContent; switch (settings.ConformanceLevel) { case ConformanceLevel.Auto: _fragmentType = XmlNodeType.None; _fragment = true; break; case ConformanceLevel.Fragment: _fragmentType = XmlNodeType.Element; _fragment = true; break; case ConformanceLevel.Document: _fragmentType = XmlNodeType.Document; break; default: Debug.Assert(false); goto case ConformanceLevel.Document; } }
// Reads next node from the input data public override bool Read() { if (_laterInitParam != null) { FinishInit(); } for (;;) { switch (_parsingFunction) { case ParsingFunction.ElementContent: return ParseElementContent(); case ParsingFunction.DocumentContent: return ParseDocumentContent(); case ParsingFunction.OpenUrl: OpenUrl(); Debug.Assert(_nextParsingFunction == ParsingFunction.DocumentContent); goto case ParsingFunction.SwitchToInteractiveXmlDecl; case ParsingFunction.SwitchToInteractive: Debug.Assert(!_ps.appendMode); _readState = ReadState.Interactive; _parsingFunction = _nextParsingFunction; continue; case ParsingFunction.SwitchToInteractiveXmlDecl: _readState = ReadState.Interactive; _parsingFunction = _nextParsingFunction; if (ParseXmlDeclaration(false)) { _reportedEncoding = _ps.encoding; return true; } _reportedEncoding = _ps.encoding; continue; case ParsingFunction.ResetAttributesRootLevel: ResetAttributes(); _curNode = _nodes[_index]; _parsingFunction = (_index == 0) ? ParsingFunction.DocumentContent : ParsingFunction.ElementContent; continue; case ParsingFunction.MoveToElementContent: ResetAttributes(); _index++; _curNode = AddNode(_index, _index); _parsingFunction = ParsingFunction.ElementContent; continue; case ParsingFunction.PopElementContext: PopElementContext(); _parsingFunction = _nextParsingFunction; Debug.Assert(_parsingFunction == ParsingFunction.ElementContent || _parsingFunction == ParsingFunction.DocumentContent); continue; case ParsingFunction.PopEmptyElementContext: _curNode = _nodes[_index]; Debug.Assert(_curNode.type == XmlNodeType.Element); _curNode.IsEmptyElement = false; ResetAttributes(); PopElementContext(); _parsingFunction = _nextParsingFunction; continue; case ParsingFunction.EntityReference: _parsingFunction = _nextParsingFunction; ParseEntityReference(); return true; case ParsingFunction.ReportEndEntity: SetupEndEntityNodeInContent(); _parsingFunction = _nextParsingFunction; return true; case ParsingFunction.AfterResolveEntityInContent: _curNode = AddNode(_index, _index); _reportedEncoding = _ps.encoding; _reportedBaseUri = _ps.baseUriStr; _parsingFunction = _nextParsingFunction; continue; case ParsingFunction.AfterResolveEmptyEntityInContent: _curNode = AddNode(_index, _index); _curNode.SetValueNode(XmlNodeType.Text, string.Empty); _curNode.SetLineInfo(_ps.lineNo, _ps.LinePos); _reportedEncoding = _ps.encoding; _reportedBaseUri = _ps.baseUriStr; _parsingFunction = _nextParsingFunction; return true; case ParsingFunction.InReadAttributeValue: FinishAttributeValueIterator(); _curNode = _nodes[_index]; continue; case ParsingFunction.InIncrementalRead: FinishIncrementalRead(); return true; case ParsingFunction.FragmentAttribute: return ParseFragmentAttribute(); case ParsingFunction.XmlDeclarationFragment: ParseXmlDeclarationFragment(); _parsingFunction = ParsingFunction.GoToEof; return true; case ParsingFunction.GoToEof: OnEof(); return false; case ParsingFunction.Error: case ParsingFunction.Eof: case ParsingFunction.ReaderClosed: return false; case ParsingFunction.NoData: ThrowWithoutLineInfo(SR.Xml_MissingRoot); return false; case ParsingFunction.PartialTextValue: SkipPartialTextValue(); continue; case ParsingFunction.InReadValueChunk: FinishReadValueChunk(); continue; case ParsingFunction.InReadContentAsBinary: FinishReadContentAsBinary(); continue; case ParsingFunction.InReadElementContentAsBinary: FinishReadElementContentAsBinary(); continue; default: Debug.Assert(false); break; } } }
// Reads next node from the input data public override bool Read() { if (laterInitParam != null) { FinishInit(); } for (;;) { switch ( parsingFunction ) { case ParsingFunction.ElementContent: return ParseElementContent(); case ParsingFunction.DocumentContent: return ParseDocumentContent(); #if !SILVERLIGHT // Needed only for XmlTextReader case ParsingFunction.OpenUrl: OpenUrl(); Debug.Assert( nextParsingFunction == ParsingFunction.DocumentContent ); goto case ParsingFunction.SwitchToInteractiveXmlDecl; #endif case ParsingFunction.SwitchToInteractive: Debug.Assert( !ps.appendMode ); readState = ReadState.Interactive; parsingFunction = nextParsingFunction; continue; case ParsingFunction.SwitchToInteractiveXmlDecl: readState = ReadState.Interactive; parsingFunction = nextParsingFunction; if ( ParseXmlDeclaration( false ) ) { reportedEncoding = ps.encoding; return true; } reportedEncoding = ps.encoding; continue; case ParsingFunction.ResetAttributesRootLevel: ResetAttributes(); curNode = nodes[index]; parsingFunction = ( index == 0 ) ? ParsingFunction.DocumentContent : ParsingFunction.ElementContent; continue; case ParsingFunction.MoveToElementContent: ResetAttributes(); index++; curNode = AddNode( index, index ); parsingFunction = ParsingFunction.ElementContent; continue; case ParsingFunction.PopElementContext: PopElementContext(); parsingFunction = nextParsingFunction; Debug.Assert( parsingFunction == ParsingFunction.ElementContent || parsingFunction == ParsingFunction.DocumentContent ); continue; case ParsingFunction.PopEmptyElementContext: curNode = nodes[index]; Debug.Assert( curNode.type == XmlNodeType.Element ); curNode.IsEmptyElement = false; ResetAttributes(); PopElementContext(); parsingFunction = nextParsingFunction; continue; #if !SILVERLIGHT // Needed only for XmlTextReader (reporting of entities) case ParsingFunction.EntityReference: parsingFunction = nextParsingFunction; ParseEntityReference(); return true; case ParsingFunction.ReportEndEntity: SetupEndEntityNodeInContent(); parsingFunction = nextParsingFunction; return true; case ParsingFunction.AfterResolveEntityInContent: curNode = AddNode( index, index ); reportedEncoding = ps.encoding; reportedBaseUri = ps.baseUriStr; parsingFunction = nextParsingFunction; continue; case ParsingFunction.AfterResolveEmptyEntityInContent: curNode = AddNode( index, index ); curNode.SetValueNode( XmlNodeType.Text, string.Empty ); curNode.SetLineInfo( ps.lineNo, ps.LinePos ); reportedEncoding = ps.encoding; reportedBaseUri = ps.baseUriStr; parsingFunction = nextParsingFunction; return true; #endif case ParsingFunction.InReadAttributeValue: FinishAttributeValueIterator(); curNode = nodes[index]; continue; #if !SILVERLIGHT // Needed only for XmlTextReader (ReadChars, ReadBase64, ReadBinHex) case ParsingFunction.InIncrementalRead: FinishIncrementalRead(); return true; case ParsingFunction.FragmentAttribute: return ParseFragmentAttribute(); case ParsingFunction.XmlDeclarationFragment: ParseXmlDeclarationFragment(); parsingFunction = ParsingFunction.GoToEof; return true; #endif case ParsingFunction.GoToEof: OnEof(); return false; case ParsingFunction.Error: case ParsingFunction.Eof: case ParsingFunction.ReaderClosed: return false; case ParsingFunction.NoData: ThrowWithoutLineInfo( Res.Xml_MissingRoot ); return false; case ParsingFunction.PartialTextValue: SkipPartialTextValue(); continue; case ParsingFunction.InReadValueChunk: FinishReadValueChunk(); continue; case ParsingFunction.InReadContentAsBinary: FinishReadContentAsBinary(); continue; case ParsingFunction.InReadElementContentAsBinary: FinishReadElementContentAsBinary(); continue; default: Debug.Assert( false ); break; } } }
// This constructor is used when creating XmlTextReaderImpl reader via "XmlReader.Create(..)" private XmlTextReaderImpl( XmlResolver resolver, XmlReaderSettings settings, XmlParserContext context ) { v1Compat = false; outerReader = this; xmlContext = new XmlContext(); // create or get nametable and namespace manager from XmlParserContext XmlNameTable nt = settings.NameTable; if ( context == null ) { if ( nt == null ) { nt = new NameTable(); Debug.Assert( nameTableFromSettings == false ); } else { nameTableFromSettings = true; } nameTable = nt; namespaceManager = new XmlNamespaceManager( nt ); } else { SetupFromParserContext( context, settings ); nt = nameTable; } nt.Add( string.Empty ); Xml = nt.Add( "xml" ); XmlNs = nt.Add( "xmlns" ); xmlResolver = resolver; Debug.Assert( index == 0 ); nodes = new NodeData[ NodesInitialSize ]; nodes[0] = new NodeData(); curNode = nodes[0]; stringBuilder = new BufferBuilder(); entityHandling = EntityHandling.ExpandEntities; whitespaceHandling = ( settings.IgnoreWhitespace ) ? WhitespaceHandling.Significant : WhitespaceHandling.All; normalize = true; ignorePIs = settings.IgnoreProcessingInstructions; ignoreComments = settings.IgnoreComments; checkCharacters = settings.CheckCharacters; lineNumberOffset = settings.LineNumberOffset; linePositionOffset = settings.LinePositionOffset; ps.lineNo = lineNumberOffset + 1; ps.lineStartPos = - linePositionOffset - 1; curNode.SetLineInfo( ps.LineNo - 1, ps.LinePos - 1 ); prohibitDtd = settings.ProhibitDtd; fragmentParserContext = context; parsingFunction = ParsingFunction.SwitchToInteractiveXmlDecl; nextParsingFunction = ParsingFunction.DocumentContent; switch ( settings.ConformanceLevel ) { case ConformanceLevel.Auto: fragmentType = XmlNodeType.None; fragment = true; break; case ConformanceLevel.Fragment: fragmentType = XmlNodeType.Element; fragment = true; break; case ConformanceLevel.Document: fragmentType = XmlNodeType.Document; break; default: Debug.Assert( false ); goto case ConformanceLevel.Document; } }
private bool ParseAttributeValueChunk() { char[] chars = ps.chars; int pos = ps.charPos; curNode = AddNode(index + attrCount + 1, index + 2); curNode.SetLineInfo(ps.LineNo, ps.LinePos); Debug.Assert(stringBuilder.Length == 0); for (; ; ) { while (chars[pos] > XmlCharType.MaxAsciiChar || (xmlCharType.charProperties[chars[pos]] & XmlCharType.fAttrValue) != 0) { pos++; } switch (chars[pos]) { // eol D case (char)0xD: Debug.Assert(ps.eolNormalized, "Entity replacement text for attribute values should be EOL-normalized!"); pos++; continue; // eol A, tab case (char)0xA: case (char)0x9: if (normalize) { chars[pos] = (char)0x20; // CDATA normalization of 0xA and 0x9 } pos++; continue; case '"': case '\'': case '>': pos++; continue; // attribute values cannot contain '<' case '<': Throw(pos, Res.Xml_BadAttributeChar, XmlException.BuildCharExceptionStr('<')); break; // entity reference case '&': if (pos - ps.charPos > 0) { stringBuilder.Append(chars, ps.charPos, pos - ps.charPos); } ps.charPos = pos; // expand char entities but not general entities switch (HandleEntityReference(true, EntityExpandType.OnlyCharacter, out pos)) { case EntityType.CharacterDec: case EntityType.CharacterHex: case EntityType.CharacterNamed: chars = ps.chars; if (normalize && xmlCharType.IsWhiteSpace(chars[ps.charPos]) && pos - ps.charPos == 1) { chars[ps.charPos] = (char)0x20; // CDATA normalization of character references in entities } break; case EntityType.Unexpanded: Debug.Assert(false, "Found general entity in attribute"); throw new NotSupportedException(); default: Debug.Assert(false, "We should never get to this point."); break; } chars = ps.chars; continue; default: // end of buffer if (pos == ps.charsUsed) { goto ReadData; } // surrogate chars else { char ch = chars[pos]; if (ch >= SurHighStart && ch <= SurHighEnd) { if (pos + 1 == ps.charsUsed) { goto ReadData; } pos++; if (chars[pos] >= SurLowStart && chars[pos] <= SurLowEnd) { pos++; continue; } } ThrowInvalidChar(pos, ch); break; } } ReadData: if (pos - ps.charPos > 0) { stringBuilder.Append(chars, ps.charPos, pos - ps.charPos); ps.charPos = pos; } // read new characters into the buffer if (ReadData() == 0) { if (stringBuilder.Length > 0) { goto ReturnText; } else { Debug.Assert(false, "We should never get to this point."); } } pos = ps.charPos; chars = ps.chars; } ReturnText: if (pos - ps.charPos > 0) { stringBuilder.Append(chars, ps.charPos, pos - ps.charPos); ps.charPos = pos; } curNode.SetValueNode(XmlNodeType.Text, stringBuilder.ToString()); stringBuilder.Length = 0; return true; }
// This constructor is used when creating XmlTextReader reader via "XmlReader.Create(..)" private XmlTextReader(XmlReaderSettings settings) { xmlContext = new XmlContext(); // create nametable XmlNameTable nt = settings.NameTable; if (nt == null) { nt = new NameTable(); Debug.Assert(nameTableFromSettings == false); } else { nameTableFromSettings = true; } nameTable = nt; nt.Add(""); Xml = nt.Add("xml"); XmlNs = nt.Add("xmlns"); Debug.Assert(index == 0); nodes = new NodeData[NodesInitialSize]; nodes[0] = new NodeData(); curNode = nodes[0]; stringBuilder = new BufferBuilder(); entityHandling = EntityHandling.ExpandEntities; whitespaceHandling = (settings.IgnoreWhitespace) ? WhitespaceHandling.Significant : WhitespaceHandling.All; normalize = true; ignorePIs = settings.IgnoreProcessingInstructions; ignoreComments = settings.IgnoreComments; checkCharacters = settings.CheckCharacters; lineNumberOffset = settings.LineNumberOffset; linePositionOffset = settings.LinePositionOffset; ps.lineNo = lineNumberOffset + 1; ps.lineStartPos = -linePositionOffset - 1; curNode.SetLineInfo(ps.LineNo - 1, ps.LinePos - 1); parsingFunction = ParsingFunction.SwitchToInteractiveXmlDecl; nextParsingFunction = ParsingFunction.DocumentContent; switch (settings.ConformanceLevel) { case ConformanceLevel.Auto: fragmentType = XmlNodeType.None; break; case ConformanceLevel.Fragment: fragmentType = XmlNodeType.Element; break; case ConformanceLevel.Document: fragmentType = XmlNodeType.Document; break; default: Debug.Assert(false); goto case ConformanceLevel.Document; } }