1 | /* -*- c++ -*- |
2 | kmime_header_parsing.h |
3 | |
4 | KMime, the KDE Internet mail/usenet news message library. |
5 | Copyright (c) 2001-2002 Marc Mutz <mutz@kde.org> |
6 | |
7 | This library is free software; you can redistribute it and/or |
8 | modify it under the terms of the GNU Library General Public |
9 | License as published by the Free Software Foundation; either |
10 | version 2 of the License, or (at your option) any later version. |
11 | |
12 | This library is distributed in the hope that it will be useful, |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | Library General Public License for more details. |
16 | |
17 | You should have received a copy of the GNU Library General Public License |
18 | along with this library; see the file COPYING.LIB. If not, write to |
19 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
20 | Boston, MA 02110-1301, USA. |
21 | */ |
22 | |
23 | #ifndef __KMIME_HEADER_PARSING_H__ |
24 | #define __KMIME_HEADER_PARSING_H__ |
25 | |
26 | #include <QtCore/QString> |
27 | #include <QtCore/QPair> |
28 | #include <QtCore/QList> |
29 | |
30 | #include <kdatetime.h> |
31 | |
32 | #include "kmime_export.h" |
33 | |
34 | template <typename K, typename V> class QMap; |
35 | class QStringList; |
36 | |
37 | namespace KMime { |
38 | |
39 | namespace Headers { |
40 | class ; |
41 | } |
42 | |
43 | namespace Types { |
44 | |
45 | // for when we can't make up our mind what to use... |
46 | // FIXME: Remove this thing, we should _always_ know whether we are handling a |
47 | // byte array or a string. |
48 | // In most places where this is used, it should simply be replaced by QByteArray |
49 | struct KMIME_EXPORT QStringOrQPair { |
50 | QStringOrQPair() : qstring(), qpair( 0, 0 ) {} |
51 | QString qstring; |
52 | QPair<const char*, int> qpair; |
53 | }; |
54 | |
55 | struct KMIME_EXPORT AddrSpec { |
56 | QString asString() const; |
57 | /*! This is the same as asString(), except it decodes IDNs for display */ |
58 | QString asPrettyString() const; |
59 | bool isEmpty() const; |
60 | QString localPart; |
61 | QString domain; |
62 | }; |
63 | typedef QList<AddrSpec> AddrSpecList; |
64 | |
65 | /** |
66 | Represents an (email address, display name) pair according RFC 2822, |
67 | section 3.4. |
68 | */ |
69 | class KMIME_EXPORT Mailbox |
70 | { |
71 | public: |
72 | typedef QList<Mailbox> List; |
73 | |
74 | /** |
75 | Returns a string representation of the email address, without |
76 | the angle brackets. |
77 | */ |
78 | QByteArray address() const; |
79 | |
80 | AddrSpec addrSpec() const; |
81 | |
82 | /** |
83 | Returns the display name. |
84 | */ |
85 | QString name() const; |
86 | |
87 | /** |
88 | Sets the email address. |
89 | */ |
90 | void setAddress( const AddrSpec &addr ); |
91 | |
92 | /** |
93 | Sets the email address. |
94 | */ |
95 | void setAddress( const QByteArray &addr ); |
96 | |
97 | /** |
98 | Sets the name. |
99 | */ |
100 | void setName( const QString &name ); |
101 | |
102 | /** |
103 | Sets the name based on a 7bit encoded string. |
104 | */ |
105 | void setNameFrom7Bit( const QByteArray &name, |
106 | const QByteArray &defaultCharset = QByteArray() ); |
107 | |
108 | /** |
109 | Returns true if this mailbox has an address. |
110 | */ |
111 | bool hasAddress() const; |
112 | |
113 | /** |
114 | Returns true if this mailbox has a display name. |
115 | */ |
116 | bool hasName() const; |
117 | |
118 | /** |
119 | Returns a assembled display name / address string of the following form: |
120 | "Display Name <address>". These are unicode strings without any |
121 | transport encoding, ie. they are only suitable for displaying. |
122 | */ |
123 | QString prettyAddress() const; |
124 | |
125 | /** |
126 | * Describes how display names should be quoted |
127 | * @since 4.5 |
128 | */ |
129 | //AK_REVIEW: remove this enum |
130 | enum Quoting { |
131 | QuoteNever, ///< Don't quote display names at all. Such an unquoted display name can not |
132 | /// be machine-processed anymore in some cases, for example when it contains |
133 | /// commas, like in "Lastname, Firstname". |
134 | QuoteWhenNecessary, ///< Only quote display names when they contain characters that need to be |
135 | /// quoted, like commas or quote signs. |
136 | QuoteAlways ///< Always quote the display name |
137 | }; |
138 | |
139 | /** |
140 | * Overloaded method that gives more control over the quoting of the display name |
141 | * @param quoting describes how the display name should be quoted |
142 | * @since 4.5 |
143 | */ |
144 | // TODO: KDE5: BIC: remove other prettyAddress() overload, and make it None the default |
145 | // parameter here |
146 | //AK_REVIEW: replace by 'QString quotedAddress() const' |
147 | QString prettyAddress( Quoting quoting ) const; |
148 | |
149 | /** |
150 | Parses the given unicode string. |
151 | */ |
152 | void fromUnicodeString( const QString &s ); |
153 | |
154 | /** |
155 | Parses the given 7bit encoded string. |
156 | */ |
157 | void from7BitString( const QByteArray &s ); |
158 | |
159 | /** |
160 | Returns a 7bit transport encoded representation of this mailbox. |
161 | |
162 | @param encCharset The charset used for encoding. |
163 | */ |
164 | QByteArray as7BitString( const QByteArray &encCharset ) const; |
165 | |
166 | private: |
167 | QString mDisplayName; |
168 | AddrSpec mAddrSpec; |
169 | }; |
170 | |
171 | typedef QList<Mailbox> MailboxList; |
172 | |
173 | struct KMIME_EXPORT Address { |
174 | QString displayName; |
175 | MailboxList mailboxList; |
176 | }; |
177 | typedef QList<Address> AddressList; |
178 | |
179 | } // namespace KMime::Types |
180 | |
181 | namespace HeaderParsing { |
182 | |
183 | /** |
184 | Parses the encoded word. |
185 | |
186 | @param scursor pointer to the first character beyond the initial '=' of |
187 | the input string. |
188 | @param send pointer to end of input buffer. |
189 | @param result the decoded string the encoded work represented. |
190 | @param language The language parameter according to RFC 2231, section 5. |
191 | @param usedCS the used charset is returned here |
192 | @param defaultCS the charset to use in case the detected |
193 | one isn't known to us. |
194 | @param forceCS force the use of the default charset. |
195 | |
196 | @return true if the input string was successfully decode; false otherwise. |
197 | */ |
198 | KMIME_EXPORT bool ( const char* &scursor, |
199 | const char * const send, |
200 | QString &result, QByteArray &language, |
201 | QByteArray &usedCS, const QByteArray &defaultCS = QByteArray(), |
202 | bool forceCS = false ); |
203 | |
204 | // |
205 | // The parsing squad: |
206 | // |
207 | |
208 | /** You may or may not have already started parsing into the |
209 | atom. This function will go on where you left off. */ |
210 | KMIME_EXPORT bool ( const char* &scursor, const char * const send, |
211 | QString &result, bool allow8Bit=false ); |
212 | |
213 | KMIME_EXPORT bool ( const char* &scursor, const char * const send, |
214 | QPair<const char*,int> &result, |
215 | bool allow8Bit=false ); |
216 | |
217 | /** You may or may not have already started parsing into the |
218 | token. This function will go on where you left off. */ |
219 | KMIME_EXPORT bool ( const char* &scursor, const char * const send, |
220 | QString &result, bool allow8Bit=false ); |
221 | |
222 | KMIME_EXPORT bool ( const char* &scursor, const char * const send, |
223 | QPair<const char*,int> &result, |
224 | bool allow8Bit=false ); |
225 | |
226 | /** @p scursor must be positioned after the opening openChar. */ |
227 | KMIME_EXPORT bool ( const char* &scursor, |
228 | const char* const send, |
229 | QString &result, bool isCRLF, |
230 | const char openChar='"', |
231 | const char closeChar='"' ); |
232 | |
233 | /** @p scursor must be positioned right after the opening '(' */ |
234 | KMIME_EXPORT bool ( const char* &scursor, const char * const send, |
235 | QString &result, bool isCRLF=false, |
236 | bool reallySave=true ); |
237 | |
238 | /** |
239 | Parses a phrase. |
240 | |
241 | You may or may not have already started parsing into the phrase, but |
242 | only if it starts with atext. If you setup this function to parse a |
243 | phrase starting with an encoded-word or quoted-string, @p scursor has |
244 | to point to the char introducing the encoded-word or quoted-string, resp. |
245 | |
246 | @param scursor pointer to the first character beyond the initial '=' of |
247 | the input string. |
248 | @param send pointer to end of input buffer. |
249 | @param result the parsed string. |
250 | |
251 | @return true if the input phrase was successfully parsed; false otherwise. |
252 | */ |
253 | KMIME_EXPORT bool ( const char* &scursor, const char * const send, |
254 | QString &result, bool isCRLF=false ); |
255 | |
256 | /** |
257 | Parses into the initial atom. |
258 | You may or may not have already started parsing into the initial |
259 | atom, but not up to it's end. |
260 | |
261 | @param scursor pointer to the first character beyond the initial '=' of |
262 | the input string. |
263 | @param send pointer to end of input buffer. |
264 | @param result the parsed string. |
265 | |
266 | @return true if the input phrase was successfully parsed; false otherwise. |
267 | */ |
268 | KMIME_EXPORT bool ( const char* &scursor, const char * const send, |
269 | QString &result, bool isCRLF=false ); |
270 | |
271 | /** |
272 | Eats comment-folding-white-space, skips whitespace, folding and comments |
273 | (even nested ones) and stops at the next non-CFWS character. After |
274 | calling this function, you should check whether @p scursor == @p send |
275 | (end of header reached). |
276 | |
277 | If a comment with unbalanced parantheses is encountered, @p scursor |
278 | is being positioned on the opening '(' of the outmost comment. |
279 | |
280 | @param scursor pointer to the first character beyond the initial '=' of |
281 | the input string. |
282 | @param send pointer to end of input buffer. |
283 | @param isCRLF true if input string is terminated with a CRLF. |
284 | */ |
285 | KMIME_EXPORT void ( const char* &scursor, const char * const send, |
286 | bool isCRLF ); |
287 | |
288 | KMIME_EXPORT bool parseDomain( const char* &scursor, const char * const send, |
289 | QString &result, bool isCRLF=false ); |
290 | |
291 | KMIME_EXPORT bool ( const char* &scursor, const char * const send, |
292 | QStringList &result, bool isCRLF=false, |
293 | bool save=false ); |
294 | |
295 | KMIME_EXPORT bool ( const char* &scursor, const char * const send, |
296 | Types::AddrSpec &result, bool isCRLF=false ); |
297 | |
298 | KMIME_EXPORT bool ( const char* &scursor, const char * const send, |
299 | Types::AddrSpec &result, bool isCRLF=false ); |
300 | |
301 | /** |
302 | Parses a single mailbox. |
303 | |
304 | RFC 2822, section 3.4 defines a mailbox as follows: |
305 | <pre>mailbox := addr-spec / ([ display-name ] angle-addr)</pre> |
306 | |
307 | KMime also accepts the legacy format of specifying display names: |
308 | <pre>mailbox := (addr-spec [ "(" display-name ")" ]) |
309 | / ([ display-name ] angle-addr) |
310 | / (angle-addr "(" display-name ")")</pre> |
311 | |
312 | @param scursor pointer to the first character of the input string |
313 | @param send pointer to end of input buffer |
314 | @param result the parsing result |
315 | @param isCRLF true if input string is terminated with a CRLF. |
316 | */ |
317 | KMIME_EXPORT bool ( const char* &scursor, const char * const send, |
318 | Types::Mailbox &result, bool isCRLF=false ); |
319 | |
320 | KMIME_EXPORT bool ( const char* &scursor, const char * const send, |
321 | Types::Address &result, bool isCRLF=false ); |
322 | |
323 | KMIME_EXPORT bool ( const char* &scursor, const char * const send, |
324 | Types::Address &result, bool isCRLF=false ); |
325 | |
326 | KMIME_EXPORT bool ( const char* &scursor, |
327 | const char * const send, |
328 | Types::AddressList &result, |
329 | bool isCRLF=false ); |
330 | |
331 | KMIME_EXPORT bool ( const char* &scursor, const char * const send, |
332 | QPair<QString,Types::QStringOrQPair> &result, |
333 | bool isCRLF=false ); |
334 | |
335 | KMIME_EXPORT bool ( const char* &scursor, |
336 | const char * const send, |
337 | QMap<QString,QString> &result, |
338 | bool isCRLF=false ); |
339 | |
340 | KMIME_EXPORT bool ( const char* &scursor, |
341 | const char * const send, |
342 | QMap<QString,Types::QStringOrQPair> &result, |
343 | bool isCRLF=false ); |
344 | |
345 | /** |
346 | * Extract the charset embedded in the parameter list if there is one. |
347 | * |
348 | * @since 4.5 |
349 | */ |
350 | KMIME_EXPORT bool ( const char* &scursor, |
351 | const char * const send, |
352 | QMap<QString,QString> &result, |
353 | QByteArray& charset, bool isCRLF=false ); |
354 | |
355 | /** |
356 | Parses an integer number. |
357 | @param scursor pointer to the first character of the input string |
358 | @param send pointer to end of input buffer |
359 | @param result the parsing result |
360 | @returns The number of parsed digits (don't confuse with @p result!) |
361 | */ |
362 | KMIME_EXPORT int ( const char* &scursor, const char* const send, int &result ); |
363 | |
364 | KMIME_EXPORT bool ( const char* &scursor, const char * const send, |
365 | int &hour, int &min, int &sec, |
366 | long int &secsEastOfGMT, |
367 | bool &timeZoneKnown, bool isCRLF=false ); |
368 | |
369 | KMIME_EXPORT bool ( const char* &scursor, const char * const send, |
370 | KDateTime &result, bool isCRLF=false ); |
371 | |
372 | /** |
373 | * Extracts and returns the first header that is contained in the given byte array. |
374 | * The header will also be removed from the passed-in byte array head. |
375 | * |
376 | * @since 4.4 |
377 | */ |
378 | KMIME_EXPORT KMime::Headers::Base *( QByteArray &head ); |
379 | |
380 | /** |
381 | * Extract the header header and the body from a complete content. |
382 | * Internally, it will simply look for the first newline and use that as a |
383 | * separator between the header and the body. |
384 | * |
385 | * @param content the complete mail |
386 | * @param header return value for the extracted header |
387 | * @param body return value for the extracted body |
388 | * @since 4.6 |
389 | */ |
390 | KMIME_EXPORT void extractHeaderAndBody( const QByteArray &content, |
391 | QByteArray &, QByteArray &body ); |
392 | |
393 | |
394 | } // namespace HeaderParsing |
395 | |
396 | } // namespace KMime |
397 | |
398 | #endif // __KMIME_HEADER_PARSING_H__ |
399 | |
400 | |