forked from andyedinborough/aenetmail
-
Notifications
You must be signed in to change notification settings - Fork 0
/
HeaderValue.cs
67 lines (57 loc) · 2.08 KB
/
HeaderValue.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mail;
using System.Text.RegularExpressions;
namespace AE.Net.Mail {
public struct HeaderValue {
private readonly string _RawValue;
private readonly SafeDictionary<string, string> _Values;
public HeaderValue(string value)
: this() {
_Values = new SafeDictionary<string, string>(StringComparer.OrdinalIgnoreCase);
_RawValue = (value ?? (value = string.Empty));
_Values[string.Empty] = RawValue;
var semicolon = value.IndexOf(';');
if (semicolon > 0) {
_Values[string.Empty] = value.Substring(0, semicolon).Trim();
value = value[semicolon..].Trim();
ParseValues(_Values, value);
}
}
public string Value => this[string.Empty] ?? string.Empty;
public string RawValue => _RawValue ?? string.Empty;
public string this[string name] {
get { return _Values.Get(name, string.Empty); }
set {
_Values.Set(name, value);
}
}
public static void ParseValues(IDictionary<string, string> result, string header) {
while (header.Length > 0) {
var eq = header.IndexOf('=');
if (eq < 0) eq = header.Length;
var name = header.Substring(0, eq).Trim().Trim(new[] { ';', ',' }).Trim();
var value = header = header[Math.Min(header.Length, eq + 1)..].Trim();
if (value.StartsWith("\"")) {
ProcessValue(1, ref header, ref value, '"');
} else if (value.StartsWith("'")) {
ProcessValue(1, ref header, ref value, '\'');
} else {
ProcessValue(0, ref header, ref value, ' ', ',', ';');
}
result.Set(name, value);
}
}
private static void ProcessValue(int skip, ref string header, ref string value, params char[] lookFor) {
var quote = value.IndexOfAny(lookFor, skip);
if (quote < 0) quote = value.Length;
header = header[Math.Min(quote + 1, header.Length)..];
value = value[skip..quote];
}
public override string ToString() {
var props = _Values.Where(x => !string.IsNullOrEmpty(x.Key)).Select(x => x.Key + "=" + x.Value);
return Value + (props.Any() ? ("; " + string.Join(", ", props)) : null);
}
}
}