private int ParseNumericCharRefInline(int startPos, bool expand, StringBuilder internalSubsetBuilder, out int charCount, out EntityType entityType)
{
Debug.Assert(_ps.chars[startPos] == '&' && _ps.chars[startPos + 1] == '#');
int val;
int pos;
char[] chars;
val = 0;
string badDigitExceptionString = null;
chars = _ps.chars;
pos = startPos + 2;
charCount = 0;
int digitPos = 0;
try
{
if (chars[pos] == 'x')
{
pos++;
digitPos = pos;
badDigitExceptionString = SR.Xml_BadHexEntity;
for (;;)
{
char ch = chars[pos];
if (ch >= '0' && ch <= '9')
val = checked(val * 16 + ch - '0');
else if (ch >= 'a' && ch <= 'f')
val = checked(val * 16 + 10 + ch - 'a');
else if (ch >= 'A' && ch <= 'F')
val = checked(val * 16 + 10 + ch - 'A');
else
break;
pos++;
}
entityType = EntityType.CharacterHex;
}
else if (pos < _ps.charsUsed)
{
digitPos = pos;
badDigitExceptionString = SR.Xml_BadDecimalEntity;
while (chars[pos] >= '0' && chars[pos] <= '9')
{
val = checked(val * 10 + chars[pos] - '0');
pos++;
}
entityType = EntityType.CharacterDec;
}
else
{
// need more data in the buffer
entityType = EntityType.Skipped;
return -2;
}
}
catch (OverflowException e)
{
_ps.charPos = pos;
entityType = EntityType.Skipped;
Throw(SR.Xml_CharEntityOverflow, (string)null, e);
}
if (chars[pos] != ';' || digitPos == pos)
{
if (pos == _ps.charsUsed)
{
// need more data in the buffer
return -2;
}
else
{
Throw(pos, badDigitExceptionString);
}
}
// simple character
if (val <= char.MaxValue)
{
char ch = (char)val;
if (!_xmlCharType.IsCharData(ch) &&
((_v1Compat && _normalize) || (!_v1Compat && _checkCharacters)))
{
Throw((_ps.chars[startPos + 2] == 'x') ? startPos + 3 : startPos + 2, SR.Xml_InvalidCharacter, XmlException.BuildCharExceptionArgs(ch, '\0'));
}
if (expand)
{
if (internalSubsetBuilder != null)
{
internalSubsetBuilder.Append(_ps.chars, _ps.charPos, pos - _ps.charPos + 1);
}
chars[pos] = ch;
}
charCount = 1;
return pos + 1;
}
// surrogate
else
{
char low, high;
XmlCharType.SplitSurrogateChar(val, out low, out high);
if (_normalize)
{
if (XmlCharType.IsHighSurrogate(high))
{
if (XmlCharType.IsLowSurrogate(low))
{
goto Return;
}
}
Throw((_ps.chars[startPos + 2] == 'x') ? startPos + 3 : startPos + 2, SR.Xml_InvalidCharacter, XmlException.BuildCharExceptionArgs(high, low));
}
Return:
Debug.Assert(pos > 0);
if (expand)
{
if (internalSubsetBuilder != null)
{
internalSubsetBuilder.Append(_ps.chars, _ps.charPos, pos - _ps.charPos + 1);
}
chars[pos - 1] = (char)high;
chars[pos] = (char)low;
}
charCount = 2;
return pos + 1;
}
}