File indexing completed on 2024-05-12 05:17:23
0001 /* 0002 Copyright (c) 2006 - 2007 Volker Krause <vkrause@kde.org> 0003 Copyright (c) 2009 Andras Mantia <amantia@kde.org> 0004 Copyright (c) 2017 Christian Mollekopf <mollekopf@kolabsys.com> 0005 0006 This library is free software; you can redistribute it and/or modify it 0007 under the terms of the GNU Library General Public License as published by 0008 the Free Software Foundation; either version 2 of the License, or (at your 0009 option) any later version. 0010 0011 This library is distributed in the hope that it will be useful, but WITHOUT 0012 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0013 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 0014 License for more details. 0015 0016 You should have received a copy of the GNU Library General Public License 0017 along with this library; see the file COPYING.LIB. If not, write to the 0018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 0019 02110-1301, USA. 0020 */ 0021 0022 #ifndef KIMAP2_IMAPSTREAMPARSER_P_H 0023 #define KIMAP2_IMAPSTREAMPARSER_P_H 0024 0025 #include "kimap2_export.h" 0026 0027 #include <QtCore/QByteArray> 0028 #include <QtCore/QList> 0029 #include <QtCore/QScopedPointer> 0030 #include <functional> 0031 #include <message_p.h> 0032 0033 class QIODevice; 0034 0035 namespace KIMAP2 0036 { 0037 0038 /** 0039 Parser for IMAP messages that operates on a local socket stream. 0040 */ 0041 class KIMAP2_EXPORT ImapStreamParser 0042 { 0043 public: 0044 /** 0045 * Construct the parser. 0046 * @param socket the local socket to work with. 0047 * @param serverModeEnabled true if the parser has to assume we're writing a server (e.g. sends 0048 * continuation message automatically) 0049 */ 0050 explicit ImapStreamParser(QIODevice *socket, bool serverModeEnabled = false); 0051 0052 /** 0053 * Return everything that remained from the command. 0054 * @return the remaining command data 0055 */ 0056 QByteArray readUntilCommandEnd(); 0057 0058 int availableDataSize() const; 0059 0060 void parseStream(); 0061 0062 void onResponseReceived(std::function<void(const Message &)>); 0063 0064 bool error() const; 0065 0066 QByteArray currentBuffer() const; 0067 0068 private: 0069 0070 /** 0071 * Remove already read data from the internal buffer if necessary. 0072 */ 0073 void trimBuffer(); 0074 0075 /** 0076 * Inform the client to send more literal data. 0077 */ 0078 void sendContinuationResponse(qint64 size); 0079 0080 0081 int readFromSocket(); 0082 void processBuffer(); 0083 0084 char at(int pos) const; 0085 QByteArray mid(int start, int end = -1) const; 0086 QByteArray midRef(int start, int end) const; 0087 int length() const; 0088 0089 QByteArray &buffer(); 0090 const QByteArray &buffer() const; 0091 0092 QScopedPointer<Message> m_message; 0093 QList<Message::Part> *m_currentPayload; 0094 0095 QIODevice *m_socket; 0096 bool m_isServerModeEnabled; 0097 bool m_processing; 0098 int m_position; 0099 int m_readPosition; 0100 qint64 m_literalSize; 0101 QByteArray m_data1; 0102 QByteArray m_data2; 0103 QByteArray *m_current; 0104 int m_bufferSize; 0105 0106 enum States { 0107 InitState, 0108 QuotedStringState, 0109 LiteralStringState, 0110 StringState, 0111 WhitespaceState, 0112 AngleBracketStringState, 0113 SublistString, 0114 CRLFState 0115 }; 0116 States m_currentState; 0117 States m_lastState; 0118 0119 void setState(States state); 0120 void forwardToState(States state); 0121 void resetState(); 0122 0123 int m_listCounter; 0124 int m_stringStartPos; 0125 bool m_readingLiteral; 0126 bool m_error; 0127 0128 std::function<void(const char *data, const int size)> string; 0129 std::function<void()> listStart; 0130 std::function<void()> listEnd; 0131 std::function<void()> responseCodeStart; 0132 std::function<void()> responseCodeEnd; 0133 std::function<void(int size)> literalStart; 0134 std::function<void(const char *data, const int size)> literalPart; 0135 std::function<void()> literalEnd; 0136 std::function<void()> lineEnd; 0137 0138 void onString(std::function<void(const char *data, const int size)> f) 0139 { 0140 string = f; 0141 } 0142 0143 void onListStart(std::function<void()> f) 0144 { 0145 listStart = f; 0146 } 0147 0148 void onListEnd(std::function<void()> f) 0149 { 0150 listEnd = f; 0151 } 0152 0153 void onResponseCodeStart(std::function<void()> f) 0154 { 0155 responseCodeStart = f; 0156 } 0157 0158 void onResponseCodeEnd(std::function<void()> f) 0159 { 0160 responseCodeEnd = f; 0161 } 0162 0163 void onLiteralStart(std::function<void(int size)> f) 0164 { 0165 literalStart = f; 0166 } 0167 0168 void onLiteralPart(std::function<void(const char *data, const int size)> f) 0169 { 0170 literalPart = f; 0171 } 0172 0173 void onLiteralEnd(std::function<void()> f) 0174 { 0175 literalEnd = f; 0176 } 0177 0178 void onLineEnd(std::function<void()> f) 0179 { 0180 lineEnd = f; 0181 } 0182 0183 std::function<void(const Message &)> responseReceived; 0184 0185 void setupCallbacks(); 0186 0187 QList<QByteArray> *m_list; 0188 QByteArray m_literalData; 0189 }; 0190 0191 } 0192 0193 #endif