private Token GetToken(bool needWhiteSpace)
{
_whitespaceSeen = false;
for (;;)
{
switch (_chars[_curPos])
{
case (char)0:
if (_curPos == _charsUsed)
{
goto ReadData;
}
else
{
ThrowInvalidChar(_chars, _charsUsed, _curPos);
}
break;
case (char)0xA:
_whitespaceSeen = true;
_curPos++;
_readerAdapter.OnNewLine(_curPos);
continue;
case (char)0xD:
_whitespaceSeen = true;
if (_chars[_curPos + 1] == (char)0xA)
{
if (Normalize)
{
SaveParsingBuffer(); // EOL normalization of 0xD 0xA
_readerAdapter.CurrentPosition++;
}
_curPos += 2;
}
else if (_curPos + 1 < _charsUsed || _readerAdapter.IsEof)
{
_chars[_curPos] = (char)0xA; // EOL normalization of 0xD
_curPos++;
}
else
{
goto ReadData;
}
_readerAdapter.OnNewLine(_curPos);
continue;
case (char)0x9:
case (char)0x20:
_whitespaceSeen = true;
_curPos++;
continue;
case '%':
if (_charsUsed - _curPos < 2)
{
goto ReadData;
}
if (!_xmlCharType.IsWhiteSpace(_chars[_curPos + 1]))
{
if (IgnoreEntityReferences)
{
_curPos++;
}
else
{
HandleEntityReference(true, false, false);
}
continue;
}
goto default;
default:
if (needWhiteSpace && !_whitespaceSeen && _scanningFunction != ScanningFunction.ParamEntitySpace)
{
Throw(_curPos, SR.Xml_ExpectingWhiteSpace, ParseUnexpectedToken(_curPos));
}
_tokenStartPos = _curPos;
SwitchAgain:
switch (_scanningFunction)
{
case ScanningFunction.Name: return ScanNameExpected();
case ScanningFunction.QName: return ScanQNameExpected();
case ScanningFunction.Nmtoken: return ScanNmtokenExpected();
case ScanningFunction.SubsetContent: return ScanSubsetContent();
case ScanningFunction.Doctype1: return ScanDoctype1();
case ScanningFunction.Doctype2: return ScanDoctype2();
case ScanningFunction.Element1: return ScanElement1();
case ScanningFunction.Element2: return ScanElement2();
case ScanningFunction.Element3: return ScanElement3();
case ScanningFunction.Element4: return ScanElement4();
case ScanningFunction.Element5: return ScanElement5();
case ScanningFunction.Element6: return ScanElement6();
case ScanningFunction.Element7: return ScanElement7();
case ScanningFunction.Attlist1: return ScanAttlist1();
case ScanningFunction.Attlist2: return ScanAttlist2();
case ScanningFunction.Attlist3: return ScanAttlist3();
case ScanningFunction.Attlist4: return ScanAttlist4();
case ScanningFunction.Attlist5: return ScanAttlist5();
case ScanningFunction.Attlist6: return ScanAttlist6();
case ScanningFunction.Attlist7: return ScanAttlist7();
case ScanningFunction.Notation1: return ScanNotation1();
case ScanningFunction.SystemId: return ScanSystemId();
case ScanningFunction.PublicId1: return ScanPublicId1();
case ScanningFunction.PublicId2: return ScanPublicId2();
case ScanningFunction.Entity1: return ScanEntity1();
case ScanningFunction.Entity2: return ScanEntity2();
case ScanningFunction.Entity3: return ScanEntity3();
case ScanningFunction.CondSection1: return ScanCondSection1();
case ScanningFunction.CondSection2: return ScanCondSection2();
case ScanningFunction.CondSection3: return ScanCondSection3();
case ScanningFunction.ClosingTag: return ScanClosingTag();
case ScanningFunction.ParamEntitySpace:
_whitespaceSeen = true;
_scanningFunction = _savedScanningFunction;
goto SwitchAgain;
default:
Debug.Assert(false);
return Token.None;
}
}
ReadData:
if (_readerAdapter.IsEof || ReadData() == 0)
{
if (HandleEntityEnd(false))
{
continue;
}
if (_scanningFunction == ScanningFunction.SubsetContent)
{
return Token.Eof;
}
else
{
Throw(_curPos, SR.Xml_IncompleteDtdContent);
}
}
}
}