private static string ParseLocalPart(string data, ref int index, bool expectAngleBracket,
bool expectMultipleAddresses)
{
// Skip comments and whitespace
index = ReadCfwsAndThrowIfIncomplete(data, index);
// Mark the start of the local-part
int startingIndex = index;
// Is the local-part component in quoted-string format or dot-atom format?
if (data[index] == MailBnfHelper.Quote)
{
index = QuotedStringFormatReader.ReadReverseQuoted(data, index, true);
}
else
{
index = DotAtomReader.ReadReverse(data, index);
// Check that the local-part is properly separated from the next component. It may be separated by a
// comment, white space, an expected angle bracket, a quote for the display-name, or an expected comma
// before the next address.
if (index >= 0 &&
!(
MailBnfHelper.IsAllowedWhiteSpace(data[index]) // < local@domain >
|| data[index] == MailBnfHelper.EndComment // <(comment)local@domain>
|| (expectAngleBracket && data[index] == MailBnfHelper.StartAngleBracket) // <local@domain>
|| (expectMultipleAddresses && data[index] == MailBnfHelper.Comma) // local@dom,local@dom
// Note: The following condition is more lax than the RFC. This is done so we could support
// a common invalid formats as shown below.
|| data[index] == MailBnfHelper.Quote // "display"local@domain
)
)
{
throw new FormatException(SR.Format(SR.MailHeaderFieldInvalidCharacter, data[index]));
}
}
string localPart = data.Substring(index + 1, startingIndex - index);
index = WhitespaceReader.ReadCfwsReverse(data, index);
return NormalizeOrThrow(localPart);
}