File indexing completed on 2024-09-22 04:52:49
0001 /* Copyright (C) 2006 - 2014 Jan Kundrát <jkt@flaska.net> 0002 0003 This file is part of the Trojita Qt IMAP e-mail client, 0004 http://trojita.flaska.net/ 0005 0006 This program is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU General Public License as 0008 published by the Free Software Foundation; either version 2 of 0009 the License or (at your option) version 3 or any later version 0010 accepted by the membership of KDE e.V. (or its successor approved 0011 by the membership of KDE e.V.), which shall act as a proxy 0012 defined in Section 14 of version 3 of the license. 0013 0014 This program is distributed in the hope that it will be useful, 0015 but WITHOUT ANY WARRANTY; without even the implied warranty of 0016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0017 GNU General Public License for more details. 0018 0019 You should have received a copy of the GNU General Public License 0020 along with this program. If not, see <http://www.gnu.org/licenses/>. 0021 */ 0022 0023 #ifndef IMAP_MESSAGE_H 0024 #define IMAP_MESSAGE_H 0025 0026 #include <QSharedPointer> 0027 #include <QByteArray> 0028 #include <QDebug> 0029 #include <QVariant> 0030 #include <QDateTime> 0031 #include <QString> 0032 #include <QPair> 0033 #include "Data.h" 0034 #include "../Exceptions.h" 0035 #include "MailAddress.h" 0036 #include "../Model/MailboxTreeFwd.h" 0037 0038 /** @short Namespace for IMAP interaction */ 0039 namespace Imap 0040 { 0041 0042 namespace Mailbox 0043 { 0044 class TreeItem; 0045 class TreeItemPart; 0046 } 0047 0048 /** @short Classes for handling e-mail messages */ 0049 namespace Message 0050 { 0051 0052 /** @short Storage for envelope */ 0053 class Envelope { 0054 public: 0055 QDateTime date; 0056 QString subject; 0057 QList<MailAddress> from; 0058 QList<MailAddress> sender; 0059 QList<MailAddress> replyTo; 0060 QList<MailAddress> to; 0061 QList<MailAddress> cc; 0062 QList<MailAddress> bcc; 0063 QList<QByteArray> inReplyTo; 0064 QByteArray messageId; 0065 0066 Envelope() {} 0067 Envelope(const QDateTime &date, const QString &subject, const QList<MailAddress> &from, 0068 const QList<MailAddress> &sender, const QList<MailAddress> &replyTo, 0069 const QList<MailAddress> &to, const QList<MailAddress> &cc, 0070 const QList<MailAddress> &bcc, const QList<QByteArray> &inReplyTo, 0071 const QByteArray &messageId): 0072 date(date), subject(subject), from(from), sender(sender), replyTo(replyTo), 0073 to(to), cc(cc), bcc(bcc), inReplyTo(inReplyTo), messageId(messageId) {} 0074 static Envelope fromList(const QVariantList &items, const QByteArray &line, const int start); 0075 QTextStream &dump(QTextStream &s, const int indent) const; 0076 0077 void clear(); 0078 0079 private: 0080 static QList<MailAddress> getListOfAddresses(const QVariant &in, 0081 const QByteArray &line, const int start); 0082 friend class Fetch; 0083 }; 0084 0085 0086 /** @short Abstract parent of all Message classes 0087 * 0088 * A message can be either one-part (OneMessage) or multipart (MultiMessage) 0089 * */ 0090 class AbstractMessage: public Responses::AbstractData { 0091 public: 0092 typedef QMap<QByteArray,QByteArray> bodyFldParam_t; 0093 typedef QPair<QByteArray, bodyFldParam_t> bodyFldDsp_t; 0094 0095 // Common fields 0096 QByteArray mediaType; 0097 QByteArray mediaSubType; 0098 // Common optional fields 0099 bodyFldParam_t bodyFldParam; 0100 bodyFldDsp_t bodyFldDsp; 0101 QList<QByteArray> bodyFldLang; 0102 QByteArray bodyFldLoc; 0103 QVariant bodyExtension; 0104 0105 virtual ~AbstractMessage() {} 0106 static QSharedPointer<AbstractMessage> fromList(const QVariantList &items, const QByteArray &line, const int start); 0107 0108 static bodyFldParam_t makeBodyFldParam(const QVariant &list, const QByteArray &line, const int start); 0109 static bodyFldDsp_t makeBodyFldDsp(const QVariant &list, const QByteArray &line, const int start); 0110 static QList<QByteArray> makeBodyFldLang(const QVariant &input, const QByteArray &line, const int start); 0111 0112 QTextStream &dump(QTextStream &s) const override { return dump(s, 0); } 0113 virtual QTextStream &dump(QTextStream &s, const int indent) const = 0; 0114 virtual Mailbox::TreeItemChildrenList createTreeItems(Mailbox::TreeItem *parent) const = 0; 0115 0116 AbstractMessage(const QByteArray &mediaType, const QByteArray &mediaSubType, const bodyFldParam_t &bodyFldParam, 0117 const bodyFldDsp_t &bodyFldDsp, const QList<QByteArray> &bodyFldLang, const QByteArray &bodyFldLoc, 0118 const QVariant &bodyExtension): 0119 mediaType(mediaType), mediaSubType(mediaSubType), bodyFldParam(bodyFldParam), bodyFldDsp(bodyFldDsp), 0120 bodyFldLang(bodyFldLang), bodyFldLoc(bodyFldLoc), bodyExtension(bodyExtension) {} 0121 protected: 0122 static uint extractUInt(const QVariant &var, const QByteArray &line, const int start); 0123 static quint64 extractUInt64(const QVariant &var, const QByteArray &line, const int start); 0124 virtual void storeInterestingFields(Mailbox::TreeItemPart *p) const; 0125 }; 0126 0127 /** @short Abstract parent class for all non-multipart messages */ 0128 class OneMessage: public AbstractMessage { 0129 public: 0130 QByteArray bodyFldId; 0131 QByteArray bodyFldDesc; 0132 QByteArray bodyFldEnc; 0133 quint64 bodyFldOctets; 0134 // optional fields specific to non-multipart: 0135 QByteArray bodyFldMd5; 0136 OneMessage(const QByteArray &mediaType, const QByteArray &mediaSubType, 0137 const bodyFldParam_t &bodyFldParam, const QByteArray &bodyFldId, 0138 const QByteArray &bodyFldDesc, const QByteArray &bodyFldEnc, 0139 const quint64 bodyFldOctets, const QByteArray &bodyFldMd5, 0140 const bodyFldDsp_t &bodyFldDsp, 0141 const QList<QByteArray> &bodyFldLang, const QByteArray &bodyFldLoc, 0142 const QVariant &bodyExtension): 0143 AbstractMessage(mediaType, mediaSubType, bodyFldParam, bodyFldDsp, bodyFldLang, bodyFldLoc, bodyExtension), 0144 bodyFldId(bodyFldId), bodyFldDesc(bodyFldDesc), 0145 bodyFldEnc(bodyFldEnc), bodyFldOctets(bodyFldOctets), bodyFldMd5(bodyFldMd5) {} 0146 0147 bool eq(const AbstractData &other) const override; 0148 0149 protected: 0150 void storeInterestingFields(Mailbox::TreeItemPart *p) const override; 0151 }; 0152 0153 /** @short Ordinary Message (body-type-basic in RFC3501) */ 0154 class BasicMessage: public OneMessage { 0155 public: 0156 // nothing new, just stuff from OneMessage 0157 BasicMessage(const QByteArray &mediaType, const QByteArray &mediaSubType, 0158 const bodyFldParam_t &bodyFldParam, const QByteArray &bodyFldId, 0159 const QByteArray &bodyFldDesc, const QByteArray &bodyFldEnc, 0160 const quint64 bodyFldOctets, const QByteArray &bodyFldMd5, 0161 const bodyFldDsp_t &bodyFldDsp, 0162 const QList<QByteArray> &bodyFldLang, const QByteArray &bodyFldLoc, 0163 const QVariant &bodyExtension): 0164 OneMessage(mediaType, mediaSubType, bodyFldParam, bodyFldId, 0165 bodyFldDesc, bodyFldEnc, bodyFldOctets, bodyFldMd5, 0166 bodyFldDsp, bodyFldLang, bodyFldLoc, bodyExtension) {}; 0167 QTextStream &dump(QTextStream &s, const int indent) const override; 0168 using OneMessage::dump; 0169 /* No need for "virtual bool eq( const AbstractData& other ) const" as 0170 * it's already implemented in OneMessage::eq() */ 0171 Mailbox::TreeItemChildrenList createTreeItems(Mailbox::TreeItem *parent) const override; 0172 }; 0173 0174 /** @short A message holding another RFC822 message (body-type-msg) */ 0175 class MsgMessage: public OneMessage { 0176 public: 0177 Envelope envelope; 0178 QSharedPointer<AbstractMessage> body; 0179 uint bodyFldLines; 0180 MsgMessage(const QByteArray &mediaType, const QByteArray &mediaSubType, 0181 const bodyFldParam_t &bodyFldParam, const QByteArray &bodyFldId, 0182 const QByteArray &bodyFldDesc, const QByteArray &bodyFldEnc, 0183 const quint64 bodyFldOctets, const QByteArray &bodyFldMd5, 0184 const bodyFldDsp_t &bodyFldDsp, 0185 const QList<QByteArray> &bodyFldLang, const QByteArray &bodyFldLoc, 0186 const QVariant &bodyExtension, 0187 const Envelope &envelope, const QSharedPointer<AbstractMessage> &body, 0188 const uint bodyFldLines): 0189 OneMessage(mediaType, mediaSubType, bodyFldParam, bodyFldId, 0190 bodyFldDesc, bodyFldEnc, bodyFldOctets, bodyFldMd5, 0191 bodyFldDsp, bodyFldLang, bodyFldLoc, bodyExtension), 0192 envelope(envelope), body(body), bodyFldLines(bodyFldLines) {} 0193 QTextStream &dump(QTextStream &s, const int indent) const override; 0194 using OneMessage::dump; 0195 bool eq(const AbstractData &other) const override; 0196 Mailbox::TreeItemChildrenList createTreeItems(Mailbox::TreeItem *parent) const override; 0197 }; 0198 0199 /** @short A text message (body-type-text) */ 0200 class TextMessage: public OneMessage { 0201 public: 0202 uint bodyFldLines; 0203 TextMessage(const QByteArray &mediaType, const QByteArray &mediaSubType, 0204 const bodyFldParam_t &bodyFldParam, const QByteArray &bodyFldId, 0205 const QByteArray &bodyFldDesc, const QByteArray &bodyFldEnc, 0206 const quint64 bodyFldOctets, const QByteArray &bodyFldMd5, 0207 const bodyFldDsp_t &bodyFldDsp, 0208 const QList<QByteArray> &bodyFldLang, const QByteArray &bodyFldLoc, 0209 const QVariant &bodyExtension, 0210 const uint bodyFldLines): 0211 OneMessage(mediaType, mediaSubType, bodyFldParam, bodyFldId, 0212 bodyFldDesc, bodyFldEnc, bodyFldOctets, bodyFldMd5, 0213 bodyFldDsp, bodyFldLang, bodyFldLoc, bodyExtension), 0214 bodyFldLines(bodyFldLines) {} 0215 QTextStream &dump(QTextStream &s, const int indent) const override; 0216 using OneMessage::dump; 0217 bool eq(const AbstractData &other) const override; 0218 Mailbox::TreeItemChildrenList createTreeItems(Mailbox::TreeItem *parent) const override; 0219 }; 0220 0221 /** @short Multipart message (body-type-mpart) */ 0222 class MultiMessage: public AbstractMessage { 0223 public: 0224 QList<QSharedPointer<AbstractMessage> > bodies; 0225 0226 MultiMessage(const QList<QSharedPointer<AbstractMessage> > &bodies, 0227 const QByteArray &mediaSubType, const bodyFldParam_t &bodyFldParam, 0228 const bodyFldDsp_t &bodyFldDsp, 0229 const QList<QByteArray> &bodyFldLang, const QByteArray &bodyFldLoc, 0230 const QVariant &bodyExtension): 0231 AbstractMessage("multipart", mediaSubType, bodyFldParam, bodyFldDsp, bodyFldLang, bodyFldLoc, bodyExtension), 0232 bodies(bodies) {} 0233 QTextStream &dump(QTextStream &s, const int indent) const override; 0234 using AbstractMessage::dump; 0235 bool eq(const AbstractData &other) const override; 0236 Mailbox::TreeItemChildrenList createTreeItems(Mailbox::TreeItem *parent) const override; 0237 protected: 0238 void storeInterestingFields(Mailbox::TreeItemPart *p) const override; 0239 }; 0240 0241 QTextStream &operator<<(QTextStream &stream, const Envelope &e); 0242 QTextStream &operator<<(QTextStream &stream, const AbstractMessage::bodyFldParam_t &p); 0243 QTextStream &operator<<(QTextStream &stream, const AbstractMessage::bodyFldDsp_t &p); 0244 QTextStream &operator<<(QTextStream &stream, const QList<QByteArray> &list); 0245 0246 bool operator==(const Envelope &a, const Envelope &b); 0247 inline bool operator!=(const Envelope &a, const Envelope &b) { return !(a == b); } 0248 0249 } 0250 0251 } 0252 0253 QDebug operator<<(QDebug dbg, const Imap::Message::Envelope &envelope); 0254 0255 QDataStream &operator>>(QDataStream &stream, Imap::Message::Envelope &e); 0256 QDataStream &operator<<(QDataStream &stream, const Imap::Message::Envelope &e); 0257 0258 Q_DECLARE_METATYPE(Imap::Message::Envelope) 0259 0260 #endif /* IMAP_MESSAGE_H */