private async Task<ValueTuple<int, int, int, bool>> ParseTextAsync_Surrogate(int outOrChars, char[] chars, int pos, int rcount, int rpos, int orChars, char c) { char ch = chars[pos]; if (XmlCharType.IsHighSurrogate(ch)) { if (pos + 1 == _ps.charsUsed) { _lastParseTextState = new ParseTextState(outOrChars, chars, pos, rcount, rpos, orChars, c); _parseText_NextFunction = ParseTextFunction.ReadData; return _parseText_dummyTask.Result; } pos++; if (XmlCharType.IsLowSurrogate(chars[pos])) { pos++; orChars |= ch; _lastParseTextState = new ParseTextState(outOrChars, chars, pos, rcount, rpos, orChars, c); _parseText_NextFunction = ParseTextFunction.ParseText; return _parseText_dummyTask.Result; } } int offset = pos - _ps.charPos; if (await ZeroEndingStreamAsync(pos).ConfigureAwait(false)) { chars = _ps.chars; pos = _ps.charPos + offset; _lastParseTextState = new ParseTextState(outOrChars, chars, pos, rcount, rpos, orChars, c); _parseText_NextFunction = ParseTextFunction.PartialValue; return _parseText_dummyTask.Result; } else { ThrowInvalidChar(_ps.chars, _ps.charsUsed, _ps.charPos + offset); } //should never hit here throw new Exception(); }
private async Task<ValueTuple<int, int, int, bool>> ParseTextAsync_ReadData(int outOrChars, char[] chars, int pos, int rcount, int rpos, int orChars, char c) { if (pos > _ps.charPos) { _lastParseTextState = new ParseTextState(outOrChars, chars, pos, rcount, rpos, orChars, c); _parseText_NextFunction = ParseTextFunction.PartialValue; return _parseText_dummyTask.Result; } // read new characters into the buffer if (await ReadDataAsync().ConfigureAwait(false) == 0) { if (_ps.charsUsed - _ps.charPos > 0) { if (_ps.chars[_ps.charPos] != (char)0xD && _ps.chars[_ps.charPos] != ']') { Throw(SR.Xml_UnexpectedEOF1); } Debug.Assert(_ps.isEof); } else { if (!InEntity) { // end the value (returns nothing) _lastParseTextState = new ParseTextState(outOrChars, chars, pos, rcount, rpos, orChars, c); _parseText_NextFunction = ParseTextFunction.NoValue; return _parseText_dummyTask.Result; } HandleEntityEnd(true); } } pos = _ps.charPos; chars = _ps.chars; _lastParseTextState = new ParseTextState(outOrChars, chars, pos, rcount, rpos, orChars, c); _parseText_NextFunction = ParseTextFunction.ParseText; return _parseText_dummyTask.Result; }
private async Task<ValueTuple<int, int, int, bool>> ParseTextAsync_ParseEntity(int outOrChars, char[] chars, int pos, int rcount, int rpos, int orChars, char c) { // try to parse char entity inline int charRefEndPos, charCount; EntityType entityType; if ((charRefEndPos = ParseCharRefInline(pos, out charCount, out entityType)) > 0) { if (rcount > 0) { ShiftBuffer(rpos + rcount, rpos, pos - rpos - rcount); } rpos = pos - rcount; rcount += (charRefEndPos - pos - charCount); pos = charRefEndPos; if (!_xmlCharType.IsWhiteSpace(chars[charRefEndPos - charCount]) || (_v1Compat && entityType == EntityType.CharacterDec)) { orChars |= 0xFF; } } else { if (pos > _ps.charPos) { _lastParseTextState = new ParseTextState(outOrChars, chars, pos, rcount, rpos, orChars, c); _parseText_NextFunction = ParseTextFunction.PartialValue; return _parseText_dummyTask.Result; } var tuple_14 = await HandleEntityReferenceAsync(false, EntityExpandType.All).ConfigureAwait(false); pos = tuple_14.Item1; switch (tuple_14.Item2) { case EntityType.CharacterDec: if (!_v1Compat) { goto case EntityType.CharacterHex; } orChars |= 0xFF; break; case EntityType.CharacterHex: case EntityType.CharacterNamed: if (!_xmlCharType.IsWhiteSpace(_ps.chars[pos - 1])) { orChars |= 0xFF; } break; default: pos = _ps.charPos; break; } chars = _ps.chars; } _lastParseTextState = new ParseTextState(outOrChars, chars, pos, rcount, rpos, orChars, c); _parseText_NextFunction = ParseTextFunction.ParseText; return _parseText_dummyTask.Result; }
private Task<ValueTuple<int, int, int, bool>> ParseTextAsync(int outOrChars, char[] chars, int pos, int rcount, int rpos, int orChars, char c) { for (; ;) { // parse text content while (_xmlCharType.IsTextChar(c = chars[pos])) { orChars |= (int)c; pos++; } switch (c) { case (char)0x9: pos++; continue; // eol case (char)0xA: pos++; OnNewLine(pos); continue; case (char)0xD: if (chars[pos + 1] == (char)0xA) { if (!_ps.eolNormalized && _parsingMode == ParsingMode.Full) { if (pos - _ps.charPos > 0) { if (rcount == 0) { rcount = 1; rpos = pos; } else { ShiftBuffer(rpos + rcount, rpos, pos - rpos - rcount); rpos = pos - rcount; rcount++; } } else { _ps.charPos++; } } pos += 2; } else if (pos + 1 < _ps.charsUsed || _ps.isEof) { if (!_ps.eolNormalized) { chars[pos] = (char)0xA; // EOL normalization of 0xD } pos++; } else { _lastParseTextState = new ParseTextState(outOrChars, chars, pos, rcount, rpos, orChars, c); _parseText_NextFunction = ParseTextFunction.ReadData; return _parseText_dummyTask; } OnNewLine(pos); continue; // some tag case '<': _lastParseTextState = new ParseTextState(outOrChars, chars, pos, rcount, rpos, orChars, c); _parseText_NextFunction = ParseTextFunction.PartialValue; return _parseText_dummyTask; // entity reference case '&': _lastParseTextState = new ParseTextState(outOrChars, chars, pos, rcount, rpos, orChars, c); _parseText_NextFunction = ParseTextFunction.Entity; return _parseText_dummyTask; case ']': if (_ps.charsUsed - pos < 3 && !_ps.isEof) { _lastParseTextState = new ParseTextState(outOrChars, chars, pos, rcount, rpos, orChars, c); _parseText_NextFunction = ParseTextFunction.ReadData; return _parseText_dummyTask; } if (chars[pos + 1] == ']' && chars[pos + 2] == '>') { Throw(pos, SR.Xml_CDATAEndInText); } orChars |= ']'; pos++; continue; default: // end of buffer if (pos == _ps.charsUsed) { _lastParseTextState = new ParseTextState(outOrChars, chars, pos, rcount, rpos, orChars, c); _parseText_NextFunction = ParseTextFunction.ReadData; return _parseText_dummyTask; } // surrogate chars else { _lastParseTextState = new ParseTextState(outOrChars, chars, pos, rcount, rpos, orChars, c); _parseText_NextFunction = ParseTextFunction.Surrogate; return _parseText_dummyTask; } } } }
private async Task<ValueTuple<int, int, int, bool>> ParseTextAsync_ParseEntity(int outOrChars, char[] chars, int pos, int rcount, int rpos, int orChars, char c) { // try to parse char entity inline int charRefEndPos, charCount; EntityType entityType; if ((charRefEndPos = ParseCharRefInline(pos, out charCount, out entityType)) > 0) { if (rcount > 0) { ShiftBuffer(rpos + rcount, rpos, pos - rpos - rcount); } rpos = pos - rcount; rcount += (charRefEndPos - pos - charCount); pos = charRefEndPos; if (!_xmlCharType.IsWhiteSpace(chars[charRefEndPos - charCount]) || (_v1Compat && entityType == EntityType.CharacterDec)) { orChars |= 0xFF; } } else { if (pos > _ps.charPos) { _lastParseTextState = new ParseTextState(outOrChars, chars, pos, rcount, rpos, orChars, c); _parseText_NextFunction = ParseTextFunction.PartialValue; return _parseText_dummyTask.Result; } var tuple_14 = await HandleEntityReferenceAsync(false, EntityExpandType.All).ConfigureAwait(false); pos = tuple_14.Item1; switch (tuple_14.Item2) { #if !SILVERLIGHT // Needed only for XmlTextReader (reporting of entities) case EntityType.Unexpanded: // make sure we will report EntityReference after the text node _nextParsingFunction = _parsingFunction; _parsingFunction = ParsingFunction.EntityReference; // end the value (returns nothing) _lastParseTextState = new ParseTextState(outOrChars, chars, pos, rcount, rpos, orChars, c); _parseText_NextFunction = ParseTextFunction.NoValue; return _parseText_dummyTask.Result; #endif case EntityType.CharacterDec: if (!_v1Compat) { goto case EntityType.CharacterHex; } orChars |= 0xFF; break; case EntityType.CharacterHex: case EntityType.CharacterNamed: if (!_xmlCharType.IsWhiteSpace(_ps.chars[pos - 1])) { orChars |= 0xFF; } break; default: pos = _ps.charPos; break; } chars = _ps.chars; } _lastParseTextState = new ParseTextState(outOrChars, chars, pos, rcount, rpos, orChars, c); _parseText_NextFunction = ParseTextFunction.ParseText; return _parseText_dummyTask.Result; }
private async Task<Tuple<int, int, int, bool>> ParseTextAsync_ReadData(int outOrChars, char[] chars, int pos, int rcount, int rpos, int orChars, char c) { if (pos > ps.charPos) { lastParseTextState = new ParseTextState(outOrChars, chars, pos, rcount, rpos, orChars, c); parseText_NextFunction = ParseTextFunction.PartialValue; return parseText_dummyTask.Result; } // read new characters into the buffer if (await ReadDataAsync().ConfigureAwait(false) == 0) { if (ps.charsUsed - ps.charPos > 0) { if (ps.chars[ps.charPos] != (char)0xD && ps.chars[ps.charPos] != ']') { Throw(Res.Xml_UnexpectedEOF1); } Debug.Assert(ps.isEof); } else { if (!InEntity) { // end the value (returns nothing) lastParseTextState = new ParseTextState(outOrChars, chars, pos, rcount, rpos, orChars, c); parseText_NextFunction = ParseTextFunction.NoValue; return parseText_dummyTask.Result; } #if SILVERLIGHT // Needed only for XmlTextReader (reporting of entities) HandleEntityEnd( true ); #else if (HandleEntityEnd(true)) { // report EndEntity after the text node nextParsingFunction = parsingFunction; parsingFunction = ParsingFunction.ReportEndEntity; // end the value (returns nothing) lastParseTextState = new ParseTextState(outOrChars, chars, pos, rcount, rpos, orChars, c); parseText_NextFunction = ParseTextFunction.NoValue; return parseText_dummyTask.Result; } #endif } } pos = ps.charPos; chars = ps.chars; lastParseTextState = new ParseTextState(outOrChars, chars, pos, rcount, rpos, orChars, c); parseText_NextFunction = ParseTextFunction.ParseText; return parseText_dummyTask.Result; }
private Task<Tuple<int, int, int, bool>> ParseTextAsync(int outOrChars, char[] chars, int pos, int rcount, int rpos, int orChars, char c) { for (; ; ) { // parse text content #if SILVERLIGHT while (xmlCharType.IsTextChar(c = chars[pos])) { orChars |= (int)c; pos++; } #else // Optimization due to the lack of inlining when a method uses byte* unsafe { while (((xmlCharType.charProperties[c = chars[pos]] & XmlCharType.fText) != 0)) { orChars |= (int)c; pos++; } } #endif switch (c) { case (char)0x9: pos++; continue; // eol case (char)0xA: pos++; OnNewLine(pos); continue; case (char)0xD: if (chars[pos + 1] == (char)0xA) { if (!ps.eolNormalized && parsingMode == ParsingMode.Full) { if (pos - ps.charPos > 0) { if (rcount == 0) { rcount = 1; rpos = pos; } else { ShiftBuffer(rpos + rcount, rpos, pos - rpos - rcount); rpos = pos - rcount; rcount++; } } else { ps.charPos++; } } pos += 2; } else if (pos + 1 < ps.charsUsed || ps.isEof) { if (!ps.eolNormalized) { chars[pos] = (char)0xA; // EOL normalization of 0xD } pos++; } else { lastParseTextState = new ParseTextState(outOrChars, chars, pos, rcount, rpos, orChars, c); parseText_NextFunction = ParseTextFunction.ReadData; return parseText_dummyTask; } OnNewLine(pos); continue; // some tag case '<': lastParseTextState = new ParseTextState(outOrChars, chars, pos, rcount, rpos, orChars, c); parseText_NextFunction = ParseTextFunction.PartialValue; return parseText_dummyTask; // entity reference case '&': lastParseTextState = new ParseTextState(outOrChars, chars, pos, rcount, rpos, orChars, c); parseText_NextFunction = ParseTextFunction.Entity; return parseText_dummyTask; case ']': if (ps.charsUsed - pos < 3 && !ps.isEof) { lastParseTextState = new ParseTextState(outOrChars, chars, pos, rcount, rpos, orChars, c); parseText_NextFunction = ParseTextFunction.ReadData; return parseText_dummyTask; } if (chars[pos + 1] == ']' && chars[pos + 2] == '>') { Throw(pos, Res.Xml_CDATAEndInText); } orChars |= ']'; pos++; continue; default: // end of buffer if (pos == ps.charsUsed) { lastParseTextState = new ParseTextState(outOrChars, chars, pos, rcount, rpos, orChars, c); parseText_NextFunction = ParseTextFunction.ReadData; return parseText_dummyTask; } // surrogate chars else { lastParseTextState = new ParseTextState(outOrChars, chars, pos, rcount, rpos, orChars, c); parseText_NextFunction = ParseTextFunction.Surrogate; return parseText_dummyTask; } } } }