// ---------------------------------------------------------------------
//
// Private methods
//
// ---------------------------------------------------------------------
#region Private Methods
/// <summary>
/// Advances a reading position by one character code
/// and reads the next availbale character from a stream.
/// This character becomes available as NextCharacter property.
/// </summary>
/// <remarks>
/// Throws InvalidOperationException if attempted to be called on EndOfStream
/// condition.
/// </remarks>
private void GetNextCharacter()
{
if (_nextCharacterCode == -1)
{
throw new InvalidOperationException("GetNextCharacter method called at the end of a stream");
}
_previousCharacter = _nextCharacter;
_nextCharacter = _lookAheadCharacter;
_nextCharacterCode = _lookAheadCharacterCode;
// next character not an entity as of now
_isNextCharacterEntity = false;
this.ReadLookAheadCharacter();
if (_nextCharacter == '&')
{
if (_lookAheadCharacter == '#')
{
// numeric entity - parse digits - &#DDDDD;
int entityCode;
entityCode = 0;
this.ReadLookAheadCharacter();
// largest numeric entity is 7 characters
for (int i = 0; i < 7 && Char.IsDigit(_lookAheadCharacter); i++)
{
entityCode = 10 * entityCode + (_lookAheadCharacterCode - (int)'0');
this.ReadLookAheadCharacter();
}
if (_lookAheadCharacter == ';')
{
// correct format - advance
this.ReadLookAheadCharacter();
_nextCharacterCode = entityCode;
// if this is out of range it will set the character to '?'
_nextCharacter = (char)_nextCharacterCode;
// as far as we are concerned, this is an entity
_isNextCharacterEntity = true;
}
else
{
// not an entity, set next character to the current lookahread character
// we would have eaten up some digits
_nextCharacter = _lookAheadCharacter;
_nextCharacterCode = _lookAheadCharacterCode;
this.ReadLookAheadCharacter();
_isNextCharacterEntity = false;
}
}
else if (Char.IsLetter(_lookAheadCharacter))
{
// entity is written as a string
string entity = "";
// maximum length of string entities is 10 characters
for (int i = 0; i < 10 && (Char.IsLetter(_lookAheadCharacter) || Char.IsDigit(_lookAheadCharacter)); i++)
{
entity += _lookAheadCharacter;
this.ReadLookAheadCharacter();
}
if (_lookAheadCharacter == ';')
{
// advance
this.ReadLookAheadCharacter();
if (HtmlSchema.IsEntity(entity))
{
_nextCharacter = HtmlSchema.EntityCharacterValue(entity);
_nextCharacterCode = (int)_nextCharacter;
_isNextCharacterEntity = true;
}
else
{
// just skip the whole thing - invalid entity
// move on to the next character
_nextCharacter = _lookAheadCharacter;
_nextCharacterCode = _lookAheadCharacterCode;
this.ReadLookAheadCharacter();
// not an entity
_isNextCharacterEntity = false;
}
}
else
{
// skip whatever we read after the ampersand
// set next character and move on
_nextCharacter = _lookAheadCharacter;
this.ReadLookAheadCharacter();
_isNextCharacterEntity = false;
}
}
}
}