1/*
2 Copyright (c) 2006 - 2007 Volker Krause <vkrause@kde.org>
3
4 This library is free software; you can redistribute it and/or modify it
5 under the terms of the GNU Library General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or (at your
7 option) any later version.
8
9 This library is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12 License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to the
16 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 02110-1301, USA.
18*/
19
20#ifndef AKONADI_IMAPPARSER_P_H
21#define AKONADI_IMAPPARSER_P_H
22
23#include "akonadiprotocolinternals_export.h"
24
25#include "imapset_p.h"
26
27#include <QtCore/QByteArray>
28#include <QtCore/QList>
29#include <QtCore/QVarLengthArray>
30
31namespace Akonadi {
32
33/**
34 Parser for IMAP messages.
35*/
36class AKONADIPROTOCOLINTERNALS_EXPORT ImapParser
37{
38public:
39 /**
40 Parses the next parenthesized list in @p data starting from @p start
41 and puts the result into @p result. The number of used characters is
42 returned.
43 This does not recurse into sub-lists.
44 @param data Source data.
45 @param result The parsed list.
46 @param start Start parsing at this index.
47 */
48 static int parseParenthesizedList(const QByteArray &data, QList<QByteArray> &result, int start = 0);
49 static int parseParenthesizedList(const QByteArray &data, QVarLengthArray<QByteArray, 16> &result, int start = 0);
50
51 /**
52 Parse the next string in @p data (quoted or literal) starting from @p start
53 and puts the result into @p result. The number of used characters is returned
54 (this is not equal to result.length()!).
55 @param data Source data.
56 @param result Parsed string, quotation, literal marker, etc. are removed,
57 'NIL' is transformed into an empty QByteArray.
58 @param start start parsing at this index.
59 */
60 static int parseString(const QByteArray &data, QByteArray &result, int start = 0);
61
62 /**
63 Parses the next quoted string from @p data starting at @p start and puts it into
64 @p result. The number of parsed characters is returned (this is not equal to result.length()!).
65 @param data Source data.
66 @param result Parsed string, quotation is removed and 'NIL' is transformed to an empty QByteArray.
67 @param start Start parsing at this index.
68 */
69 static int parseQuotedString(const QByteArray &data, QByteArray &result, int start = 0);
70
71 /**
72 Returns the number of leading espaces in @p data starting from @p start.
73 @param data The source data.
74 @param start Start parsing at this index.
75 */
76 static int stripLeadingSpaces(const QByteArray &data, int start = 0);
77
78 /**
79 Returns the parentheses balance for the given data, considering quotes.
80 @param data The source data.
81 @param start Start parsing at this index.
82 */
83 static int parenthesesBalance(const QByteArray &data, int start = 0);
84
85 /**
86 Joins a QByteArray list with the given separator.
87 @param list The QByteArray list to join.
88 @param separator The separator.
89 */
90 static QByteArray join(const QList<QByteArray> &list, const QByteArray &separator);
91
92 /**
93 Joins a QByteArray set with the given separator.
94 @param set The QByteArray set to join.
95 @param separator The separator.
96 */
97 static QByteArray join(const QSet<QByteArray> &set, const QByteArray &separator);
98
99 /**
100 Same as parseString(), but with additional UTF-8 decoding of the result.
101 @param data Source data.
102 @param result Parsed string, quotation, literal marker, etc. are removed,
103 'NIL' is transformed into an empty QString. UTF-8 decoding is applied..
104 @param start Start parsing at this index.
105 */
106 static int parseString(const QByteArray &data, QString &result, int start = 0);
107
108 /**
109 Parses the next integer number from @p data starting at start and puts it into
110 @p result. The number of characters parsed is returned (this is not the parsed result!).
111 @param data Source data.
112 @param result Parsed integer number, invalid if ok is false.
113 @param ok Set to false if the parsing failed.
114 @param start Start parsing at this index.
115 */
116 static int parseNumber(const QByteArray &data, qint64 &result, bool *ok = 0, int start = 0);
117
118 /**
119 Quotes the given QByteArray.
120 @param data Source data.
121 */
122 static QByteArray quote(const QByteArray &data);
123
124 /**
125 Parse an IMAP sequence set.
126 @param data source data.
127 @param result The parse sequence set.
128 @param start start parsing at this index.
129 @return end position of parsing.
130 */
131 static int parseSequenceSet(const QByteArray &data, ImapSet &result, int start = 0);
132
133 /**
134 Parse an IMAP date/time value.
135 @param data source data.
136 @param dateTime The result date/time.
137 @param start Start parsing at this index.
138 @return end position of parsing.
139 */
140 static int parseDateTime(const QByteArray &data, QDateTime &dateTime, int start = 0);
141
142 /**
143 Split a versioned key of the form 'key[version]' into its components.
144 @param data The versioned key.
145 @param key The unversioned key.
146 @param version The version of the key or 0 if no version was set.
147 */
148 static void splitVersionedKey(const QByteArray &data, QByteArray &key, int &version);
149
150 /**
151 Constructs a new IMAP parser.
152 */
153 ImapParser();
154
155 /**
156 Destroys an IMAP parser.
157 */
158 ~ImapParser();
159
160 /**
161 Parses the given line.
162 @returns True if an IMAP message was parsed completely, false if more data is needed.
163 @todo read from a QIODevice directly to avoid an extra line buffer
164 */
165 bool parseNextLine(const QByteArray &readBuffer);
166
167 /**
168 Parses the given block of data.
169 Note: This currently only handles continuation blocks.
170 @param data The data to parse.
171 */
172 void parseBlock(const QByteArray &data);
173
174 /**
175 Returns the tag of the parsed message.
176 Only valid if parseNextLine() returned true.
177 */
178 QByteArray tag() const;
179
180 /**
181 Return the raw data of the parsed IMAP message.
182 Only valid if parseNextLine() returned true.
183 */
184 QByteArray data() const;
185
186 /**
187 Resets the internal state of the parser. Call before parsing
188 a new IMAP message.
189 */
190 void reset();
191
192 /**
193 Returns true if the last parsed line contained a literal continuation,
194 ie. readiness for receiving literal data needs to be indicated.
195 */
196 bool continuationStarted() const;
197
198 /**
199 Returns the expected size of liteal data.
200 */
201 qint64 continuationSize() const;
202
203private:
204 Q_DISABLE_COPY(ImapParser)
205 class Private;
206 Private *const d;
207};
208
209}
210
211#endif
212