Skip to content

Commit

Permalink
better code for parsing email addresses; for #62
Browse files Browse the repository at this point in the history
  • Loading branch information
andyedinborough committed Apr 2, 2012
1 parent 9ee20e5 commit 9f1fa19
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 23 deletions.
60 changes: 38 additions & 22 deletions HeaderCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,32 +115,48 @@ public T GetEnum<T>(string name) where T : struct, IConvertible {
return values.FirstOrDefault(x => x.ToString().Equals(value, StringComparison.OrdinalIgnoreCase));
}

private static string ReadUntil(string values, ref int start, params char[] until) {
char c, nil = '\0', q = nil;
var hash = new System.Collections.Generic.HashSet<char>(until);
string value;
for (int i = start; i < values.Length; i++) {
c = values[i];
if (q != nil ) {
if(q == c){
q = nil;
}
} else if (c == '"' || c == '\'') {
q = c;
} else if (c == '<') {
q = '>';

} else if (hash.Contains(c)) {
value = values.Substring(start, i - start);
start = i + 1;
return value;
}
}

value = values.Substring(start);
start = values.Length;
return value;
}

public MailAddress[] GetAddresses(string header) {
string values = this[header].RawValue.Trim();
List<MailAddress> addrs = new List<MailAddress>();
while (true) {
int semicolon = values.IndexOf(';');
int comma = values.IndexOf(',');
if (comma < semicolon || semicolon == -1) semicolon = comma;

int bracket = values.IndexOf('>');
string temp = null;
if (semicolon == -1 && bracket == -1) {
if (values.Length > 0) addrs.Add(values.ToEmailAddress());
return addrs.Where(x => x != null).ToArray();
} else {
if (bracket > -1 && (semicolon == -1 || bracket < semicolon)) {
temp = values.Substring(0, bracket + 1);
values = values.Substring(temp.Length);
} else if (semicolon > -1 && (bracket == -1 || semicolon < bracket)) {
temp = values.Substring(0, semicolon);
values = values.Substring(semicolon + 1);
}
if (temp.Length > 0)
addrs.Add(temp.Trim().ToEmailAddress());
values = values.Trim();
}

int i = 0;
string value;
MailAddress addr;
while (i < values.Length) {
value = ReadUntil(values, ref i, ';', ',', '\n');
addr = value.ToEmailAddress();
if (addr != null)
addrs.Add(addr);
}

return addrs.ToArray();
}


Expand Down
13 changes: 12 additions & 1 deletion Tests/Parsing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ BUSINESS DEMANDS AND HOPE YOU WILL NOT BETRAY THE TRUST AND CONFIDENCE WHICH
[TestMethod]
public void TestBasicMimeMessage() {
var msg = GetMessage(@"From: John Doe <[email protected]>
To: <[email protected]>; [email protected]; John Doe <[email protected]>
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary=""XXXXboundary text""
Expand All @@ -301,7 +302,17 @@ this is the attachment text
--XXXXboundary text--");

msg.From.Should().Not.Be.Null();
msg.Attachments.Count.Should().Equal(2);
msg.From.DisplayName.Should().Equal("John Doe");
msg.From.Address.Should().Equal("[email protected]");

var to = msg.To.ToArray();
to.Length.Should().Equal(3);
to[0].Address.Should().Equal("[email protected]");
to[1].Address.Should().Equal("[email protected]");
to[2].Address.Should().Equal("[email protected]");

msg.Attachments.Count.Should().Equal(1);
msg.AlternateViews.Count.Should().Equal(1);
msg.Attachments.All(a => a.GetData().Any().Should().Be.True());
}

Expand Down

0 comments on commit 9f1fa19

Please sign in to comment.