File indexing completed on 2024-09-22 04:52:51
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 #ifndef IMAP_RESPONSE_H 0023 #define IMAP_RESPONSE_H 0024 0025 #include <QMap> 0026 #include <QPair> 0027 #include <QSharedPointer> 0028 #include <QStringList> 0029 #include <QTextStream> 0030 #include <QVariantList> 0031 #include <QVector> 0032 #include "Command.h" 0033 #include "../Exceptions.h" 0034 #include "Data.h" 0035 #include "ThreadingNode.h" 0036 #include "Uids.h" 0037 0038 class QSslCertificate; 0039 class QSslError; 0040 0041 /** 0042 * @file 0043 * @short Various data structures related to IMAP responses 0044 * 0045 * @author Jan Kundrát <jkt@flaska.net> 0046 */ 0047 0048 /** @short Namespace for IMAP interaction */ 0049 namespace Imap 0050 { 0051 0052 namespace Mailbox 0053 { 0054 class Model; 0055 class ImapTask; 0056 } 0057 0058 class Parser; 0059 0060 /** @short IMAP server responses 0061 * 0062 * @ref AbstractResponse is an abstact parent of all classes. Each response 0063 * that might be received from the server is a child of this one. 0064 * */ 0065 namespace Responses 0066 { 0067 0068 /** @short Result of a command */ 0069 enum Kind { 0070 OK /**< @short OK */, 0071 NO /**< @short NO */, 0072 BAD /**< @short BAD */, 0073 BYE, 0074 PREAUTH, 0075 EXPUNGE, 0076 FETCH, 0077 EXISTS, 0078 RECENT, 0079 CAPABILITY, 0080 LIST, 0081 LSUB, 0082 FLAGS, 0083 SEARCH, 0084 ESEARCH, /**< @short RFC 4731 ESEARCH */ 0085 STATUS, 0086 NAMESPACE, 0087 SORT, 0088 THREAD, 0089 ID, 0090 ENABLED, /**< @short RFC 5161 ENABLE */ 0091 VANISHED, /**< @short RFC 5162 VANISHED (for QRESYNC) */ 0092 GENURLAUTH /**< @short GENURLAUTH, RFC 4467 */ 0093 }; // aren't those comments just sexy? :) 0094 0095 /** @short Response Code */ 0096 enum Code { 0097 NONE /**< @short No response code specified */, 0098 ATOM /**< @short Not recognized */, 0099 ALERT /**< @short ALERT */, 0100 BADCHARSET /**< @short BADCHARSET */, 0101 /** @short CAPABILITY. 0102 * 0103 * Yeah, it's different than the RFC3501 name for it. 0104 * Responses::Kind already defines a CAPABILITY and we aren't using 0105 * C++0x yet. 0106 * 0107 * */ 0108 CAPABILITIES, 0109 PARSE /**< @short PARSE */, 0110 PERMANENTFLAGS /**< @short PERMANENTFLAGS */, 0111 READ_ONLY /**< @short READ-ONLY */, 0112 READ_WRITE /**< @short READ-WRITE */, 0113 TRYCREATE /**< @short TRYCREATE */, 0114 UIDNEXT /**< @short UIDNEXT */, 0115 UIDVALIDITY /**< @short UIDVALIDITY */, 0116 UNSEEN /**< @short UNSEEN */, 0117 0118 // obsolete from RFC 2060 0119 NEWNAME /**< Obsolete NEWNAME from RFC 2060 */, 0120 0121 // RFC 2221 0122 REFERRAL /**< REFERRAL from RFC 2221 */, 0123 0124 // RFC 3516 0125 UNKNOWN_CTE /**< UNKNOWN-CTE from RFC 3516 */, 0126 0127 // RFC 4315 0128 UIDNOTSTICKY /**< UIDNOTSTICKY from RFC 4315 */, 0129 APPENDUID /**< APPENDUID from RFC 4315 */, 0130 COPYUID /**< COPYUID from RFC 4315 */, 0131 0132 // RFC 4467 0133 URLMECH /**< URLMECH from RFC 4467 */, 0134 0135 // RFC 4469 0136 TOOBIG /**< RFC 4469's TOOBIG */, 0137 BADURL /**< BADURL from RFC 4469 */, 0138 0139 // RFC 4551 0140 HIGHESTMODSEQ /**< HIGHESTMODSEQ from RFC 4451 */, 0141 NOMODSEQ /**< NOMODSEQ from RFC 4551 */, 0142 MODIFIED /**< MODIFIED from RFC 4551 */, 0143 0144 // RFC 4978 0145 COMPRESSIONACTIVE /**< COMPRESSIONACTIVE from RFC 4978 */, 0146 0147 // RFC 5162 0148 CLOSED /**< CLOSED from the QRESYNC RFC 5162 */, 0149 0150 // RFC 5182 0151 NOTSAVED /**< NOTSAVED from RFC 5182 */, 0152 0153 // RFC 5255 0154 BADCOMPARATOR /**< BADCOMPARATOR from RFC 5255 */, 0155 0156 // RFC 5257 0157 ANNOTATE /**< ANNOTATE from RFC 5257 */, 0158 ANNOTATIONS /**< ANNOTATIONS from RFC 5257 */, 0159 0160 // RFC 5259 0161 TEMPFAIL /**< TEMPFAIL from RFC 5259 */, 0162 MAXCONVERTMESSAGES /**< MAXCONVERTMESSAGES from RFC 5259 */, 0163 MAXCONVERTPARTS /**< MAXCONVERTPARTS from RFC 5259 */, 0164 0165 // RFC 5267 0166 NOUPDATE /**< NOUPDATE from RFC 5267 */, 0167 0168 // RFC 5464 0169 METADATA /**< METADATA from RFC 5464 */, 0170 0171 // RFC 5465 0172 NOTIFICATIONOVERFLOW /**< NOTIFICATIONOVERFLOW from RFC 5465 */, 0173 BADEVENT /**< BADEVENT from RFC 5465 */, 0174 0175 // RFC 5466 0176 UNDEFINED_FILTER /**< UNDEFINED-FILTER from RFC 5466 */, 0177 0178 // RFC5530 0179 UNAVAILABLE /**< UNAVAILABLE from RFC 5530 */, 0180 AUTHENTICATIONFAILED /**< AUTHENTICATIONFAILED from RFC 5530 */, 0181 AUTHORIZATIONFAILED /**< AUTHORIZATIONFAILED from RFC 5530 */, 0182 EXPIRED /**< EXPIRED from RFC 5530 */, 0183 PRIVACYREQUIRED /**< PRIVACYREQUIRED from RFC 5530 */, 0184 CONTACTADMIN /**< CONTACTADMIN from RFC 5530 */, 0185 NOPERM /**< NOPERM from RFC 5530 */, 0186 INUSE /**< INUSE from RFC 5530 */, 0187 EXPUNGEISSUED /**< EXPUNGEISSUED from RFC 5530 */, 0188 CORRUPTION /**< CORRUPTION from RFC 5530 */, 0189 SERVERBUG /**< SERVERBUG from RFC 5530 */, 0190 CLIENTBUG /**< CLIENTBUG from RFC 5530 */, 0191 CANNOT /**< CANNOT from RFC 5530 */, 0192 LIMIT /**< LIMIT from RFC 5530 */, 0193 OVERQUOTA /**< OVERQUOTA from RFC 5530 */, 0194 ALREADYEXISTS /**< ALREADYEXISTS from RFC 5530 */, 0195 NONEXISTENT /**< NONEXISTENT from RFC 5530 */, 0196 0197 // draft-imap-sendmail by yours truly 0198 POLICYDENIED, 0199 SUBMISSIONRACE 0200 0201 }; // luvly comments, huh? :) 0202 0203 /** @short Parent class for all server responses */ 0204 class AbstractResponse 0205 { 0206 public: 0207 AbstractResponse() {} 0208 virtual ~AbstractResponse(); 0209 /** @short Helper for operator<<() */ 0210 virtual QTextStream &dump(QTextStream &) const = 0; 0211 /** @short Helper for operator==() */ 0212 virtual bool eq(const AbstractResponse &other) const = 0; 0213 /** @short Helper for Imap::Mailbox::MailboxModel to prevent ugly 0214 * dynamic_cast<>s */ 0215 virtual void plug(Imap::Parser *parser, Imap::Mailbox::Model *model) const = 0; 0216 virtual bool plug(Imap::Mailbox::ImapTask *task) const = 0; 0217 }; 0218 0219 /** @short Structure storing OK/NO/BAD/PREAUTH/BYE responses */ 0220 class State : public AbstractResponse 0221 { 0222 public: 0223 /** @short Tag name or QString::null if untagged */ 0224 QByteArray tag; 0225 0226 /** @short Kind of response 0227 * 0228 * A tagged status response might be either OK, NO or BAD. 0229 * Untagged status response might be either te same as tagged or BYE or 0230 * PREAUTH. 0231 * */ 0232 Kind kind; 0233 0234 /** @short Textual information embedded in the response 0235 * 0236 * While this information might be handy for correct understanding of 0237 * what happens at ther server, its value is not standardized so the 0238 * meaning is usually either duplicate to what's already said elsewhere 0239 * or only a hint to the user. Nevertheless, we decode and store it. 0240 * */ 0241 QString message; 0242 0243 /** @short Kind of optional Response Code 0244 * 0245 * For each supported value, type of ResponseCodeData stored in the 0246 * respCodeData is defined as follows: 0247 * 0248 * ALERT, PARSE, READ_ONLY, READ_WRITE, TRYCREATE: 0249 * Nothing else should be included, ie. void 0250 * 0251 * UIDNEXT, UIDVALIDITY, UNSEEN: 0252 * Only number, ie. unsigned int 0253 * 0254 * BADCHARSET, PERMANENTFLAGS: 0255 * List of strings, ie. QStringList 0256 * 0257 * default: 0258 * Any data, ie. QString 0259 * */ 0260 Code respCode; 0261 0262 /** @short Response Code Data 0263 * 0264 * Format is explained in the respCode documentation. 0265 * We have to use pointer indirection because virtual methods wouldn't 0266 * work otherwise. 0267 * */ 0268 QSharedPointer<AbstractData> respCodeData; 0269 0270 /** @short Default constructor 0271 * 0272 * No error checking takes place, we assume _respCodeData's type 0273 * actually corresponds to all invariants we declare as per respCode's 0274 * documentation. 0275 * */ 0276 State(const QByteArray &tag, const Kind kind, const QString &message, const Code respCode, const QSharedPointer<AbstractData> respCodeData): 0277 tag(tag), kind(kind), message(message), respCode(respCode), respCodeData(respCodeData) {} 0278 0279 /** @short "Smart" constructor that parses a response out of a QByteArray */ 0280 State(const QByteArray &tag, const Kind kind, const QByteArray &line, int &start); 0281 0282 /** @short Default destructor that makes containers and QtTest happy */ 0283 State(): respCode(NONE) {} 0284 0285 /** @short helper for operator<<( QTextStream& ) */ 0286 QTextStream &dump(QTextStream &s) const override; 0287 bool eq(const AbstractResponse &other) const override; 0288 void plug(Imap::Parser *parser, Imap::Mailbox::Model *model) const override; 0289 bool plug(Imap::Mailbox::ImapTask *task) const override; 0290 }; 0291 0292 /** @short Structure storing a CAPABILITY untagged response */ 0293 class Capability : public AbstractResponse 0294 { 0295 public: 0296 /** @short List of capabilities */ 0297 QStringList capabilities; 0298 Capability(const QStringList &capabilities): capabilities(capabilities) {} 0299 QTextStream &dump(QTextStream &s) const override; 0300 bool eq(const AbstractResponse &other) const override; 0301 void plug(Imap::Parser *parser, Imap::Mailbox::Model *model) const override; 0302 bool plug(Imap::Mailbox::ImapTask *task) const override; 0303 }; 0304 0305 /** @short Structure for EXISTS/EXPUNGE/RECENT responses */ 0306 class NumberResponse : public AbstractResponse 0307 { 0308 public: 0309 Kind kind; 0310 /** @short Number that we're storing */ 0311 uint number; 0312 NumberResponse(const Kind kind, const uint number); 0313 QTextStream &dump(QTextStream &s) const override; 0314 bool eq(const AbstractResponse &other) const override; 0315 void plug(Imap::Parser *parser, Imap::Mailbox::Model *model) const override; 0316 bool plug(Imap::Mailbox::ImapTask *task) const override; 0317 }; 0318 0319 /** @short Structure storing a LIST untagged response */ 0320 class List : public AbstractResponse 0321 { 0322 public: 0323 /** @short LIST or LSUB */ 0324 Kind kind; 0325 /** @short Flags for this particular mailbox */ 0326 QStringList flags; 0327 /** @short Hierarchy separator 0328 * 0329 * QString::null in case original response containded NIL 0330 * */ 0331 QString separator; 0332 /** @short Mailbox name */ 0333 QString mailbox; 0334 0335 /** @short Extended LIST data (mbox-list-extended from RFC5258) */ 0336 QMap<QByteArray, QVariant> extendedData; 0337 0338 /** @short Parse line and construct List object from it */ 0339 List(const Kind kind, const QByteArray &line, int &start); 0340 List(const Kind kind, const QStringList &flags, const QString &separator, const QString &mailbox, 0341 const QMap<QByteArray, QVariant> &extendedData): 0342 kind(kind), flags(flags), separator(separator), mailbox(mailbox), extendedData(extendedData) {} 0343 QTextStream &dump(QTextStream &s) const override; 0344 bool eq(const AbstractResponse &other) const override; 0345 void plug(Imap::Parser *parser, Imap::Mailbox::Model *model) const override; 0346 bool plug(Imap::Mailbox::ImapTask *task) const override; 0347 }; 0348 0349 struct NamespaceData { 0350 QString prefix; 0351 QString separator; 0352 NamespaceData(const QString &prefix, const QString &separator): prefix(prefix), separator(separator) {}; 0353 bool operator==(const NamespaceData &other) const; 0354 bool operator!=(const NamespaceData &other) const; 0355 static QList<NamespaceData> listFromLine(const QByteArray &line, int &start); 0356 }; 0357 0358 /** @short Structure storing a NAMESPACE untagged response */ 0359 class Namespace : public AbstractResponse 0360 { 0361 public: 0362 QList<NamespaceData> personal, users, other; 0363 /** @short Parse line and construct List object from it */ 0364 Namespace(const QByteArray &line, int &start); 0365 Namespace(const QList<NamespaceData> &personal, const QList<NamespaceData> &users, 0366 const QList<NamespaceData> &other): 0367 personal(personal), users(users), other(other) {}; 0368 QTextStream &dump(QTextStream &s) const override; 0369 bool eq(const AbstractResponse &other) const override; 0370 void plug(Imap::Parser *parser, Imap::Mailbox::Model *model) const override; 0371 bool plug(Imap::Mailbox::ImapTask *task) const override; 0372 }; 0373 0374 0375 /** @short Structure storing a FLAGS untagged response */ 0376 class Flags : public AbstractResponse 0377 { 0378 public: 0379 /** @short List of flags */ 0380 QStringList flags; 0381 Flags(const QStringList &flags) : flags(flags) {}; 0382 Flags(const QByteArray &line, int &start); 0383 QTextStream &dump(QTextStream &s) const override; 0384 bool eq(const AbstractResponse &other) const override; 0385 void plug(Imap::Parser *parser, Imap::Mailbox::Model *model) const override; 0386 bool plug(Imap::Mailbox::ImapTask *task) const override; 0387 }; 0388 0389 /** @short Structure storing a SEARCH untagged response */ 0390 class Search : public AbstractResponse 0391 { 0392 public: 0393 /** @short List of matching messages */ 0394 Uids items; 0395 Search(const QByteArray &line, int &start); 0396 Search(const Uids &items) : items(items) {}; 0397 QTextStream &dump(QTextStream &s) const override; 0398 bool eq(const AbstractResponse &other) const override; 0399 void plug(Imap::Parser *parser, Imap::Mailbox::Model *model) const override; 0400 bool plug(Imap::Mailbox::ImapTask *task) const override; 0401 }; 0402 0403 /** @short Structure storing an ESEARCH untagged response */ 0404 class ESearch : public AbstractResponse 0405 { 0406 public: 0407 /** @short Is the response given in UIDs, or just in sequence numbers */ 0408 typedef enum { 0409 SEQUENCE, /**< @short In sequence numbers */ 0410 UIDS /**< @short In UIDs */ 0411 } SequencesOrUids; 0412 0413 /** @short Convenience typedef for the received data of the list type */ 0414 typedef QVector<QPair<QByteArray, Uids>> ListData_t; 0415 0416 /** @short Represent one item to be added/removed by an incremental SEARCH/SORT response */ 0417 struct ContextIncrementalItem { 0418 0419 /** @short Is this incremental update record about adding an item, or removing it? 0420 0421 These correspond to RFC 5267's ADDTO and REMOVEFROM identifiers. 0422 */ 0423 typedef enum { 0424 ADDTO, /**< ADDTO, adding items to the search/sort criteria */ 0425 REMOVEFROM /**< REMOVEFROM, removing items from the list of matches */ 0426 } Modification; 0427 0428 /** @short Type of modification */ 0429 Modification modification; 0430 0431 /** @short Offset at which the modification shall be performed */ 0432 uint offset; 0433 0434 /** @short Sequence of UIDs to apply */ 0435 Uids uids; 0436 0437 ContextIncrementalItem(const Modification modification, const uint offset, const Uids &uids): 0438 modification(modification), offset(offset), uids(uids) {} 0439 0440 bool operator==(const ContextIncrementalItem &other) const { 0441 return modification == other.modification && offset == other.offset && uids == other.uids; 0442 } 0443 }; 0444 0445 typedef QList<ContextIncrementalItem> IncrementalContextData_t; 0446 0447 /** @short The tag of the command which requested in this operation */ 0448 QByteArray tag; 0449 0450 /** @short Are the numbers given in UIDs, or as sequence numbers? */ 0451 SequencesOrUids seqOrUids; 0452 0453 /** @short The received data: list of numbers */ 0454 ListData_t listData; 0455 0456 /** @short The received data: incremental updates to SEARCH/SORT according to RFC 5267 */ 0457 IncrementalContextData_t incrementalContextData; 0458 0459 /** @short Incremental threading information along its identifier and the preceding thread root in an ESEARCH response */ 0460 struct IncrementalThreadingItem_t { 0461 /** @short UID of the previous thread root's item or 0 if there's no previous item */ 0462 uint previousThreadRoot; 0463 0464 /** @short A complete subthread */ 0465 QVector<ThreadingNode> thread; 0466 0467 IncrementalThreadingItem_t(const uint previousThreadRoot, const QVector<ThreadingNode> &thread): 0468 previousThreadRoot(previousThreadRoot), thread(thread) {} 0469 0470 bool operator==(const IncrementalThreadingItem_t &other) const { 0471 return previousThreadRoot == other.previousThreadRoot && thread == other.thread; 0472 } 0473 }; 0474 0475 /** @short Typedef for all threading data sent over ESEARCH */ 0476 typedef QList<IncrementalThreadingItem_t> IncrementalThreadingData_t; 0477 0478 /** @short The threading information, draft-imap-incthread */ 0479 IncrementalThreadingData_t incThreadData; 0480 0481 // Other forms of returned data are quite explicitly not supported. 0482 0483 ESearch(const QByteArray &line, int &start); 0484 ESearch(const QByteArray &tag, const SequencesOrUids seqOrUids, const ListData_t &listData) : 0485 tag(tag), seqOrUids(seqOrUids), listData(listData) {} 0486 ESearch(const QByteArray &tag, const SequencesOrUids seqOrUids, const IncrementalContextData_t &incrementalContextData) : 0487 tag(tag), seqOrUids(seqOrUids), incrementalContextData(incrementalContextData) {} 0488 ESearch(const QByteArray &tag, const SequencesOrUids seqOrUids, const IncrementalThreadingData_t &incThreadData): 0489 tag(tag), seqOrUids(seqOrUids), incThreadData(incThreadData) {} 0490 QTextStream &dump(QTextStream &stream) const override; 0491 bool eq(const AbstractResponse &other) const override; 0492 void plug(Imap::Parser *parser, Imap::Mailbox::Model *model) const override; 0493 bool plug(Imap::Mailbox::ImapTask *task) const override; 0494 }; 0495 0496 /** @short Structure storing a STATUS untagged response */ 0497 class Status : public AbstractResponse 0498 { 0499 public: 0500 /** @short Indentifies type of status data */ 0501 enum StateKind { 0502 MESSAGES, 0503 RECENT, 0504 UIDNEXT, 0505 UIDVALIDITY, 0506 UNSEEN 0507 }; 0508 0509 typedef QMap<StateKind,uint> stateDataType; 0510 0511 /** @short Mailbox name */ 0512 QString mailbox; 0513 /** @short Associative array of states */ 0514 stateDataType states; 0515 0516 Status(const QString &mailbox, const stateDataType &states) : 0517 mailbox(mailbox), states(states) {}; 0518 Status(const QByteArray &line, int &start); 0519 QTextStream &dump(QTextStream &s) const override; 0520 bool eq(const AbstractResponse &other) const override; 0521 static StateKind stateKindFromStr(QString s); 0522 void plug(Imap::Parser *parser, Imap::Mailbox::Model *model) const override; 0523 bool plug(Imap::Mailbox::ImapTask *task) const override; 0524 }; 0525 0526 /** @short FETCH response */ 0527 class Fetch : public AbstractResponse 0528 { 0529 public: 0530 typedef QMap<QByteArray,QSharedPointer<AbstractData> > dataType; 0531 0532 /** @short Sequence number of message that we're working with */ 0533 uint number; 0534 0535 /** @short Fetched items */ 0536 dataType data; 0537 0538 Fetch(const uint number, const QByteArray &line, int &start); 0539 Fetch(const uint number, const dataType &data); 0540 QTextStream &dump(QTextStream &s) const override; 0541 bool eq(const AbstractResponse &other) const override; 0542 void plug(Imap::Parser *parser, Imap::Mailbox::Model *model) const override; 0543 bool plug(Imap::Mailbox::ImapTask *task) const override; 0544 private: 0545 static QDateTime dateify(QByteArray str, const QByteArray &line, const int start); 0546 }; 0547 0548 /** @short Structure storing a SORT untagged response */ 0549 class Sort : public AbstractResponse 0550 { 0551 public: 0552 /** @short List of sequence/UID numbers as returned by the server */ 0553 Uids numbers; 0554 Sort(const QByteArray &line, int &start); 0555 Sort(const Uids &items): numbers(items) {} 0556 QTextStream &dump(QTextStream &s) const override; 0557 bool eq(const AbstractResponse &other) const override; 0558 void plug(Imap::Parser *parser, Imap::Mailbox::Model *model) const override; 0559 bool plug(Imap::Mailbox::ImapTask *task) const override; 0560 }; 0561 0562 /** @short Structure storing a THREAD untagged response */ 0563 class Thread : public AbstractResponse 0564 { 0565 public: 0566 /** @short List of "top-level" messages */ 0567 QVector<ThreadingNode> rootItems; 0568 Thread(const QByteArray &line, int &start); 0569 Thread(const QVector<ThreadingNode> &items): rootItems(items) {} 0570 QTextStream &dump(QTextStream &s) const override; 0571 bool eq(const AbstractResponse &other) const override; 0572 void plug(Imap::Parser *parser, Imap::Mailbox::Model *model) const override; 0573 bool plug(Imap::Mailbox::ImapTask *task) const override; 0574 }; 0575 0576 /** @short Structure storing the result of the ID command */ 0577 class Id : public AbstractResponse 0578 { 0579 public: 0580 /** @short List of sequence/UID numbers as returned by the server */ 0581 QMap<QByteArray,QByteArray> data; 0582 Id(const QByteArray &line, int &start); 0583 Id(const QMap<QByteArray,QByteArray> &items): data(items) {} 0584 QTextStream &dump(QTextStream &s) const override; 0585 bool eq(const AbstractResponse &other) const override; 0586 void plug(Imap::Parser *parser, Imap::Mailbox::Model *model) const override; 0587 bool plug(Imap::Mailbox::ImapTask *task) const override; 0588 }; 0589 0590 /** @short Structure storing each enabled extension */ 0591 class Enabled: public AbstractResponse 0592 { 0593 public: 0594 QList<QByteArray> extensions; 0595 Enabled(const QByteArray &line, int &start); 0596 Enabled(const QList<QByteArray> &extensions): extensions(extensions) {} 0597 QTextStream &dump(QTextStream &s) const override; 0598 bool eq(const AbstractResponse &other) const override; 0599 void plug(Imap::Parser *parser, Imap::Mailbox::Model *model) const override; 0600 bool plug(Imap::Mailbox::ImapTask *task) const override; 0601 }; 0602 0603 /** @short VANISHED contains information about UIDs of removed messages */ 0604 class Vanished: public AbstractResponse 0605 { 0606 public: 0607 typedef enum {EARLIER, NOT_EARLIER} EarlierOrNow; 0608 EarlierOrNow earlier; 0609 Uids uids; 0610 Vanished(const QByteArray &line, int &start); 0611 Vanished(EarlierOrNow earlier, const Uids &uids): earlier(earlier), uids(uids) {} 0612 QTextStream &dump(QTextStream &s) const override; 0613 bool eq(const AbstractResponse &other) const override; 0614 void plug(Imap::Parser *parser, Imap::Mailbox::Model *model) const override; 0615 bool plug(Imap::Mailbox::ImapTask *task) const override; 0616 }; 0617 0618 /** @short The GENURLAUTH response */ 0619 class GenUrlAuth: public AbstractResponse 0620 { 0621 public: 0622 QString url; 0623 GenUrlAuth(const QByteArray &line, int &start); 0624 GenUrlAuth(const QString &url): url(url) {} 0625 QTextStream &dump(QTextStream &s) const override; 0626 bool eq(const AbstractResponse &other) const override; 0627 void plug(Imap::Parser *parser, Imap::Mailbox::Model *model) const override; 0628 bool plug(Imap::Mailbox::ImapTask *task) const override; 0629 }; 0630 0631 /** @short A fake response for passing along the SSL state */ 0632 class SocketEncryptedResponse : public AbstractResponse 0633 { 0634 public: 0635 QList<QSslCertificate> sslChain; 0636 QList<QSslError> sslErrors; 0637 /** @short List of sequence/UID numbers as returned by the server */ 0638 SocketEncryptedResponse(const QList<QSslCertificate> &certificateChain, const QList<QSslError> &sslErrors); 0639 QTextStream &dump(QTextStream &s) const override; 0640 bool eq(const AbstractResponse &other) const override; 0641 void plug(Imap::Parser *parser, Imap::Mailbox::Model *model) const override; 0642 bool plug(Imap::Mailbox::ImapTask *task) const override; 0643 }; 0644 0645 /** @short A fake response saying that the socket got disconnected */ 0646 class SocketDisconnectedResponse : public AbstractResponse 0647 { 0648 public: 0649 QString message; 0650 explicit SocketDisconnectedResponse(const QString &message): message(message) {} 0651 QTextStream &dump(QTextStream &s) const override; 0652 bool eq(const AbstractResponse &other) const override; 0653 void plug(Imap::Parser *parser, Imap::Mailbox::Model *model) const override; 0654 bool plug(Imap::Mailbox::ImapTask *task) const override; 0655 }; 0656 0657 /** @short A fake response about a parsing error */ 0658 class ParseErrorResponse : public AbstractResponse 0659 { 0660 public: 0661 QString message; 0662 QString exceptionClass; 0663 QByteArray line; 0664 int offset; 0665 explicit ParseErrorResponse(const ImapException &e); 0666 QTextStream &dump(QTextStream &s) const override; 0667 bool eq(const AbstractResponse &other) const override; 0668 void plug(Imap::Parser *parser, Imap::Mailbox::Model *model) const override; 0669 bool plug(Imap::Mailbox::ImapTask *task) const override; 0670 }; 0671 0672 QTextStream &operator<<(QTextStream &stream, const Code &r); 0673 QTextStream &operator<<(QTextStream &stream, const Kind &res); 0674 QTextStream &operator<<(QTextStream &stream, const Status::StateKind &kind); 0675 QTextStream &operator<<(QTextStream &stream, const AbstractResponse &res); 0676 QTextStream &operator<<(QTextStream &stream, const NamespaceData &res); 0677 0678 inline bool operator==(const AbstractResponse &first, const AbstractResponse &other) 0679 { 0680 return first.eq(other); 0681 } 0682 0683 inline bool operator!=(const AbstractResponse &first, const AbstractResponse &other) 0684 { 0685 return !first.eq(other); 0686 } 0687 0688 /** @short Build Responses::Kind from textual value */ 0689 Kind kindFromString(QByteArray str); 0690 0691 } 0692 0693 } 0694 0695 #endif // IMAP_RESPONSE_H