File indexing completed on 2024-09-15 04:36:25
0001 /* 0002 SPDX-FileCopyrightText: 2006-2007 Volker Krause <vkrause@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 #include "akonadiprivate_export.h" 0010 0011 #include "imapset_p.h" 0012 0013 #include <QByteArray> 0014 #include <QList> 0015 #include <QVarLengthArray> 0016 0017 #include <memory> 0018 0019 namespace Akonadi 0020 { 0021 class ImapParserPrivate; 0022 0023 /** 0024 Parser for IMAP messages. 0025 */ 0026 class AKONADIPRIVATE_EXPORT ImapParser 0027 { 0028 public: 0029 /** 0030 Parses the next parenthesized list in @p data starting from @p start 0031 and puts the result into @p result. The number of used characters is 0032 returned. 0033 This does not recurse into sub-lists. 0034 @param data Source data. 0035 @param result The parsed list. 0036 @param start Start parsing at this index. 0037 */ 0038 static int parseParenthesizedList(const QByteArray &data, QList<QByteArray> &result, int start = 0); 0039 static int parseParenthesizedList(const QByteArray &data, QVarLengthArray<QByteArray, 16> &result, int start = 0); 0040 0041 /** 0042 Parse the next string in @p data (quoted or literal) starting from @p start 0043 and puts the result into @p result. The number of used characters is returned 0044 (this is not equal to result.length()!). 0045 @param data Source data. 0046 @param result Parsed string, quotation, literal marker, etc. are removed, 0047 'NIL' is transformed into an empty QByteArray. 0048 @param start start parsing at this index. 0049 */ 0050 static int parseString(const QByteArray &data, QByteArray &result, int start = 0); 0051 0052 /** 0053 Parses the next quoted string from @p data starting at @p start and puts it into 0054 @p result. The number of parsed characters is returned (this is not equal to result.length()!). 0055 @param data Source data. 0056 @param result Parsed string, quotation is removed and 'NIL' is transformed to an empty QByteArray. 0057 @param start Start parsing at this index. 0058 */ 0059 static int parseQuotedString(const QByteArray &data, QByteArray &result, int start = 0); 0060 0061 /** 0062 Returns the number of leading spaces in @p data starting from @p start. 0063 @param data The source data. 0064 @param start Start parsing at this index. 0065 */ 0066 static int stripLeadingSpaces(const QByteArray &data, int start = 0); 0067 0068 /** 0069 Returns the parentheses balance for the given data, considering quotes. 0070 @param data The source data. 0071 @param start Start parsing at this index. 0072 */ 0073 static int parenthesesBalance(const QByteArray &data, int start = 0); 0074 0075 /** 0076 Joins a QByteArray list with the given separator. 0077 @param list The QByteArray list to join. 0078 @param separator The separator. 0079 */ 0080 static QByteArray join(const QList<QByteArray> &list, const QByteArray &separator); 0081 0082 /** 0083 Joins a QByteArray set with the given separator. 0084 @param set The QByteArray set to join. 0085 @param separator The separator. 0086 */ 0087 static QByteArray join(const QSet<QByteArray> &set, const QByteArray &separator); 0088 0089 /** 0090 Same as parseString(), but with additional UTF-8 decoding of the result. 0091 @param data Source data. 0092 @param result Parsed string, quotation, literal marker, etc. are removed, 0093 'NIL' is transformed into an empty QString. UTF-8 decoding is applied.. 0094 @param start Start parsing at this index. 0095 */ 0096 static int parseString(const QByteArray &data, QString &result, int start = 0); 0097 0098 /** 0099 Parses the next integer number from @p data starting at start and puts it into 0100 @p result. The number of characters parsed is returned (this is not the parsed result!). 0101 @param data Source data. 0102 @param result Parsed integer number, invalid if ok is false. 0103 @param ok Set to false if the parsing failed. 0104 @param start Start parsing at this index. 0105 */ 0106 static int parseNumber(const QByteArray &data, qint64 &result, bool *ok = nullptr, int start = 0); 0107 0108 /** 0109 Quotes the given QByteArray. 0110 @param data Source data. 0111 */ 0112 static QByteArray quote(const QByteArray &data); 0113 0114 /** 0115 Parse an IMAP sequence set. 0116 @param data source data. 0117 @param result The parse sequence set. 0118 @param start start parsing at this index. 0119 @return end position of parsing. 0120 */ 0121 static int parseSequenceSet(const QByteArray &data, ImapSet &result, int start = 0); 0122 0123 /** 0124 Parse an IMAP date/time value. 0125 @param data source data. 0126 @param dateTime The result date/time. 0127 @param start Start parsing at this index. 0128 @return end position of parsing. 0129 */ 0130 static int parseDateTime(const QByteArray &data, QDateTime &dateTime, int start = 0); 0131 0132 /** 0133 Split a versioned key of the form 'key[version]' into its components. 0134 @param data The versioned key. 0135 @param key The unversioned key. 0136 @param version The version of the key or 0 if no version was set. 0137 */ 0138 static void splitVersionedKey(const QByteArray &data, QByteArray &key, int &version); 0139 0140 /** 0141 Constructs a new IMAP parser. 0142 */ 0143 ImapParser(); 0144 0145 /** 0146 Destroys an IMAP parser. 0147 */ 0148 ~ImapParser(); 0149 0150 /** 0151 Parses the given line. 0152 @returns True if an IMAP message was parsed completely, false if more data is needed. 0153 @todo read from a QIODevice directly to avoid an extra line buffer 0154 */ 0155 bool parseNextLine(const QByteArray &readBuffer); 0156 0157 /** 0158 Parses the given block of data. 0159 Note: This currently only handles continuation blocks. 0160 @param data The data to parse. 0161 */ 0162 void parseBlock(const QByteArray &data); 0163 0164 /** 0165 Returns the tag of the parsed message. 0166 Only valid if parseNextLine() returned true. 0167 */ 0168 QByteArray tag() const; 0169 0170 /** 0171 Return the raw data of the parsed IMAP message. 0172 Only valid if parseNextLine() returned true. 0173 */ 0174 QByteArray data() const; 0175 0176 /** 0177 Resets the internal state of the parser. Call before parsing 0178 a new IMAP message. 0179 */ 0180 void reset(); 0181 0182 /** 0183 Returns true if the last parsed line contained a literal continuation, 0184 ie. readiness for receiving literal data needs to be indicated. 0185 */ 0186 bool continuationStarted() const; 0187 0188 /** 0189 Returns the expected size of liteal data. 0190 */ 0191 qint64 continuationSize() const; 0192 0193 private: 0194 Q_DISABLE_COPY(ImapParser) 0195 std::unique_ptr<ImapParserPrivate> const d; 0196 }; 0197 0198 }