public override bool Read()
{
if (this.Node.ReadState == ReadState.Closed)
return false;
if (this.Node.CanMoveToElement)
{
// If we're positioned on an attribute or attribute text on an empty element, we need to move back
// to the element in order to get the correct setting of ExitScope
MoveToElement();
}
if (this.Node.ExitScope)
{
ExitScope();
}
if (!_buffered)
BufferReader.SetWindow(ElementNode.BufferOffset, _maxBytesPerRead);
if (BufferReader.EndOfFile)
{
MoveToEndOfFile();
return false;
}
byte ch = BufferReader.GetByte();
if (ch == (byte)'<')
{
BufferReader.SkipByte();
ch = BufferReader.GetByte();
if (ch == (byte)'/')
ReadEndElement();
else if (ch == (byte)'!')
{
BufferReader.SkipByte();
ch = BufferReader.GetByte();
if (ch == '-')
{
ReadComment();
}
else
{
if (OutsideRootElement)
XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.Format(SR.XmlCDATAInvalidAtTopLevel)));
ReadCData();
}
}
else if (ch == (byte)'?')
ReadDeclaration();
else
ReadStartElement();
}
else if ((s_charType[ch] & CharType.SpecialWhitespace) != 0)
{
ReadWhitespace();
}
else if (OutsideRootElement && ch != '\r')
{
XmlExceptionHelper.ThrowInvalidRootData(this);
}
else if ((s_charType[ch] & CharType.Text) != 0)
{
ReadText(false);
}
else if (ch == '&')
{
ReadEscapedText();
}
else if (ch == '\r')
{
BufferReader.SkipByte();
if (!BufferReader.EndOfFile && BufferReader.GetByte() == '\n')
ReadWhitespace();
else
MoveToComplexText().Value.SetCharValue('\n');
}
else if (ch == ']')
{
int offset;
byte[] buffer = BufferReader.GetBuffer(3, out offset);
if (buffer[offset + 0] == (byte)']' &&
buffer[offset + 1] == (byte)']' &&
buffer[offset + 2] == (byte)'>')
{
XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.Format(SR.XmlCloseCData)));
}
BufferReader.SkipByte();
MoveToComplexText().Value.SetCharValue(']'); // Need to get past the ']' and keep going.
}
else if (ch == 0xEF) // Watch for invalid characters 0xfffe and 0xffff
{
ReadText(true);
}
else
{
XmlExceptionHelper.ThrowInvalidXml(this, ch);
}
return true;
}