private bool ParsePI(StringBuilder piInDtdStringBuilder)
{
if (_parsingMode == ParsingMode.Full)
{
_curNode.SetLineInfo(_ps.LineNo, _ps.LinePos);
}
Debug.Assert(_stringBuilder.Length == 0);
// parse target name
int nameEndPos = ParseName();
string target = _nameTable.Add(_ps.chars, _ps.charPos, nameEndPos - _ps.charPos);
if (string.Equals(target, "xml", StringComparison.OrdinalIgnoreCase))
{
Throw(target.Equals("xml") ? SR.Xml_XmlDeclNotFirst : SR.Xml_InvalidPIName, target);
}
_ps.charPos = nameEndPos;
if (piInDtdStringBuilder == null)
{
if (!_ignorePIs && _parsingMode == ParsingMode.Full)
{
_curNode.SetNamedNode(XmlNodeType.ProcessingInstruction, target);
}
}
else
{
piInDtdStringBuilder.Append(target);
}
// check mandatory whitespace
char ch = _ps.chars[_ps.charPos];
Debug.Assert(_ps.charPos < _ps.charsUsed);
if (EatWhitespaces(piInDtdStringBuilder) == 0)
{
if (_ps.charsUsed - _ps.charPos < 2)
{
ReadData();
}
if (ch != '?' || _ps.chars[_ps.charPos + 1] != '>')
{
Throw(SR.Xml_BadNameChar, XmlException.BuildCharExceptionArgs(_ps.chars, _ps.charsUsed, _ps.charPos));
}
}
// scan processing instruction value
int startPos, endPos;
if (ParsePIValue(out startPos, out endPos))
{
if (piInDtdStringBuilder == null)
{
if (_ignorePIs)
{
return false;
}
if (_parsingMode == ParsingMode.Full)
{
_curNode.SetValue(_ps.chars, startPos, endPos - startPos);
}
}
else
{
piInDtdStringBuilder.Append(_ps.chars, startPos, endPos - startPos);
}
}
else
{
StringBuilder sb;
if (piInDtdStringBuilder == null)
{
if (_ignorePIs || _parsingMode != ParsingMode.Full)
{
while (!ParsePIValue(out startPos, out endPos)) ;
return false;
}
sb = _stringBuilder;
Debug.Assert(_stringBuilder.Length == 0);
}
else
{
sb = piInDtdStringBuilder;
}
do
{
sb.Append(_ps.chars, startPos, endPos - startPos);
} while (!ParsePIValue(out startPos, out endPos));
sb.Append(_ps.chars, startPos, endPos - startPos);
if (piInDtdStringBuilder == null)
{
_curNode.SetValue(_stringBuilder.ToString());
_stringBuilder.Length = 0;
}
}
return true;
}