00001 #ifndef _IMAPPARSER_H
00002 #define _IMAPPARSER_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "imap4-config.h"
00028 #include "imaplist.h"
00029 #include "imapcommand.h"
00030 #include "imapinfo.h"
00031 #include "mailheader.h"
00032
00033 #include <kio/authinfo.h>
00034 #include <kio/slavebase.h>
00035
00036 #include <QHash>
00037 #include <QList>
00038 #include <QStringList>
00039 #include <QByteArray>
00040
00041 class KUrl;
00042 class QString;
00043 class mailAddress;
00044 class mimeHeader;
00045
00051 class parseString
00052 {
00053 public:
00054 parseString() : pos(0) {}
00055 char operator[](int i) const { return data.length() > (i + pos) ? data[i + pos] : '\0'; }
00056 bool isEmpty() const { return pos >= data.size(); }
00057 QByteArray cstr() const
00058 {
00059 if (pos >= data.size()) return QByteArray();
00060 return QByteArray(data.data() + pos, data.size() - pos);
00061 }
00062 int find(char c, int index = 0) const
00063 {
00064 int res = data.indexOf(c, index + pos);
00065 return (res == -1) ? res : (res - pos);
00066 }
00067
00068 void takeLeftNoResize(QByteArray& dest, uint len) const
00069 {
00070 memmove(dest.data(), data.data() + pos, len);
00071 }
00072
00073 void takeMidNoResize(QByteArray& dest, uint start, uint len) const
00074 {
00075 memmove(dest.data(), data.data() + pos + start, len);
00076 }
00077 void clear()
00078 {
00079 data.resize(0);
00080 pos = 0;
00081 }
00082 uint length()
00083 {
00084 return data.size() - pos;
00085 }
00086 void fromString(const QString &s)
00087 {
00088 clear();
00089 data = s.toLatin1();
00090 }
00091 QByteArray data;
00092 int pos;
00093 };
00094
00095 class imapCache
00096 {
00097 public:
00098 imapCache ()
00099 {
00100 myHeader = NULL;
00101 mySize = 0;
00102 myFlags = 0;
00103 myUid = 0;
00104 }
00105
00106 ~imapCache ()
00107 {
00108 if (myHeader) delete myHeader;
00109 }
00110
00111 mailHeader *getHeader ()
00112 {
00113 return myHeader;
00114 }
00115 void setHeader (mailHeader * inHeader)
00116 {
00117 myHeader = inHeader;
00118 }
00119
00120 ulong getSize ()
00121 {
00122 return mySize;
00123 }
00124 void setSize (ulong inSize)
00125 {
00126 mySize = inSize;
00127 }
00128
00129 ulong getUid ()
00130 {
00131 return myUid;
00132 }
00133 void setUid (ulong inUid)
00134 {
00135 myUid = inUid;
00136 }
00137
00138 ulong getFlags ()
00139 {
00140 return myFlags;
00141 }
00142 void setFlags (ulong inFlags)
00143 {
00144 myFlags = inFlags;
00145 }
00146
00147 QByteArray getDate ()
00148 {
00149 return myDate;
00150 }
00151 void setDate (const QByteArray & _str)
00152 {
00153 myDate = _str;
00154 }
00155 void clear()
00156 {
00157 if (myHeader) delete myHeader;
00158 myHeader = NULL;
00159 mySize = 0;
00160 myFlags = 0;
00161 myDate = QByteArray();
00162 myUid = 0;
00163 }
00164
00165 protected:
00166 mailHeader * myHeader;
00167 ulong mySize;
00168 ulong myFlags;
00169 ulong myUid;
00170 QByteArray myDate;
00171 };
00172
00173
00174 class imapParser
00175 {
00176
00177 public:
00178
00180 enum IMAP_STATE
00181 {
00182 ISTATE_NO,
00183 ISTATE_CONNECT,
00184 ISTATE_LOGIN,
00185 ISTATE_SELECT
00186 };
00187
00188 public:
00189 imapParser ();
00190 virtual ~ imapParser ();
00191
00193 enum IMAP_STATE getState () { return currentState; }
00195 void setState(enum IMAP_STATE state) { currentState = state; }
00196
00197
00198 const QString getCurrentBox ()
00199 {
00200 return KIMAP::decodeImapFolderName(currentBox);
00201 }
00202
00208 CommandPtr sendCommand (CommandPtr aCmd);
00214 CommandPtr doCommand (CommandPtr aCmd);
00215
00216
00224 bool clientLogin (const QString & aUser, const QString & aPass, QString & resultInfo);
00234 bool clientAuthenticate (KIO::SlaveBase *slave, KIO::AuthInfo &ai, const QString & aFQDN,
00235 const QString & aAuth, bool isSSL, QString & resultInfo);
00236
00241 int parseLoop ();
00242
00247 void parseUntagged (parseString & result);
00248
00250 void parseRecent (ulong value, parseString & result);
00252 void parseResult (QByteArray & result, parseString & rest,
00253 const QString & command = QString());
00255 void parseCapability (parseString & result);
00257 void parseFlags (parseString & result);
00259 void parseList (parseString & result);
00261 void parseLsub (parseString & result);
00263 void parseListRights (parseString & result);
00265 void parseMyRights (parseString & result);
00267 void parseSearch (parseString & result);
00269 void parseStatus (parseString & result);
00271 void parseExists (ulong value, parseString & result);
00273 void parseExpunge (ulong value, parseString & result);
00275 void parseAcl (parseString & result);
00277 void parseAnnotation (parseString & result);
00279 void parseNamespace (parseString & result);
00281 void parseQuotaRoot (parseString & result);
00283 void parseQuota (parseString & result);
00285 void parseCustom (parseString & result);
00287 void parseOtherUser (parseString & result);
00289 void parseDelegate (parseString & result);
00291 void parseOutOfOffice (parseString & result);
00292
00297 void parseFetch (ulong value, parseString & inWords);
00298
00300 mailHeader *parseEnvelope (parseString & inWords);
00302 void parseAddressList (parseString & inWords, QList<mailAddress *>& list);
00304 const mailAddress& parseAddress (parseString & inWords, mailAddress& buffer);
00305
00307 void parseBody (parseString & inWords);
00308
00310 mimeHeader *parseBodyStructure (parseString & inWords,
00311 QString & section, mimeHeader * inHeader = 0);
00312
00314 mimeHeader *parseSimplePart (parseString & inWords, QString & section,
00315 mimeHeader * localPart = 0);
00316
00318 QHash< QByteArray, QString > parseParameters (parseString & inWords);
00319
00324 QHash< QByteArray, QString > parseDisposition (parseString & inWords);
00325
00326
00327
00329 virtual void parseRelay (const QByteArray & buffer);
00330
00333 virtual void parseRelay (ulong);
00334
00336 virtual bool parseRead (QByteArray & buffer, long len, long relay = 0);
00337
00339 virtual bool parseReadLine (QByteArray & buffer, long relay = 0);
00340
00342 virtual void parseWriteLine (const QString &);
00343
00344
00345
00347 void parseSentence (parseString & inWords);
00348
00350 QByteArray parseLiteral(parseString & inWords, bool relay = false,
00351 bool stopAtBracket = false);
00352
00353
00354
00356 static QByteArray parseOneWord (parseString & inWords,
00357 bool stopAtBracket = false);
00358
00360 static bool parseOneNumber (parseString & inWords, ulong & num);
00361
00363 static void parseURL (const KUrl & _url, QString & _box, QString & _section,
00364 QString & _type, QString & _uid, QString & _validity,
00365 QString & _info);
00366
00367
00371 imapCache *getLastHandled ()
00372 {
00373 return lastHandled;
00374 }
00375
00377 const QStringList & getResults ()
00378 {
00379 return lastResults;
00380 }
00381
00383 const imapInfo & getStatus ()
00384 {
00385 return lastStatus;
00386 }
00388 const imapInfo & getSelected ()
00389 {
00390 return selectInfo;
00391 }
00392
00393 const QByteArray & getContinuation ()
00394 {
00395 return continuation;
00396 }
00397
00399 bool hasCapability (const QString &);
00400
00401 void removeCapability (const QString & cap);
00402
00403 static inline void skipWS (parseString & inWords)
00404 {
00405 char c;
00406 while (!inWords.isEmpty() &&
00407 ((c = inWords[0]) == ' ' || c == '\t' || c == '\r' || c == '\n'))
00408 {
00409 inWords.pos++;
00410 }
00411 }
00412
00414 QString namespaceForBox( const QString & box );
00415
00416
00417 protected:
00418
00420 enum IMAP_STATE currentState;
00421
00423 QString currentBox;
00424
00426 imapInfo selectInfo;
00427
00429 imapInfo lastStatus;
00430
00432 QStringList imapCapabilities;
00433
00435 QList < imapList > listResponses;
00436
00438 QList <CommandPtr> sentQueue;
00439 QList <CommandPtr> completeQueue;
00440
00444 QStringList unhandled;
00445
00447 QByteArray continuation;
00448
00450 QString seenUid;
00451 imapCache *lastHandled;
00452
00453 ulong commandCounter;
00454
00456 QStringList lastResults;
00457
00462 QMap<QString, QString> namespaceToDelimiter;
00463
00468 QStringList imapNamespaces;
00469
00470 private:
00471
00473 imapParser & operator = (const imapParser &);
00474
00475 };
00476 #endif