KIMAP

imapstreamparser.h
1 /*
2  SPDX-FileCopyrightText: 2006-2007 Volker Krause <[email protected]>
3  SPDX-FileCopyrightText: 2009 Andras Mantia <[email protected]>
4 
5  SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7 
8 #pragma once
9 
10 #include "kimap_export.h"
11 
12 #include <exception>
13 
14 #include <QByteArray>
15 #include <QList>
16 #include <QString>
17 
18 class QIODevice;
19 
20 namespace KIMAP
21 {
22 class ImapParserException : public std::exception
23 {
24 public:
25  explicit ImapParserException(const char *what) throw()
26  : mWhat(what)
27  {
28  }
29  explicit ImapParserException(const QByteArray &what) throw()
30  : mWhat(what)
31  {
32  }
33  explicit ImapParserException(const QString &what) throw()
34  : mWhat(what.toUtf8())
35  {
36  }
37  ImapParserException(const ImapParserException &other) throw()
38  : std::exception(other)
39  , mWhat(other.what())
40  {
41  }
42  ~ImapParserException() throw() override
43  {
44  }
45  const char *what() const throw() override
46  {
47  return mWhat.constData();
48  }
49  virtual const char *type() const throw()
50  {
51  return "ImapParserException";
52  }
53 
54 private:
55  QByteArray mWhat;
56 };
57 
58 /**
59  Parser for IMAP messages that operates on a local socket stream.
60 */
61 class KIMAP_EXPORT ImapStreamParser
62 {
63 public:
64  /**
65  * Construct the parser.
66  * @param socket the local socket to work with.
67  * @param serverModeEnabled true if the parser has to assume we're writing a server (e.g. sends
68  * continuation message automatically)
69  */
70  explicit ImapStreamParser(QIODevice *socket, bool serverModeEnabled = false);
71 
72  /**
73  * Get a string from the message. If the upcoming data is not a quoted string, unquoted string or a literal,
74  * the behavior is undefined. Use @ref hasString to be sure a string comes. This call might block.
75  * @return the next string from the message as an utf8 string
76  */
77  QString readUtf8String();
78 
79  /**
80  * Same as above, but without decoding it to utf8.
81  * @return the next string from the message
82  */
83  QByteArray readString();
84 
85  /**
86  * Get he next parenthesized list. If the upcoming data is not a parenthesized list,
87  * the behavior is undefined. Use @ref hasList to be sure a string comes. This call might block.
88  * @return the next parenthesized list.
89  */
90  QList<QByteArray> readParenthesizedList();
91 
92  /**
93  * Get the next data as a number. This call might block.
94  * @param ok true if the data found was a number
95  * @return the number
96  */
97  qint64 readNumber(bool *ok = nullptr);
98 
99  /**
100  * Check if the next data is a string or not. This call might block.
101  * @return true if a string follows
102  */
103  bool hasString();
104 
105  /**
106  * Check if the next data is a literal data or not. If a literal is found, the
107  * internal position pointer is set to the beginning of the literal data.
108  * This call might block.
109  * @return true if a literal follows
110  */
111  bool hasLiteral();
112 
113  /**
114  * Read the next literal sequence. This might or might not be the full data. Example code to read a literal would be:
115  * @code
116  * ImapStreamParser parser;
117  * ...
118  * if (parser.hasLiteral())
119  * {
120  * while (!parser.atLiteralEnd())
121  * {
122  * QByteArray data = parser.readLiteralPart();
123  * // do something with the data
124  * }
125  * }
126  * @endcode
127  *
128  * This call might block.
129  *
130  * @return part of a literal data
131  */
132  QByteArray readLiteralPart();
133 
134  /**
135  * Check if the literal data end was reached. See @ref hasLiteral and @ref readLiteralPart .
136  * @return true if the literal was completely read.
137  */
138  bool atLiteralEnd() const;
139 
140  /**
141  * Check if the next data is a parenthesized list. This call might block.
142  * @return true if a parenthesized list comes.
143  */
144  bool hasList();
145 
146  /**
147  * Check if the next data is a parenthesized list end. This call might block.
148  * @return true if a parenthesized list end.
149  */
150  bool atListEnd();
151 
152  /**
153  * Check if the next data is a response code. This call might block.
154  * @return true if a response code comes.
155  */
156  bool hasResponseCode();
157 
158  /**
159  * Check if the next data is a response code end. This call might block.
160  * @return true if a response code end.
161  */
162  bool atResponseCodeEnd();
163 
164  /**
165  * Check if the command end was reached
166  * @return true if the end of command is reached
167  */
168  bool atCommandEnd();
169 
170  /**
171  * Return everything that remained from the command.
172  * @return the remaining command data
173  */
174  QByteArray readUntilCommandEnd();
175 
176  /**
177  * Return all the data that was read from the socket, but not processed yet.
178  * @return the remaining unprocessed data
179  */
180  QByteArray readRemainingData();
181 
182  int availableDataSize() const;
183 
184  void setData(const QByteArray &data);
185 
186 private:
187  void stripLeadingSpaces();
188  QByteArray parseQuotedString();
189 
190  /**
191  * If the condition is true, wait for more data to be available from the socket.
192  * If no data comes after a timeout (30000ms), it aborts and returns false.
193  * @param wait the condition
194  * @return true if more data is available
195  */
196  bool waitForMoreData(bool wait);
197 
198  /**
199  * Inform the client to send more literal data.
200  */
201  void sendContinuationResponse(qint64 size);
202 
203  /**
204  * Remove already read data from the internal buffer if necessary.
205  */
206  void trimBuffer();
207 
208  QIODevice *m_socket = nullptr;
209  bool m_isServerModeEnabled = false;
210  QByteArray m_data;
211  int m_position = -1;
212  qint64 m_literalSize = -1;
213 };
214 
215 }
Parser for IMAP messages that operates on a local socket stream.
Type type(const QSqlDatabase &db)
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Sun Dec 10 2023 03:48:59 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.