private void SkipUntil(char stopChar, bool recognizeLiterals)
{
bool inLiteral = false;
bool inComment = false;
bool inPI = false;
char literalQuote = '"';
char[] chars = _ps.chars;
int pos = _ps.charPos;
for (;;)
{
char ch;
unsafe
{
while (_xmlCharType.IsAttributeValueChar(ch = chars[pos]) && chars[pos] != stopChar && ch != '-' && ch != '?')
{
pos++;
}
}
// closing stopChar outside of literal and ignore/include sections -> save value & return
if (ch == stopChar && !inLiteral)
{
_ps.charPos = pos + 1;
return;
}
// handle the special character
_ps.charPos = pos;
switch (ch)
{
// 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 || _ps.isEof)
{
pos++;
}
else
{
goto ReadData;
}
OnNewLine(pos);
continue;
// comment, PI
case '<':
// processing instruction
if (chars[pos + 1] == '?')
{
if (recognizeLiterals && !inLiteral && !inComment)
{
inPI = true;
pos += 2;
continue;
}
}
// comment
else if (chars[pos + 1] == '!')
{
if (pos + 3 >= _ps.charsUsed && !_ps.isEof)
{
goto ReadData;
}
if (chars[pos + 2] == '-' && chars[pos + 3] == '-')
{
if (recognizeLiterals && !inLiteral && !inPI)
{
inComment = true;
pos += 4;
continue;
}
}
}
// need more data
else if (pos + 1 >= _ps.charsUsed && !_ps.isEof)
{
goto ReadData;
}
pos++;
continue;
case '-':
// end of comment
if (inComment)
{
if (pos + 2 >= _ps.charsUsed && !_ps.isEof)
{
goto ReadData;
}
if (chars[pos + 1] == '-' && chars[pos + 2] == '>')
{
inComment = false;
pos += 2;
continue;
}
}
pos++;
continue;
case '?':
// end of processing instruction
if (inPI)
{
if (pos + 1 >= _ps.charsUsed && !_ps.isEof)
{
goto ReadData;
}
if (chars[pos + 1] == '>')
{
inPI = false;
pos += 1;
continue;
}
}
pos++;
continue;
case (char)0x9:
case '>':
case ']':
case '&':
pos++;
continue;
case '"':
case '\'':
if (inLiteral)
{
if (literalQuote == ch)
{
inLiteral = false;
}
}
else
{
if (recognizeLiterals && !inComment && !inPI)
{
inLiteral = true;
literalQuote = ch;
}
}
pos++;
continue;
default:
// end of buffer
if (pos == _ps.charsUsed)
{
goto ReadData;
}
// surrogate chars
else
{
char tmpCh = chars[pos];
if (XmlCharType.IsHighSurrogate(tmpCh))
{
if (pos + 1 == _ps.charsUsed)
{
goto ReadData;
}
pos++;
if (XmlCharType.IsLowSurrogate(chars[pos]))
{
pos++;
continue;
}
}
ThrowInvalidChar(chars, _ps.charsUsed, pos);
break;
}
}
ReadData:
// read new characters into the buffer
if (ReadData() == 0)
{
if (_ps.charsUsed - _ps.charPos > 0)
{
if (_ps.chars[_ps.charPos] != (char)0xD)
{
Debug.Assert(false, "We should never get to this point.");
Throw(SR.Xml_UnexpectedEOF1);
}
Debug.Assert(_ps.isEof);
}
else
{
Throw(SR.Xml_UnexpectedEOF1);
}
}
chars = _ps.chars;
pos = _ps.charPos;
}
}