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
34template <typename K, typename V> class QMap;
35class QStringList;
36
37namespace KMime {
38
39namespace Headers {
40 class Base;
41}
42
43namespace 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
49struct KMIME_EXPORT QStringOrQPair {
50 QStringOrQPair() : qstring(), qpair( 0, 0 ) {}
51 QString qstring;
52 QPair<const char*, int> qpair;
53};
54
55struct 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};
63typedef QList<AddrSpec> AddrSpecList;
64
65/**
66 Represents an (email address, display name) pair according RFC 2822,
67 section 3.4.
68*/
69class 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 &lt;address&gt;". 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
171typedef QList<Mailbox> MailboxList;
172
173struct KMIME_EXPORT Address {
174 QString displayName;
175 MailboxList mailboxList;
176};
177typedef QList<Address> AddressList;
178
179} // namespace KMime::Types
180
181namespace 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*/
198KMIME_EXPORT bool parseEncodedWord( 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. */
210KMIME_EXPORT bool parseAtom( const char* &scursor, const char * const send,
211 QString &result, bool allow8Bit=false );
212
213KMIME_EXPORT bool parseAtom( 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. */
219KMIME_EXPORT bool parseToken( const char* &scursor, const char * const send,
220 QString &result, bool allow8Bit=false );
221
222KMIME_EXPORT bool parseToken( 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. */
227KMIME_EXPORT bool parseGenericQuotedString( 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 '(' */
234KMIME_EXPORT bool parseComment( 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*/
253KMIME_EXPORT bool parsePhrase( 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*/
268KMIME_EXPORT bool parseDotAtom( 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*/
285KMIME_EXPORT void eatCFWS( const char* &scursor, const char * const send,
286 bool isCRLF );
287
288KMIME_EXPORT bool parseDomain( const char* &scursor, const char * const send,
289 QString &result, bool isCRLF=false );
290
291KMIME_EXPORT bool parseObsRoute( const char* &scursor, const char * const send,
292 QStringList &result, bool isCRLF=false,
293 bool save=false );
294
295KMIME_EXPORT bool parseAddrSpec( const char* &scursor, const char * const send,
296 Types::AddrSpec &result, bool isCRLF=false );
297
298KMIME_EXPORT bool parseAngleAddr( 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*/
317KMIME_EXPORT bool parseMailbox( const char* &scursor, const char * const send,
318 Types::Mailbox &result, bool isCRLF=false );
319
320KMIME_EXPORT bool parseGroup( const char* &scursor, const char * const send,
321 Types::Address &result, bool isCRLF=false );
322
323KMIME_EXPORT bool parseAddress( const char* &scursor, const char * const send,
324 Types::Address &result, bool isCRLF=false );
325
326KMIME_EXPORT bool parseAddressList( const char* &scursor,
327 const char * const send,
328 Types::AddressList &result,
329 bool isCRLF=false );
330
331KMIME_EXPORT bool parseParameter( const char* &scursor, const char * const send,
332 QPair<QString,Types::QStringOrQPair> &result,
333 bool isCRLF=false );
334
335KMIME_EXPORT bool parseParameterList( const char* &scursor,
336 const char * const send,
337 QMap<QString,QString> &result,
338 bool isCRLF=false );
339
340KMIME_EXPORT bool parseRawParameterList( 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 */
350KMIME_EXPORT bool parseParameterListWithCharset( 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*/
362KMIME_EXPORT int parseDigits( const char* &scursor, const char* const send, int &result );
363
364KMIME_EXPORT bool parseTime( 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
369KMIME_EXPORT bool parseDateTime( 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 */
378KMIME_EXPORT KMime::Headers::Base *extractFirstHeader( 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 */
390KMIME_EXPORT void extractHeaderAndBody( const QByteArray &content,
391 QByteArray &header, QByteArray &body );
392
393
394} // namespace HeaderParsing
395
396} // namespace KMime
397
398#endif // __KMIME_HEADER_PARSING_H__
399
400