24 #include "imapstreamparser.h"
29 using namespace KIMAP;
34 m_isServerModeEnabled = serverModeEnabled;
47 QString result = QString::fromUtf8( tmp );
55 if ( !waitForMoreData( m_data.length() == 0 ) )
56 throw ImapParserException(
"Unable to read more data");
58 if ( !waitForMoreData( m_position >= m_data.length() ) )
59 throw ImapParserException(
"Unable to read more data");
71 return parseQuotedString();
76 if ( !waitForMoreData( m_position >= m_data.length() ) )
77 throw ImapParserException(
"Unable to read more data");
78 int savedPos = m_position;
81 m_position = savedPos;
82 if ( m_data.at(pos) ==
'{' )
84 if (m_data.at(pos) ==
'"' )
86 if ( m_data.at(pos) !=
' ' &&
87 m_data.at(pos) !=
'(' &&
88 m_data.at(pos) !=
')' &&
89 m_data.at(pos) !=
'[' &&
90 m_data.at(pos) !=
']' &&
91 m_data.at(pos) !=
'\n' &&
92 m_data.at(pos) !=
'\r' )
100 if ( !waitForMoreData( m_position >= m_data.length() ) )
101 throw ImapParserException(
"Unable to read more data");
102 int savedPos = m_position;
103 stripLeadingSpaces();
104 if ( m_data.at(m_position) ==
'{' )
108 end = m_data.indexOf(
'}', m_position );
109 if ( !waitForMoreData( end == -1 ) )
110 throw ImapParserException(
"Unable to read more data");
112 Q_ASSERT( end > m_position );
113 m_literalSize = m_data.mid( m_position + 1, end - m_position - 1 ).toInt();
115 m_position = end + 1;
117 if ( m_position < m_data.length() && m_data.at(m_position) ==
'\r' )
119 if ( m_position < m_data.length() && m_data.at(m_position) ==
'\n' )
123 if (m_isServerModeEnabled && m_literalSize > 0)
124 sendContinuationResponse( m_literalSize );
128 m_position = savedPos;
135 return (m_literalSize == 0);
140 static qint64 maxLiteralPartSize = 4096;
141 int size = qMin(maxLiteralPartSize, m_literalSize);
143 if ( !waitForMoreData( m_data.length() < m_position + size ) )
144 throw ImapParserException(
"Unable to read more data");
146 if ( m_data.length() < m_position + size ) {
148 size = m_data.length() - m_position;
151 QByteArray result = m_data.mid(m_position, size);
153 m_literalSize -= size;
154 Q_ASSERT(m_literalSize >= 0);
162 if ( !waitForMoreData( m_position >= m_data.length() ) )
163 throw ImapParserException(
"Unable to read more data");
164 int savedPos = m_position;
165 stripLeadingSpaces();
166 int pos = m_position;
167 m_position = savedPos;
168 if ( m_data.at(pos) ==
'(' )
178 if ( !waitForMoreData( m_position >= m_data.length() ) )
179 throw ImapParserException(
"Unable to read more data");
180 int savedPos = m_position;
181 stripLeadingSpaces();
182 int pos = m_position;
183 m_position = savedPos;
184 if ( m_data.at(pos) ==
')' )
186 m_position = pos + 1;
195 QList<QByteArray> result;
196 if (! waitForMoreData( m_data.length() <= m_position ) )
197 throw ImapParserException(
"Unable to read more data");
199 stripLeadingSpaces();
200 if ( m_data.at(m_position) !=
'(' )
203 bool concatToLast =
false;
205 int sublistbegin = m_position;
206 int i = m_position + 1;
208 if ( !waitForMoreData( m_data.length() <= i ) )
211 throw ImapParserException(
"Unable to read more data");
213 if ( m_data.at(i) ==
'(' ) {
220 if ( m_data.at(i) ==
')' ) {
226 result.append( m_data.mid( sublistbegin, i - sublistbegin + 1 ) );
231 if ( m_data.at(i) ==
' ' ) {
235 if ( m_data.at(i) ==
'"' ) {
243 if ( m_data.at(i) ==
'[' ) {
245 if ( result.isEmpty() ) {
246 result.append( QByteArray() );
252 if ( m_data.at(i) ==
']' ) {
253 concatToLast =
false;
271 while ( ( m_position < m_data.size() ) && ( m_data.at(m_position) ==
'\r' || m_data.at(m_position) ==
'\n' ) ) {
285 throw ImapParserException(
"Something went very very wrong!" );
290 if ( !waitForMoreData( m_position >= m_data.length() ) )
291 throw ImapParserException(
"Unable to read more data");
292 int savedPos = m_position;
293 stripLeadingSpaces();
294 int pos = m_position;
295 m_position = savedPos;
296 if ( m_data.at(pos) ==
'[' )
298 m_position = pos + 1;
307 if ( !waitForMoreData( m_position >= m_data.length() ) )
308 throw ImapParserException(
"Unable to read more data");
309 int savedPos = m_position;
310 stripLeadingSpaces();
311 int pos = m_position;
312 m_position = savedPos;
313 if ( m_data.at(pos) ==
']' )
315 m_position = pos + 1;
322 QByteArray ImapStreamParser::parseQuotedString()
325 if (! waitForMoreData( m_data.length() == 0 ) )
326 throw ImapParserException(
"Unable to read more data");
327 stripLeadingSpaces();
328 int end = m_position;
330 if ( !waitForMoreData( m_position >= m_data.length() ) )
331 throw ImapParserException(
"Unable to read more data");
332 if ( !waitForMoreData( m_position >= m_data.length() ) )
333 throw ImapParserException(
"Unable to read more data");
335 bool foundSlash =
false;
337 if ( m_data.at(m_position) ==
'"' ) {
341 if ( !waitForMoreData( m_data.length() <= i ) )
344 throw ImapParserException(
"Unable to read more data");
346 if ( m_data.at(i) ==
'\\' ) {
351 if ( m_data.at(i) ==
'"' ) {
352 result = m_data.mid( m_position, i - m_position );
362 bool reachedInputEnd =
true;
365 if ( !waitForMoreData( m_data.length() <= i ) )
368 throw ImapParserException(
"Unable to read more data");
370 if ( m_data.at(i) ==
' ' || m_data.at(i) ==
'(' || m_data.at(i) ==
')' || m_data.at(i) ==
'[' || m_data.at(i) ==
']' || m_data.at(i) ==
'\n' || m_data.at(i) ==
'\r' || m_data.at(i) ==
'"') {
372 reachedInputEnd =
false;
375 if (m_data.at(i) ==
'\\')
379 if ( reachedInputEnd )
380 end = m_data.length();
382 result = m_data.mid( m_position, end - m_position );
387 while ( result.contains(
"\\\"" ) )
388 result.replace(
"\\\"",
"\"" );
389 while ( result.contains(
"\\\\" ) )
390 result.replace(
"\\\\",
"\\" );
401 if (! waitForMoreData( m_data.length() == 0 ) )
402 throw ImapParserException(
"Unable to read more data");
403 stripLeadingSpaces();
404 if ( !waitForMoreData( m_position >= m_data.length() ) )
405 throw ImapParserException(
"Unable to read more data");
406 if ( m_position >= m_data.length() )
407 throw ImapParserException(
"Unable to read more data");
410 if ( !waitForMoreData( m_data.length() <= i ) )
413 throw ImapParserException(
"Unable to read more data");
415 if ( !isdigit( m_data.at( i ) ) )
419 const QByteArray tmp = m_data.mid( m_position, i - m_position );
420 result = tmp.toLongLong( ok );
425 void ImapStreamParser::stripLeadingSpaces()
427 for (
int i = m_position; i < m_data.length(); ++i ) {
428 if ( m_data.at(i) !=
' ' )
434 m_position = m_data.length();
437 bool ImapStreamParser::waitForMoreData(
bool wait )
440 if ( m_socket->bytesAvailable() > 0 ||
441 m_socket->waitForReadyRead(30000) ) {
442 m_data.append( m_socket->readAll() );
451 void ImapStreamParser::setData(
const QByteArray &data )
458 return m_data.mid(m_position);
461 int ImapStreamParser::availableDataSize()
const
463 return m_socket->bytesAvailable()+m_data.size()-m_position;
468 int savedPos = m_position;
470 if ( !waitForMoreData( m_position >= m_data.length() ) )
471 throw ImapParserException(
"Unable to read more data");
472 stripLeadingSpaces();
473 }
while ( m_position >= m_data.size() );
475 if ( m_data.at(m_position) ==
'\n' || m_data.at(m_position) ==
'\r') {
476 if ( m_data.at(m_position) ==
'\r' )
478 if ( m_position < m_data.length() && m_data.at(m_position) ==
'\n' )
486 m_position = savedPos;
494 int paranthesisBalance = 0;
496 if ( !waitForMoreData( m_data.length() <= i ) )
499 throw ImapParserException(
"Unable to read more data");
501 if ( m_data.at(i) ==
'{' )
505 result.append(m_data.mid(i-1, m_position - i +1));
512 if ( m_data.at(i) ==
'(' )
513 paranthesisBalance++;
514 if ( m_data.at(i) ==
')' )
515 paranthesisBalance--;
516 if ( ( i == m_data.length() && paranthesisBalance == 0 ) || m_data.at(i) ==
'\n' || m_data.at(i) ==
'\r')
518 result.append( m_data.at(i) );
526 void ImapStreamParser::sendContinuationResponse( qint64 size )
528 QByteArray block =
"+ Ready for literal data (expecting "
529 + QByteArray::number( size ) +
" bytes)\r\n";
530 m_socket->write(block);
531 m_socket->waitForBytesWritten(30000);
534 void ImapStreamParser::trimBuffer()
536 if ( m_position < 4096 )
538 m_data = m_data.right(m_data.size()-m_position);