private Task ParseEndElementAsync_CheckEndTag(int nameLen, NodeData startTagNode, LineInfo endTagLineInfo) { int pos; char[] chars; for (; ;) { pos = _ps.charPos + nameLen; chars = _ps.chars; if (pos == _ps.charsUsed) { _parseEndElement_NextFunc = ParseEndElementParseFunction.ReadData; return Task.CompletedTask; } bool tagMismatch = false; unsafe { if (_xmlCharType.IsNCNameSingleChar(chars[pos]) || (chars[pos] == ':') #if XML10_FIFTH_EDITION || xmlCharType.IsNCNameHighSurrogateChar(chars[pos]) #endif ) { tagMismatch = true; } } if (tagMismatch) { return ThrowTagMismatchAsync(startTagNode); } // eat whitespaces if (chars[pos] != '>') { char tmpCh; while (_xmlCharType.IsWhiteSpace(tmpCh = chars[pos])) { pos++; switch (tmpCh) { case (char)0xA: OnNewLine(pos); continue; case (char)0xD: if (chars[pos] == (char)0xA) { pos++; } else if (pos == _ps.charsUsed && !_ps.isEof) { break; } OnNewLine(pos); continue; } } } if (chars[pos] == '>') { break; } else if (pos == _ps.charsUsed) { _parseEndElement_NextFunc = ParseEndElementParseFunction.ReadData; return Task.CompletedTask; } else { ThrowUnexpectedToken(pos, ">"); } Debug.Assert(false, "We should never get to this point."); } Debug.Assert(_index > 0); _index--; _curNode = _nodes[_index]; // set the element data Debug.Assert(_curNode == startTagNode); startTagNode.lineInfo = endTagLineInfo; startTagNode.type = XmlNodeType.EndElement; _ps.charPos = pos + 1; // set next parsing function _nextParsingFunction = (_index > 0) ? _parsingFunction : ParsingFunction.DocumentContent; _parsingFunction = ParsingFunction.PopElementContext; _parseEndElement_NextFunc = ParseEndElementParseFunction.Done; return Task.CompletedTask; }
private async Task ParseEndElementAsync_ReadData() { if (await ReadDataAsync().ConfigureAwait(false) == 0) { ThrowUnclosedElements(); } _parseEndElement_NextFunc = ParseEndElementParseFunction.CheckEndTag; return; }
private Task ParseEndElementAsync_CheckEndTag(int nameLen, NodeData startTagNode, LineInfo endTagLineInfo) { int pos; char[] chars; for (; ; ) { pos = ps.charPos + nameLen; chars = ps.chars; if (pos == ps.charsUsed) { parseEndElement_NextFunc = ParseEndElementParseFunction.ReadData; return AsyncHelper.DoneTask; } bool tagMismatch = false; unsafe { #if SILVERLIGHT if ( xmlCharType.IsNCNameSingleChar( chars[pos] ) || #else // Optimization due to the lack of inlining when a method uses byte* if (((xmlCharType.charProperties[chars[pos]] & XmlCharType.fNCNameSC) != 0) || #endif (chars[pos] == ':') #if XML10_FIFTH_EDITION || xmlCharType.IsNCNameHighSurrogateChar( chars[pos] ) #endif ) { tagMismatch = true; } } if (tagMismatch) { return ThrowTagMismatchAsync(startTagNode); } // eat whitespaces if (chars[pos] != '>') { char tmpCh; while (xmlCharType.IsWhiteSpace(tmpCh = chars[pos])) { pos++; switch (tmpCh) { case (char)0xA: OnNewLine(pos); continue; case (char)0xD: if (chars[pos] == (char)0xA) { pos++; } else if (pos == ps.charsUsed && !ps.isEof) { break; } OnNewLine(pos); continue; } } } if (chars[pos] == '>') { break; } else if (pos == ps.charsUsed) { parseEndElement_NextFunc = ParseEndElementParseFunction.ReadData; return AsyncHelper.DoneTask; } else { ThrowUnexpectedToken(pos, ">"); } Debug.Assert(false, "We should never get to this point."); } Debug.Assert(index > 0); index--; curNode = nodes[index]; // set the element data Debug.Assert(curNode == startTagNode); startTagNode.lineInfo = endTagLineInfo; startTagNode.type = XmlNodeType.EndElement; ps.charPos = pos + 1; // set next parsing function nextParsingFunction = (index > 0) ? parsingFunction : ParsingFunction.DocumentContent; parsingFunction = ParsingFunction.PopElementContext; parseEndElement_NextFunc = ParseEndElementParseFunction.Done; return AsyncHelper.DoneTask; }