1 /*  -*- c++ -*-
2     kmime_headers.h
3 
4     KMime, the KDE Internet mail/usenet news message library.
5     SPDX-FileCopyrightText: 2001-2002 the KMime authors.
6     See file AUTHORS for details
7     SPDX-FileCopyrightText: 2006 Volker Krause <vkrause@kde.org>
8 
9     SPDX-License-Identifier: LGPL-2.0-or-later
10 */
11 /**
12   @file
13   This file is part of the API for handling @ref MIME data and
14   defines the various header classes:
15    - header's base class defining the common interface
16    - generic base classes for different types of fields
17    - incompatible, Structured-based field classes
18    - compatible, Unstructured-based field classes
19 
20   @brief
21   Defines the various headers classes.
22 
23   @authors the KMime authors (see AUTHORS file),
24   Volker Krause \<vkrause@kde.org\>
25 */
26 
27 #pragma once
28 
29 #include "kmime_export.h"
30 #include "kmime_header_parsing.h"
31 
32 #include <QString>
33 #include <QStringList>
34 #include <QDateTime>
35 #include <QVector>
36 #include <QByteArray>
37 #include <QMetaType>
38 
39 namespace KMime
40 {
41 
42 class Content;
43 
44 namespace Headers
45 {
46 
47 class BasePrivate;
48 
49 enum contentCategory {
50     CCsingle,
51     CCcontainer,
52     CCmixedPart,
53     CCalternativePart
54 };
55 
56 /**
57   Various possible values for the "Content-Transfer-Encoding" header.
58 */
59 enum contentEncoding {
60     CE7Bit,              ///< 7bit
61     CE8Bit,              ///< 8bit
62     CEquPr,              ///< quoted-printable
63     CEbase64,            ///< base64
64     CEuuenc,             ///< uuencode
65     CEbinary             ///< binary
66 };
67 
68 /**
69   Various possible values for the "Content-Disposition" header.
70 */
71 enum contentDisposition {
72     CDInvalid,           ///< Default, invalid value
73     CDinline,            ///< inline
74     CDattachment,        ///< attachment
75     CDparallel           ///< parallel (invalid, do not use)
76 };
77 
78 //@cond PRIVATE
79 // internal macro to generate default constructors
80 #define kmime_mk_trivial_ctor( subclass )                               \
81     public:                                                               \
82     subclass();                           \
83     ~subclass() override;
84 
85 #define kmime_mk_dptr_ctor( subclass ) \
86     protected: \
87     explicit subclass( subclass##Private *d );
88 
89 #define kmime_mk_trivial_ctor_with_name( subclass )     \
90     kmime_mk_trivial_ctor( subclass )                     \
91     const char *type() const override;                           \
92     static const char *staticType();
93 //@endcond
94 
95 //
96 //
97 // HEADER'S BASE CLASS. DEFINES THE COMMON INTERFACE
98 //
99 //
100 
101 /** Baseclass of all header-classes. It represents a
102     header-field as described in RFC-822.  */
103 class KMIME_EXPORT Base
104 {
105 public:
106     /**
107       A vector of headers.
108     */
109     typedef QVector<KMime::Headers::Base *> List;
110 
111     /**
112       Creates an empty header.
113     */
114     Base();
115 
116     /**
117       Destructor.
118     */
119     virtual ~Base();
120 
121     /**
122       Parses the given string. Take care of RFC2047-encoded strings.
123       @param s The encoded header data.
124     */
125     virtual void from7BitString(const char *s, size_t len);
126     virtual void from7BitString(const QByteArray &s) = 0;
127 
128     /**
129       Returns the encoded header.
130       @param withHeaderType Specifies whether the header-type should be included.
131     */
132     Q_REQUIRED_RESULT virtual QByteArray as7BitString(bool withHeaderType = true) const = 0;
133 
134     /**
135       Returns the charset that is used for RFC2047-encoding.
136     */
137     Q_REQUIRED_RESULT QByteArray rfc2047Charset() const;
138 
139     /**
140       Sets the charset for RFC2047-encoding.
141       @param cs The new charset used for RFC2047 encoding.
142     */
143     void setRFC2047Charset(const QByteArray &cs);
144 
145     /**
146       Parses the given string and set the charset.
147       @param s The header data as unicode string.
148       @param b The charset preferred for encoding.
149     */
150     virtual void fromUnicodeString(const QString &s, const QByteArray &b) = 0;
151 
152     /**
153       Returns the decoded content of the header without the header-type.
154 
155       @note The return value of this method should only be used when showing an address
156             to the user. It is not guaranteed that fromUnicodeString( asUnicodeString(), ... )
157             will return the original string.
158     */
159     virtual QString asUnicodeString() const = 0;
160 
161     /**
162       Deletes.
163     */
164     virtual void clear() = 0;
165 
166     /**
167       Checks if this header contains any data.
168     */
169     virtual bool isEmpty() const = 0;
170 
171     /**
172       Returns the type of this header (e.g. "From").
173     */
174     virtual const char *type() const;
175 
176     /**
177       Checks if this header is of type @p t.
178     */
179     Q_REQUIRED_RESULT bool is(const char *t) const;
180 
181     /**
182       Checks if this header is a MIME header.
183     */
184     Q_REQUIRED_RESULT bool isMimeHeader() const;
185 
186 protected:
187     /**
188       Helper method, returns the header prefix including ":".
189     */
190     QByteArray typeIntro() const;
191 
192     //@cond PRIVATE
193     BasePrivate *d_ptr;
194     kmime_mk_dptr_ctor(Base)
195     //@endcond
196 
197 private:
198     Q_DECLARE_PRIVATE(Base)
199     Q_DISABLE_COPY(Base)
200 };
201 
202 //
203 //
204 // GENERIC BASE CLASSES FOR DIFFERENT TYPES OF FIELDS
205 //
206 //
207 
208 namespace Generics
209 {
210 
211 class UnstructuredPrivate;
212 
213 /**
214   Abstract base class for unstructured header fields
215   (e.g. "Subject", "Comment", "Content-description").
216 
217   Features: Decodes the header according to RFC2047, incl. RFC2231
218   extensions to encoded-words.
219 
220   Subclasses need only re-implement @p const @p char* @p type().
221 */
222 
223 // known issues:
224 // - uses old decodeRFC2047String function, instead of our own...
225 
226 class KMIME_EXPORT Unstructured : public Base
227 {
228     //@cond PRIVATE
229     kmime_mk_dptr_ctor(Unstructured)
230     //@endcond
231 public:
232     Unstructured();
233     ~Unstructured() override;
234 
235     using Base::from7BitString;
236     void from7BitString(const QByteArray &s) override;
237     QByteArray as7BitString(bool withHeaderType = true) const override;
238 
239     void fromUnicodeString(const QString &s, const QByteArray &b) override;
240     QString asUnicodeString() const override;
241 
242     void clear() override;
243 
244     bool isEmpty() const override;
245 
246 private:
247     Q_DECLARE_PRIVATE(Unstructured)
248 };
249 
250 class StructuredPrivate;
251 
252 /**
253   @brief
254   Base class for structured header fields.
255 
256   This is the base class for all structured header fields.
257   It contains parsing methods for all basic token types found in rfc2822.
258 
259   @section Parsing
260 
261   At the basic level, there are tokens & tspecials (rfc2045),
262   atoms & specials, quoted-strings, domain-literals (all rfc822) and
263   encoded-words (rfc2047).
264 
265   As a special token, we have the comment. It is one of the basic
266   tokens defined in rfc822, but it's parsing relies in part on the
267   basic token parsers (e.g. comments may contain encoded-words).
268   Also, most upper-level parsers (notably those for phrase and
269   dot-atom) choose to ignore any comment when parsing.
270 
271   Then there are the real composite tokens, which are made up of one
272   or more of the basic tokens (and semantically invisible comments):
273   phrases (rfc822 with rfc2047) and dot-atoms (rfc2822).
274 
275   This finishes the list of supported token types. Subclasses will
276   provide support for more higher-level tokens, where necessary,
277   using these parsers.
278 
279   @author Marc Mutz <mutz@kde.org>
280 */
281 
282 class KMIME_EXPORT Structured : public Base
283 {
284 public:
285     Structured();
286     ~Structured() override;
287 
288     void from7BitString(const char *s, size_t len) override;
289     void from7BitString(const QByteArray &s) override;
290     QString asUnicodeString() const override;
291     void fromUnicodeString(const QString &s, const QByteArray &b) override;
292 
293 protected:
294     /**
295       This method parses the raw header and needs to be implemented in
296       every sub-class.
297 
298       @param scursor Pointer to the start of the data still to parse.
299       @param send Pointer to the end of the data.
300       @param isCRLF true if input string is terminated with a CRLF.
301     */
302     virtual bool parse(const char *&scursor, const char *const send,
303                        bool isCRLF = false) = 0;
304 
305     //@cond PRIVATE
306     kmime_mk_dptr_ctor(Structured)
307     //@endcond
308 
309 private:
310     Q_DECLARE_PRIVATE(Structured)
311 };
312 
313 class AddressPrivate;
314 
315 /**
316   Base class for all address related headers.
317 */
318 class KMIME_EXPORT Address : public Structured
319 {
320 public:
321     Address();
322     ~Address() override;
323 protected:
324     //@cond PRIVATE
325     kmime_mk_dptr_ctor(Address)
326     //@endcond
327 private:
328     Q_DECLARE_PRIVATE(Address)
329 };
330 
331 class MailboxListPrivate;
332 
333 /**
334   Base class for headers that deal with (possibly multiple)
335   addresses, but don't allow groups.
336 
337   @see RFC 2822, section 3.4
338 */
339 class KMIME_EXPORT MailboxList : public Address
340 {
341     //@cond PRIVATE
342     kmime_mk_trivial_ctor(MailboxList)
343     kmime_mk_dptr_ctor(MailboxList)
344     //@endcond
345 public:
346     QByteArray as7BitString(bool withHeaderType = true) const override;
347     void fromUnicodeString(const QString &s, const QByteArray &b) override;
348     QString asUnicodeString() const override;
349 
350     void clear() override;
351     bool isEmpty() const override;
352 
353     /**
354       Adds an address to this header.
355 
356       @param mbox A Mailbox object specifying the address.
357     */
358     void addAddress(const Types::Mailbox &mbox);
359 
360     /**
361       Adds an address to this header.
362       @param address The actual email address, with or without angle brackets.
363       @param displayName An optional name associated with the address.
364     */
365     void addAddress(const QByteArray &address,
366                     const QString &displayName = QString());
367 
368     /**
369       Returns a list of all addresses in this header, regardless of groups.
370     */
371     QVector<QByteArray> addresses() const;
372 
373     /**
374       Returns a list of all display names associated with the addresses in
375       this header. The address is added for addresses that do not have
376       a display name.
377     */
378     QStringList displayNames() const;
379 
380     /**
381       Returns a single string for user-facing display of this mailbox list.
382       This is equivalent to displayNames().join(", ").
383       @since 5.14
384     */
385     QString displayString() const;
386 
387     /**
388       Returns a list of mailboxes listed in this header.
389     */
390     Types::Mailbox::List mailboxes() const;
391 
392 protected:
393     bool parse(const char *&scursor, const char *const send, bool isCRLF = false) override;
394 
395 private:
396     Q_DECLARE_PRIVATE(MailboxList)
397 };
398 
399 class SingleMailboxPrivate;
400 
401 /**
402    Base class for headers that deal with exactly one mailbox
403    (e.g. Sender).
404 */
405 class KMIME_EXPORT SingleMailbox : public MailboxList
406 {
407     //@cond PRIVATE
408     kmime_mk_trivial_ctor(SingleMailbox)
409     //@endcond
410 protected:
411     bool parse(const char *&scursor, const char *const send, bool isCRLF = false) override;
412 private:
413     Q_DECLARE_PRIVATE(SingleMailbox)
414 };
415 
416 class AddressListPrivate;
417 
418 /**
419   Base class for headers that deal with (possibly multiple)
420   addresses, allowing groups.
421 
422   Note: Groups are parsed but not represented in the API yet. All addresses in
423   groups are listed as if they would not be part of a group.
424 
425   @todo Add API for groups?
426 
427   @see RFC 2822, section 3.4
428 */
429 class KMIME_EXPORT AddressList : public Address
430 {
431     //@cond PRIVATE
432     kmime_mk_trivial_ctor(AddressList)
433     kmime_mk_dptr_ctor(AddressList)
434     //@endcond
435 public:
436     QByteArray as7BitString(bool withHeaderType = true) const override;
437     void fromUnicodeString(const QString &s, const QByteArray &b) override;
438     QString asUnicodeString() const override;
439 
440     void clear() override;
441     bool isEmpty() const override;
442 
443     /**
444       Adds an address to this header.
445 
446       @param mbox A Mailbox object specifying the address.
447     */
448     void addAddress(const Types::Mailbox &mbox);
449 
450     /**
451       Adds an address to this header.
452       @param address The actual email address, with or without angle brackets.
453       @param displayName An optional name associated with the address.
454     */
455     void addAddress(const QByteArray &address, const QString &displayName = QString());
456 
457     /**
458       Returns a list of all addresses in this header, regardless of groups.
459     */
460     QVector<QByteArray> addresses() const;
461 
462     /**
463       Returns a list of all display names associated with the addresses in this header.
464       The address is added for addresses that don't have a display name.
465     */
466     QStringList displayNames() const;
467 
468     /**
469       Returns a single string for user-facing display of this address list.
470       This is equivalent to displayNames().join(", ").
471       @since 5.14
472     */
473     QString displayString() const;
474 
475     /**
476       Returns a list of mailboxes listed in this header.
477     */
478     Types::Mailbox::List mailboxes() const;
479 
480 protected:
481     bool parse(const char *&scursor, const char *const send, bool isCRLF = false) override;
482 
483 private:
484     Q_DECLARE_PRIVATE(AddressList)
485 };
486 
487 class IdentPrivate;
488 
489 /**
490   Base class for headers which deal with a list of msg-id's.
491 
492   @see RFC 2822, section 3.6.4
493 */
494 class KMIME_EXPORT Ident : public Address
495 {
496     //@cond PRIVATE
497     kmime_mk_trivial_ctor(Ident)
498     kmime_mk_dptr_ctor(Ident)
499     //@endcond
500 public:
501     QByteArray as7BitString(bool withHeaderType = true) const override;
502     void clear() override;
503     bool isEmpty() const override;
504 
505     /**
506       Initialize this identifier Copy the data from
507      */
508     void fromIdent(const Ident* ident);
509 
510     /**
511       Returns the list of identifiers contained in this header.
512       Note:
513       - Identifiers are not enclosed in angle-brackets.
514       - Identifiers are listed in the same order as in the header.
515     */
516     QVector<QByteArray> identifiers() const;
517 
518     /**
519       Appends a new identifier to this header.
520       @param id The identifier to append, with or without angle-brackets.
521     */
522     void appendIdentifier(const QByteArray &id);
523 
524 protected:
525     bool parse(const char *&scursor, const char *const send, bool isCRLF = false) override;
526 
527 private:
528     Q_DECLARE_PRIVATE(Ident)
529 };
530 
531 class SingleIdentPrivate;
532 
533 /**
534   Base class for headers which deal with a single msg-id.
535 
536   @see RFC 2822, section 3.6.4
537 */
538 class KMIME_EXPORT SingleIdent : public Ident
539 {
540     //@cond PRIVATE
541     kmime_mk_trivial_ctor(SingleIdent)
542     kmime_mk_dptr_ctor(SingleIdent)
543     //@endcond
544 public:
545     /**
546       Returns the identifier contained in this header.
547       Note: The identifiers is not enclosed in angle-brackets.
548     */
549     QByteArray identifier() const;
550 
551     /**
552       Sets the identifier.
553       @param id The new identifier with or without angle-brackets.
554     */
555     void setIdentifier(const QByteArray &id);
556 
557 protected:
558     bool parse(const char *&scursor, const char *const send, bool isCRLF = false) override;
559 
560 private:
561     Q_DECLARE_PRIVATE(SingleIdent)
562 };
563 
564 class TokenPrivate;
565 
566 /**
567   Base class for headers which deal with a single atom.
568 */
569 class KMIME_EXPORT Token : public Structured
570 {
571     //@cond PRIVATE
572     kmime_mk_trivial_ctor(Token)
573     kmime_mk_dptr_ctor(Token)
574     //@endcond
575 public:
576     QByteArray as7BitString(bool withHeaderType = true) const override;
577     void clear() override;
578     bool isEmpty() const override;
579 
580     /**
581       Returns the token.
582     */
583     QByteArray token() const;
584 
585     /**
586       Sets the token to @p t,
587     */
588     void setToken(const QByteArray &t);
589 
590 protected:
591     bool parse(const char *&scursor, const char *const send, bool isCRLF = false) override;
592 
593 private:
594     Q_DECLARE_PRIVATE(Token)
595 };
596 
597 class PhraseListPrivate;
598 
599 /**
600   Base class for headers containing a list of phrases.
601 */
602 class KMIME_EXPORT PhraseList : public Structured
603 {
604     //@cond PRIVATE
605     kmime_mk_trivial_ctor(PhraseList)
606     //@endcond
607 public:
608     QByteArray as7BitString(bool withHeaderType = true) const override;
609     QString asUnicodeString() const override;
610     void clear() override;
611     bool isEmpty() const override;
612 
613     /**
614       Returns the list of phrases contained in this header.
615     */
616     QStringList phrases() const;
617 
618 protected:
619     bool parse(const char *&scursor, const char *const send, bool isCRLF = false) override;
620 
621 private:
622     Q_DECLARE_PRIVATE(PhraseList)
623 };
624 
625 class DotAtomPrivate;
626 
627 /**
628   Base class for headers containing a dot atom.
629 */
630 class KMIME_EXPORT DotAtom : public Structured
631 {
632     //@cond PRIVATE
633     kmime_mk_trivial_ctor(DotAtom)
634     //@endcond
635 public:
636     QByteArray as7BitString(bool withHeaderType = true) const override;
637     QString asUnicodeString() const override;
638     void clear() override;
639     bool isEmpty() const override;
640 
641 protected:
642     bool parse(const char *&scursor, const char *const send, bool isCRLF = false) override;
643 
644 private:
645     Q_DECLARE_PRIVATE(DotAtom)
646 };
647 
648 class ParametrizedPrivate;
649 
650 /**
651   Base class for headers containing a parameter list such as "Content-Type".
652 */
653 class KMIME_EXPORT Parametrized : public Structured
654 {
655     //@cond PRIVATE
656     kmime_mk_trivial_ctor(Parametrized)
657     kmime_mk_dptr_ctor(Parametrized)
658     //@endcond
659 public:
660     QByteArray as7BitString(bool withHeaderType = true) const override;
661 
662     bool isEmpty() const override;
663     void clear() override;
664 
665     //FIXME: Shouldn't the parameter keys be QByteArray and not QStrings? Only the values can be
666     //       non-ascii!
667 
668     /**
669       Returns the value of the specified parameter.
670       @param key The parameter name.
671     */
672     QString parameter(const QString &key) const;
673 
674     /**
675       @param key the key of the parameter to check for
676       @return true if a parameter with the given @p key exists.
677       @since 4.5
678     */
679     bool hasParameter(const QString &key) const;
680 
681     /**
682       Sets the parameter @p key to @p value.
683       @param key The parameter name.
684       @param value The new value for @p key.
685     */
686     void setParameter(const QString &key, const QString &value);
687 
688 protected:
689     bool parse(const char *&scursor, const char *const send, bool isCRLF = false) override;
690 
691 private:
692     Q_DECLARE_PRIVATE(Parametrized)
693 };
694 
695 } // namespace Generics
696 
697 //
698 //
699 // INCOMPATIBLE, GSTRUCTURED-BASED FIELDS:
700 //
701 //
702 
703 class ReturnPathPrivate;
704 
705 /**
706   Represents the Return-Path header field.
707 
708   @see RFC 2822, section 3.6.7
709 */
710 class KMIME_EXPORT ReturnPath : public Generics::Address
711 {
712     //@cond PRIVATE
713     kmime_mk_trivial_ctor_with_name(ReturnPath)
714     //@endcond
715 public:
716     QByteArray as7BitString(bool withHeaderType = true) const override;
717     void clear() override;
718     bool isEmpty() const override;
719 
720 protected:
721     bool parse(const char *&scursor, const char *const send, bool isCRLF = false) override;
722 
723 private:
724     Q_DECLARE_PRIVATE(ReturnPath)
725 };
726 
727 // Address et al.:
728 
729 // rfc(2)822 headers:
730 /**
731    Represent a "From" header.
732 
733    @see RFC 2822, section 3.6.2.
734 */
735 class KMIME_EXPORT From : public Generics::MailboxList
736 {
737     kmime_mk_trivial_ctor_with_name(From)
738 };
739 
740 /**
741   Represents a "Sender" header.
742 
743   @see RFC 2822, section 3.6.2.
744 */
745 class KMIME_EXPORT Sender : public Generics::SingleMailbox
746 {
747     kmime_mk_trivial_ctor_with_name(Sender)
748 };
749 
750 /**
751   Represents a "To" header.
752 
753   @see RFC 2822, section 3.6.3.
754 */
755 class KMIME_EXPORT To : public Generics::AddressList
756 {
757     kmime_mk_trivial_ctor_with_name(To)
758 };
759 
760 /**
761   Represents a "Cc" header.
762 
763   @see RFC 2822, section 3.6.3.
764 */
765 class KMIME_EXPORT Cc : public Generics::AddressList
766 {
767     kmime_mk_trivial_ctor_with_name(Cc)
768 };
769 
770 /**
771   Represents a "Bcc" header.
772 
773   @see RFC 2822, section 3.6.3.
774 */
775 class KMIME_EXPORT Bcc : public Generics::AddressList
776 {
777     kmime_mk_trivial_ctor_with_name(Bcc)
778 };
779 
780 /**
781   Represents a "ReplyTo" header.
782 
783   @see RFC 2822, section 3.6.2.
784 */
785 class KMIME_EXPORT ReplyTo : public Generics::AddressList
786 {
787     kmime_mk_trivial_ctor_with_name(ReplyTo)
788 };
789 
790 class MailCopiesToPrivate;
791 
792 /**
793   Represents a "Mail-Copies-To" header.
794 
795   @see http://www.newsreaders.com/misc/mail-copies-to.html
796 */
797 class KMIME_EXPORT MailCopiesTo : public Generics::AddressList
798 {
799     //@cond PRIVATE
800     kmime_mk_trivial_ctor_with_name(MailCopiesTo)
801     //@endcond
802 public:
803     QByteArray as7BitString(bool withHeaderType = true) const override;
804     QString asUnicodeString() const override;
805 
806     void clear() override;
807     bool isEmpty() const override;
808 
809     /**
810       Returns true if a mail copy was explicitly requested.
811     */
812     bool alwaysCopy() const;
813 
814     /**
815       Sets the header to "poster".
816     */
817     void setAlwaysCopy();
818 
819     /**
820       Returns true if a mail copy was explicitly denied.
821     */
822     bool neverCopy() const;
823 
824     /**
825       Sets the header to "never".
826     */
827     void setNeverCopy();
828 
829 protected:
830     bool parse(const char *&scursor, const char *const send, bool isCRLF = false) override;
831 
832 private:
833     Q_DECLARE_PRIVATE(MailCopiesTo)
834 };
835 
836 class ContentTransferEncodingPrivate;
837 
838 /**
839   Represents a "Content-Transfer-Encoding" header.
840 
841   @see RFC 2045, section 6.
842 */
843 class KMIME_EXPORT ContentTransferEncoding : public Generics::Token
844 {
845     //@cond PRIVATE
846     kmime_mk_trivial_ctor_with_name(ContentTransferEncoding)
847     //@endcond
848 public:
849     void clear() override;
850 
851     /**
852       Returns the encoding specified in this header.
853     */
854     contentEncoding encoding() const;
855 
856     /**
857       Sets the encoding to @p e.
858     */
859     void setEncoding(contentEncoding e);
860 
861     /**
862       Returns whether the Content containing this header is already decoded.
863     */
864     bool isDecoded() const;
865 
866     /**
867       Set whether the Content containing this header is already decoded.
868       For instance, if you fill your Content with already-encoded base64 data,
869       you will want to setDecoded( false ).
870       @param decoded if @c true the content is already decoded
871     */
872     void setDecoded(bool isDecoded = true);
873 
874     /**
875       Returns whether the Content containing this header needs to be encoded
876       (i.e., if decoded() is true and encoding() is base64 or quoted-printable).
877     */
878     bool needToEncode() const;
879 
880 protected:
881     bool parse(const char *&scursor, const char *const send, bool isCRLF = false) override;
882 
883 private:
884     Q_DECLARE_PRIVATE(ContentTransferEncoding)
885 };
886 
887 /**
888   Represents a "Keywords" header.
889 
890   @see RFC 2822, section 3.6.5.
891 */
892 class KMIME_EXPORT Keywords : public Generics::PhraseList
893 {
894     kmime_mk_trivial_ctor_with_name(Keywords)
895 };
896 
897 // DotAtom:
898 
899 /**
900   Represents a "MIME-Version" header.
901 
902   @see RFC 2045, section 4.
903 */
904 class KMIME_EXPORT MIMEVersion : public Generics::DotAtom
905 {
906     kmime_mk_trivial_ctor_with_name(MIMEVersion)
907 };
908 
909 // Ident:
910 
911 /**
912   Represents a "Message-ID" header.
913 
914   @see RFC 2822, section 3.6.4.
915 */
916 class KMIME_EXPORT MessageID : public Generics::SingleIdent
917 {
918     //@cond PRIVATE
919     kmime_mk_trivial_ctor_with_name(MessageID)
920     //@endcond
921 public:
922     /**
923       Generate a message identifier.
924       @param fqdn A fully qualified domain name.
925     */
926     void generate(const QByteArray &fqdn);
927 };
928 
929 class ContentIDPrivate;
930 
931 /**
932   Represents a "Content-ID" header.
933 */
934 class KMIME_EXPORT ContentID : public Generics::SingleIdent
935 {
936     //@cond PRIVATE
937     kmime_mk_trivial_ctor_with_name(ContentID)
938     kmime_mk_dptr_ctor(ContentID)
939     //@endcond
940 
941 protected:
942     bool parse(const char *&scursor, const char *const send, bool isCRLF = false) override;
943 private:
944     Q_DECLARE_PRIVATE(ContentID)
945 };
946 
947 /**
948   Represents a "Supersedes" header.
949 */
950 class KMIME_EXPORT Supersedes : public Generics::SingleIdent
951 {
952     kmime_mk_trivial_ctor_with_name(Supersedes)
953 };
954 
955 /**
956   Represents a "In-Reply-To" header.
957 
958   @see RFC 2822, section 3.6.4.
959 */
960 class KMIME_EXPORT InReplyTo : public Generics::Ident
961 {
962     kmime_mk_trivial_ctor_with_name(InReplyTo)
963 };
964 
965 /**
966   Represents a "References" header.
967 
968   @see RFC 2822, section 3.6.4.
969 */
970 class KMIME_EXPORT References : public Generics::Ident
971 {
972     kmime_mk_trivial_ctor_with_name(References)
973 };
974 
975 class ContentTypePrivate;
976 
977 /**
978   Represents a "Content-Type" header.
979 
980   @see RFC 2045, section 5.
981 */
982 class KMIME_EXPORT ContentType : public Generics::Parametrized
983 {
984     //@cond PRIVATE
985     kmime_mk_trivial_ctor_with_name(ContentType)
986     //@endcond
987 public:
988     QByteArray as7BitString(bool withHeaderType = true) const override;
989     void clear() override;
990     bool isEmpty() const override;
991 
992     /**
993       Returns the mimetype.
994     */
995     QByteArray mimeType() const;
996 
997     /**
998       Returns the media type (first part of the mimetype).
999     */
1000 
1001     QByteArray mediaType() const;
1002 
1003     /**
1004       Returns the mime sub-type (second part of the mimetype).
1005     */
1006     QByteArray subType() const;
1007 
1008     /**
1009       Sets the mimetype.
1010       @param mimeType The new mimetype.
1011     */
1012     void setMimeType(const QByteArray &mimeType);
1013 
1014     /**
1015       Tests if the media type equals @p mediatype.
1016     */
1017     bool isMediatype(const char *mediatype) const;
1018 
1019     /**
1020       Tests if the mime sub-type equals @p subtype.
1021     */
1022     bool isSubtype(const char *subtype) const;
1023 
1024     /**
1025       Tests if the mime type is @p mimeType.
1026     */
1027     bool isMimeType(const char *mimeType) const;
1028 
1029     /**
1030       Returns true if the associated MIME entity is a text.
1031     */
1032     bool isText() const;
1033 
1034     /**
1035       Returns true if the associated MIME entity is a plain text.
1036     */
1037     bool isPlainText() const;
1038 
1039     /**
1040       Returns true if the associated MIME entity is a HTML file.
1041     */
1042     bool isHTMLText() const;
1043 
1044     /**
1045       Returns true if the associated MIME entity is an image.
1046     */
1047     bool isImage() const;
1048 
1049     /**
1050       Returns true if the associated MIME entity is a multipart container.
1051     */
1052     bool isMultipart() const;
1053 
1054     /**
1055       Returns true if the associated MIME entity contains partial data.
1056       @see partialNumber(), partialCount()
1057     */
1058     bool isPartial() const;
1059 
1060     /**
1061       Returns the charset for the associated MIME entity.
1062     */
1063     QByteArray charset() const;
1064 
1065     /**
1066       Sets the charset.
1067     */
1068     void setCharset(const QByteArray &s);
1069 
1070     /**
1071       Returns the boundary (for multipart containers).
1072     */
1073     QByteArray boundary() const;
1074 
1075     /**
1076       Sets the multipart container boundary.
1077     */
1078     void setBoundary(const QByteArray &s);
1079 
1080     /**
1081       Returns the name of the associated MIME entity.
1082     */
1083     QString name() const;
1084 
1085     /**
1086       Sets the name to @p s using charset @p cs.
1087     */
1088     void setName(const QString &s, const QByteArray &cs);
1089 
1090     /**
1091       Returns the identifier of the associated MIME entity.
1092     */
1093     QByteArray id() const;
1094 
1095     /**
1096       Sets the identifier.
1097     */
1098     void setId(const QByteArray &s);
1099 
1100     /**
1101       Returns the position of this part in a multi-part set.
1102       @see isPartial(), partialCount()
1103     */
1104     int partialNumber() const;
1105 
1106     /**
1107       Returns the total number of parts in a multi-part set.
1108       @see isPartial(), partialNumber()
1109     */
1110     int partialCount() const;
1111 
1112     /**
1113       Sets parameters of a partial MIME entity.
1114       @param total The total number of entities in the multi-part set.
1115       @param number The number of this entity in a multi-part set.
1116     */
1117     void setPartialParams(int total, int number);
1118 
1119     // TODO: document
1120     contentCategory category() const;
1121 
1122     void setCategory(contentCategory c);
1123 
1124 protected:
1125     bool parse(const char *&scursor, const char *const send, bool isCRLF = false) override;
1126 
1127 private:
1128     Q_DECLARE_PRIVATE(ContentType)
1129 };
1130 
1131 class ContentDispositionPrivate;
1132 
1133 /**
1134   Represents a "Content-Disposition" header.
1135 
1136   @see RFC 2183
1137 */
1138 class KMIME_EXPORT ContentDisposition : public Generics::Parametrized
1139 {
1140     //@cond PRIVATE
1141     kmime_mk_trivial_ctor_with_name(ContentDisposition)
1142     //@endcond
1143 public:
1144     QByteArray as7BitString(bool withHeaderType = true) const override;
1145     bool isEmpty() const override;
1146     void clear() override;
1147 
1148     /**
1149       Returns the content disposition.
1150     */
1151     contentDisposition disposition() const;
1152 
1153     /**
1154       Sets the content disposition.
1155       @param disp The new content disposition.
1156     */
1157     void setDisposition(contentDisposition disp);
1158 
1159     /**
1160       Returns the suggested filename for the associated MIME part.
1161       This is just a convenience function, it is equivalent to calling
1162       parameter( "filename" );
1163     */
1164     QString filename() const;
1165 
1166     /**
1167       Sets the suggested filename for the associated MIME part.
1168       This is just a convenience function, it is equivalent to calling
1169       setParameter( "filename", filename );
1170       @param filename The filename.
1171     */
1172     void setFilename(const QString &filename);
1173 
1174 protected:
1175     bool parse(const char *&scursor, const char *const send, bool isCRLF = false) override;
1176 
1177 private:
1178     Q_DECLARE_PRIVATE(ContentDisposition)
1179 };
1180 
1181 //
1182 //
1183 // COMPATIBLE GUNSTRUCTURED-BASED FIELDS:
1184 //
1185 //
1186 
1187 class GenericPrivate;
1188 
1189 /**
1190   Represents an arbitrary header, that can contain any header-field.
1191   Adds a type over Unstructured.
1192   @see Unstructured
1193 */
1194 class KMIME_EXPORT Generic : public Generics::Unstructured
1195 {
1196 public:
1197     Generic();
1198     Generic(const char *t, int len = -1);
1199     ~Generic() override;
1200 
1201     void clear() override;
1202 
1203     bool isEmpty() const override;
1204 
1205     const char *type() const override;
1206 
1207     void setType(const char *type, int len = -1);
1208 
1209 private:
1210     Q_DECLARE_PRIVATE(Generic)
1211 };
1212 
1213 /**
1214   Represents a "Subject" header.
1215 
1216   @see RFC 2822, section 3.6.5.
1217 */
1218 class KMIME_EXPORT Subject : public Generics::Unstructured
1219 {
1220     //@cond PRIVATE
1221     kmime_mk_trivial_ctor_with_name(Subject)
1222     //@endcond
1223 };
1224 
1225 /**
1226   Represents a "Organization" header.
1227 */
1228 class KMIME_EXPORT Organization : public Generics::Unstructured
1229 {
1230     kmime_mk_trivial_ctor_with_name(Organization)
1231 };
1232 
1233 /**
1234   Represents a "Content-Description" header.
1235 */
1236 class KMIME_EXPORT ContentDescription : public Generics::Unstructured
1237 {
1238     kmime_mk_trivial_ctor_with_name(ContentDescription)
1239 };
1240 
1241 /**
1242   Represents a "Content-Location" header.
1243   @since 4.2
1244 */
1245 class KMIME_EXPORT ContentLocation : public Generics::Unstructured
1246 {
1247     kmime_mk_trivial_ctor_with_name(ContentLocation)
1248 };
1249 
1250 class ControlPrivate;
1251 
1252 /**
1253   Represents a "Control" header.
1254 
1255   @see RFC 1036, section 3.
1256 */
1257 class KMIME_EXPORT Control : public Generics::Structured
1258 {
1259     //@cond PRIVATE
1260     kmime_mk_trivial_ctor_with_name(Control)
1261     //@endcond
1262 public:
1263     QByteArray as7BitString(bool withHeaderType = true) const override;
1264     void clear() override;
1265     bool isEmpty() const override;
1266 
1267     /**
1268       Returns the control message type.
1269     */
1270     QByteArray controlType() const;
1271 
1272     /**
1273       Returns the control message parameter.
1274     */
1275     QByteArray parameter() const;
1276 
1277     /**
1278       Returns true if this is a cancel control message.
1279       @see RFC 1036, section 3.1.
1280     */
1281     bool isCancel() const;
1282 
1283     /**
1284       Changes this header into a cancel control message for the given message-id.
1285       @param msgid The message-id of the article that should be canceled.
1286     */
1287     void setCancel(const QByteArray &msgid);
1288 
1289 protected:
1290     bool parse(const char *&scursor, const char *const send, bool isCRLF = false) override;
1291 
1292 private:
1293     Q_DECLARE_PRIVATE(Control)
1294 };
1295 
1296 class DatePrivate;
1297 
1298 /**
1299   Represents a "Date" header.
1300 
1301   @see RFC 2822, section 3.3.
1302 */
1303 class KMIME_EXPORT Date : public Generics::Structured
1304 {
1305     //@cond PRIVATE
1306     kmime_mk_trivial_ctor_with_name(Date)
1307     //@endcond
1308 public:
1309     QByteArray as7BitString(bool withHeaderType = true) const override;
1310     void clear() override;
1311     bool isEmpty() const override;
1312 
1313     /**
1314       Returns the date contained in this header.
1315     */
1316     QDateTime dateTime() const;
1317 
1318     /**
1319       Sets the date.
1320     */
1321     void setDateTime(const QDateTime &dt);
1322 
1323     /**
1324       Returns the age of the message.
1325     */
1326     int ageInDays() const;
1327 
1328 protected:
1329     bool parse(const char *&scursor, const char *const send, bool isCRLF = false) override;
1330 
1331 private:
1332     Q_DECLARE_PRIVATE(Date)
1333 };
1334 
1335 class NewsgroupsPrivate;
1336 
1337 /**
1338   Represents a "Newsgroups" header.
1339 
1340   @see RFC 1036, section 2.1.3.
1341 */
1342 class KMIME_EXPORT Newsgroups : public Generics::Structured
1343 {
1344     //@cond PRIVATE
1345     kmime_mk_trivial_ctor_with_name(Newsgroups)
1346     //@endcond
1347 public:
1348     QByteArray as7BitString(bool withHeaderType = true) const override;
1349     void fromUnicodeString(const QString &s, const QByteArray &b) override;
1350     QString asUnicodeString() const override;
1351     void clear() override;
1352     bool isEmpty() const override;
1353 
1354     /**
1355       Returns the list of newsgroups.
1356     */
1357     QVector<QByteArray> groups() const;
1358 
1359     /**
1360       Sets the newsgroup list.
1361     */
1362     void setGroups(const QVector<QByteArray> &groups);
1363 
1364     /**
1365       Returns true if this message has been cross-posted, i.e. if it has been
1366       posted to multiple groups.
1367     */
1368     bool isCrossposted() const;
1369 
1370 protected:
1371     bool parse(const char *&scursor, const char *const send, bool isCRLF = false) override;
1372 
1373 private:
1374     Q_DECLARE_PRIVATE(Newsgroups)
1375 };
1376 
1377 /**
1378   Represents a "Followup-To" header.
1379 
1380   @see RFC 1036, section 2.2.3.
1381 */
1382 class KMIME_EXPORT FollowUpTo : public Newsgroups
1383 {
1384     //@cond PRIVATE
1385     kmime_mk_trivial_ctor_with_name(FollowUpTo)
1386     //@endcond
1387 };
1388 
1389 class LinesPrivate;
1390 
1391 /**
1392   Represents a "Lines" header.
1393 
1394   @see RFC 1036, section 2.2.12.
1395 */
1396 class KMIME_EXPORT Lines : public Generics::Structured
1397 {
1398     //@cond PRIVATE
1399     kmime_mk_trivial_ctor_with_name(Lines)
1400     //@endcond
1401 public:
1402     QByteArray as7BitString(bool withHeaderType = true) const override;
1403     QString asUnicodeString() const override;
1404     void clear() override;
1405     bool isEmpty() const override;
1406 
1407     /**
1408       Returns the number of lines, undefined if isEmpty() returns true.
1409     */
1410     int numberOfLines() const;
1411 
1412     /**
1413       Sets the number of lines to @p lines.
1414     */
1415     void setNumberOfLines(int lines);
1416 
1417 protected:
1418     bool parse(const char *&scursor, const char *const send, bool isCRLF = false) override;
1419 
1420 private:
1421     Q_DECLARE_PRIVATE(Lines)
1422 };
1423 
1424 /**
1425   Represents a "User-Agent" header.
1426 */
1427 class KMIME_EXPORT UserAgent : public Generics::Unstructured
1428 {
1429     kmime_mk_trivial_ctor_with_name(UserAgent)
1430 };
1431 
1432 /** Creates a header based on @param type. If @param type is a known header type,
1433  * the right object type will be created, otherwise a null pointer is returned. */
1434 KMIME_EXPORT Base *createHeader(const QByteArray &type);
1435 
1436 }  //namespace Headers
1437 
1438 }  //namespace KMime
1439 
1440 // undefine code generation macros again
1441 #undef kmime_mk_trivial_ctor
1442 #undef kmime_mk_dptr_ctor
1443 #undef kmime_mk_trivial_ctor_with_name
1444 
1445 Q_DECLARE_METATYPE(KMime::Headers::To*)
1446 Q_DECLARE_METATYPE(KMime::Headers::Cc*)
1447 Q_DECLARE_METATYPE(KMime::Headers::Bcc*)
1448 
1449