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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
%{C++
#define NS_MAILNEWS_MIME_HEADER_PARSER_CONTRACTID \
"@mozilla.org/messenger/headerparser;1"
%}
/**
* A structured representation of an address.
*
* This is meant to correspond to the address production from RFC 5322. As a
* result, an instance of this interface is either a single mailbox or a group
* of mailboxes. The difference between the two forms is in which attribute is
* undefined: mailboxes leave the members attribute undefined while groups leave
* the email attribute undefined.
*
* For example, an address like "John Doe <jdoe@machine.example>" will, when
* parsed, result in an instance with the name attribute set to "John Doe", the
* email attribute set to "jdoe@machine.example", and the members variable left
* undefined.
*
* A group like "undisclosed-recipients:;" will, when parsed, result in an
* instance with the name attribute set to "undisclosed-recipients", the email
* attribute left defined, and the members variable set to an empty array.
*
* In general, the attributes of this interface are always meant to be in a form
* suitable for display purposes, and not in a form usable for MIME emission. In
* particular, email addresses could be fully internationalized and non-ASCII,
* RFC 2047-encoded words may appear in names, and the name or email parameters
* are unquoted.
*/
[scriptable, uuid(b19f5636-ebc4-470e-b46c-98b5fc7e88c9)]
interface msgIAddressObject : nsISupports {
/// The name of the mailbox or group.
readonly attribute AString name;
/// The email of the mailbox.
readonly attribute AString email;
/**
* The member mailboxes of this group, which may be an empty list.
*
* Due to the limitations of XPIDL, the type of this attribute cannot be
* properly reflected. It is actually an array of msgIAddressObject instances,
* although it is instead undefined if this object does not represent a group.
*/
readonly attribute jsval group;
/// Return a string form of this object that is suitable for display.
AString toString();
};
/**
* A utility service for manipulating addressing headers in email messages.
*
* This interface is designed primarily for use from JavaScript code; code in
* C++ should use the methods in MimeHeaderParser.h instead, as it is better
* designed to take advantage of C++'s features, particularly with respect to
* arrays.
*
* There are two methods for parsing MIME headers, one for RFC 2047-decoded
* strings, and one for non-RFC 2047-decoded strings.
*
* In general, this API attempts to preserve the format of addresses as
* faithfully as possible. No case normalization is performed at any point.
* However, internationalized email addresses generally need extra processing to
* work properly, so while this API should handle them without issues, consumers
* of this API may fail to work properly when presented with such addresses. To
* ease use for such cases, future versions of the API may incorporate necessary
* normalization steps to make oblivious consumers more likely to work properly.
*/
[scriptable, uuid(af2f9dd1-0226-4835-b981-a4f88b5e97cc)]
interface nsIMsgHeaderParser : nsISupports {
/**
* Parse an address-based header that has not yet been 2047-decoded.
*
* The result of this method is an array of objects described in the above
* comment. Note that the header is a binary string that will be decoded as if
* passed into nsIMimeConverter.
*
* @param aEncodedHeader The RFC 2047-encoded header to parse.
* @param aHeaderCharset The charset to assume for raw octets.
* @param aPreserveGroups If false (the default), the result is a flat array
* of mailbox objects, containing no group objects.
* @return An array corresponding to the header description.
*/
void parseEncodedHeader(in ACString aEncodedHeader,
in string aHeaderCharset,
[optional] in bool aPreserveGroups,
[optional] out unsigned long length,
[retval, array, size_is(length)]
out msgIAddressObject addresses);
/**
* Parse an address-based header that has been 2047-decoded.
*
* The result of this method is an array of objects described in the above
* comment. Note that the header is a binary string that will be decoded as if
* passed into nsIMimeConverter.
*
* @param aDecodedHeader The non-RFC 2047-encoded header to parse.
* @param aPreserveGroups If false (the default), the result is a flat array
* of mailbox objects, containing no group objects.
* @return An array corresponding to the header description.
*/
void parseDecodedHeader(in AString aDecodedHeader,
[optional] in bool aPreserveGroups,
[optional] out unsigned long length,
[retval, array, size_is(length)]
out msgIAddressObject addresses);
/**
* Given an array of addresses, make a MIME header suitable for emission.
*
* The return value of this method is not directly suitable for use in a MIME
* message but rather needs to be passed through nsIMimeConverter first to
* have RFC-2047 encoding applied and the resulting output wrapped to adhere
* to maximum line length formats.
*
* @param aAddresses An array corresponding to the header description.
* @param aLength The length of said array of addresses.
* @return A string that is suitable for writing in a MIME message.
*/
AString makeMimeHeader([array, size_is(aLength)]
in msgIAddressObject aAddresses,
in unsigned long aLength);
/**
* Return the first address in the list in a format suitable for display.
*
* This is largely a convience method for handling From headers (or similar),
* which are expected to only have a single element in them. It is exactly
* equivalent to saying (parseDecodedHeader(decodedHeader))[0].toString().
*
* @param decodedHeader The non-RFC 2047-encoded header to parse.
* @return The first address, suitable for display.
*/
AString extractFirstName(in AString aDecodedHeader);
/**
* Returns a copy of the input which may have had some addresses removed.
* Addresses are removed if they are already in either of the supplied
* address lists.
*
* Addresses are considered to be the same if they contain the same email
* part (case-insensitive). Since the email part should never be RFC
* 2047-encoded, this method should work whether or not the header is
* RFC 2047-encoded.
*
* @param aAddrs The addresses to remove duplicates from.
* @param aOtherAddrs Other addresses that the duplicate removal process also
* checks for duplicates against. Addresses in this list
* will not be added to the result.
* @return The original header with duplicate addresses removed.
*/
AUTF8String removeDuplicateAddresses(in AUTF8String aAddrs,
[optional] in AUTF8String aOtherAddrs);
/// Return a structured mailbox object having the given name and email.
msgIAddressObject makeMailboxObject(in AString aName, in AString aEmail);
/// Return a structured group object having the given name and members.
msgIAddressObject makeGroupObject(in AString aName,
[array, size_is(aLength)] in msgIAddressObject aMembers,
in unsigned long aLength);
/**
* Return an array of structured mailbox objects for the given display name
* string.
*
* The string is expected to be a comma-separated sequence of strings that
* would be produced by msgIAddressObject::toString(). For example, the string
* "Bond, James <agent007@mi5.invalid>" would produce one address object,
* while the string "webmaster@nowhere.invalid, child@nowhere.invalid" would
* produce two address objects.
*
* Note that the input string is RFC 2231 and RFC 2047 decoded but no UTF-8
* decoding takes place.
*/
void makeFromDisplayAddress(in AString aDisplayAddresses,
[optional] out unsigned long count,
[retval, array, size_is(count)] out msgIAddressObject addresses);
[deprecated] void parseHeadersWithArray(in wstring aLine,
[array, size_is(count)] out wstring aEmailAddresses,
[array, size_is(count)] out wstring aNames,
[array, size_is(count)] out wstring aFullNames,
[retval] out unsigned long count);
/**
* Given a string which contains a list of Header addresses, returns a
* comma-separated list of just the `mailbox' portions.
*
* @param aLine The header line to parse.
* @return A comma-separated list of just the mailbox parts
* of the email-addresses.
*/
[deprecated] ACString extractHeaderAddressMailboxes(in ACString aLine);
/**
* Given a string which contains a list of Header addresses, returns a
* comma-separated list of just the `user name' portions. If any of
* the addresses doesn't have a name, then the mailbox is used instead.
*
* @param aLine The header line to parse.
* @return A comma-separated list of just the name parts
* of the addresses.
*/
[deprecated] AUTF8String extractHeaderAddressNames(in AUTF8String aLine);
/*
* Like extractHeaderAddressNames, but only returns the first name in the
* header if there is one. This function will return unquoted strings suitable
* for display.
*
* @param aLine The header line to parse.
* @return The first name found in the list.
*/
[deprecated] AUTF8String extractHeaderAddressName(in AUTF8String aLine);
/**
* Given a name and email address, produce a string that is suitable for
* emitting in a MIME header (after applying RFC 2047 encoding).
*
* @note This is a temporary method.
*/
[deprecated] AString makeMimeAddress(in AString aName, in AString aEmail);
};
|