summaryrefslogtreecommitdiff
path: root/kimap/imapstreamparser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kimap/imapstreamparser.cpp')
-rw-r--r--kimap/imapstreamparser.cpp302
1 files changed, 137 insertions, 165 deletions
diff --git a/kimap/imapstreamparser.cpp b/kimap/imapstreamparser.cpp
index 37bf691..50a8552 100644
--- a/kimap/imapstreamparser.cpp
+++ b/kimap/imapstreamparser.cpp
@@ -48,21 +48,20 @@ QString ImapStreamParser::readUtf8String()
return result;
}
+
QByteArray ImapStreamParser::readString()
{
QByteArray result;
- if ( !waitForMoreData( m_data.length() == 0 ) ) {
- throw ImapParserException( "Unable to read more data" );
- }
+ if ( !waitForMoreData( m_data.length() == 0 ) )
+ throw ImapParserException("Unable to read more data");
stripLeadingSpaces();
- if ( !waitForMoreData( m_position >= m_data.length() ) ) {
- throw ImapParserException( "Unable to read more data" );
- }
+ if ( !waitForMoreData( m_position >= m_data.length() ) )
+ throw ImapParserException("Unable to read more data");
// literal string
// TODO: error handling
if ( hasLiteral() ) {
- while ( !atLiteralEnd() ) {
+ while (!atLiteralEnd()) {
result += readLiteralPart();
}
return result;
@@ -74,65 +73,58 @@ QByteArray ImapStreamParser::readString()
bool ImapStreamParser::hasString()
{
- if ( !waitForMoreData( m_position >= m_data.length() ) ) {
- throw ImapParserException( "Unable to read more data" );
- }
+ if ( !waitForMoreData( m_position >= m_data.length() ) )
+ throw ImapParserException("Unable to read more data");
int savedPos = m_position;
stripLeadingSpaces();
int pos = m_position;
m_position = savedPos;
- if ( m_data.at( pos ) == '{' ) {
+ if ( m_data.at(pos) == '{' )
return true; //literal string
- }
- if ( m_data.at( pos ) == '"' ) {
+ if (m_data.at(pos) == '"' )
return true; //quoted string
- }
- if ( m_data.at( pos ) != ' ' &&
- m_data.at( pos ) != '(' &&
- m_data.at( pos ) != ')' &&
- m_data.at( pos ) != '[' &&
- m_data.at( pos ) != ']' &&
- m_data.at( pos ) != '\n' &&
- m_data.at( pos ) != '\r' ) {
+ if ( m_data.at(pos) != ' ' &&
+ m_data.at(pos) != '(' &&
+ m_data.at(pos) != ')' &&
+ m_data.at(pos) != '[' &&
+ m_data.at(pos) != ']' &&
+ m_data.at(pos) != '\n' &&
+ m_data.at(pos) != '\r' )
return true; //unquoted string
- }
return false; //something else, not a string
}
bool ImapStreamParser::hasLiteral()
{
- if ( !waitForMoreData( m_position >= m_data.length() ) ) {
- throw ImapParserException( "Unable to read more data" );
- }
+ if ( !waitForMoreData( m_position >= m_data.length() ) )
+ throw ImapParserException("Unable to read more data");
int savedPos = m_position;
stripLeadingSpaces();
- if ( m_data.at( m_position ) == '{' ) {
+ if ( m_data.at(m_position) == '{' )
+ {
int end = -1;
do {
end = m_data.indexOf( '}', m_position );
- if ( !waitForMoreData( end == -1 ) ) {
- throw ImapParserException( "Unable to read more data" );
- }
- } while ( end == -1 );
+ if ( !waitForMoreData( end == -1 ) )
+ throw ImapParserException("Unable to read more data");
+ } while (end == -1);
Q_ASSERT( end > m_position );
m_literalSize = m_data.mid( m_position + 1, end - m_position - 1 ).toInt();
// strip CRLF
m_position = end + 1;
- if ( m_position < m_data.length() && m_data.at( m_position ) == '\r' ) {
+ if ( m_position < m_data.length() && m_data.at(m_position) == '\r' )
++m_position;
- }
- if ( m_position < m_data.length() && m_data.at( m_position ) == '\n' ) {
+ if ( m_position < m_data.length() && m_data.at(m_position) == '\n' )
++m_position;
- }
//FIXME: Makes sense only on the server side?
- if ( m_isServerModeEnabled && m_literalSize > 0 ) {
+ if (m_isServerModeEnabled && m_literalSize > 0)
sendContinuationResponse( m_literalSize );
- }
return true;
- } else {
+ } else
+ {
m_position = savedPos;
return false;
}
@@ -140,7 +132,7 @@ bool ImapStreamParser::hasLiteral()
bool ImapStreamParser::atLiteralEnd() const
{
- return ( m_literalSize == 0 );
+ return (m_literalSize == 0);
}
QByteArray ImapStreamParser::readLiteralPart()
@@ -148,19 +140,18 @@ QByteArray ImapStreamParser::readLiteralPart()
static qint64 maxLiteralPartSize = 4096;
int size = qMin(maxLiteralPartSize, m_literalSize);
- if ( !waitForMoreData( m_data.length() < m_position + size ) ) {
- throw ImapParserException( "Unable to read more data" );
- }
+ if ( !waitForMoreData( m_data.length() < m_position + size ) )
+ throw ImapParserException("Unable to read more data");
if ( m_data.length() < m_position + size ) { // Still not enough data
// Take what's already there
size = m_data.length() - m_position;
}
- QByteArray result = m_data.mid( m_position, size );
+ QByteArray result = m_data.mid(m_position, size);
m_position += size;
m_literalSize -= size;
- Q_ASSERT( m_literalSize >= 0 );
+ Q_ASSERT(m_literalSize >= 0);
trimBuffer();
return result;
@@ -168,81 +159,80 @@ QByteArray ImapStreamParser::readLiteralPart()
bool ImapStreamParser::hasList()
{
- if ( !waitForMoreData( m_position >= m_data.length() ) ) {
- throw ImapParserException( "Unable to read more data" );
- }
+ if ( !waitForMoreData( m_position >= m_data.length() ) )
+ throw ImapParserException("Unable to read more data");
int savedPos = m_position;
stripLeadingSpaces();
int pos = m_position;
m_position = savedPos;
- if ( m_data.at( pos ) == '(' ) {
+ if ( m_data.at(pos) == '(' )
+ {
return true;
}
+
return false;
}
bool ImapStreamParser::atListEnd()
{
- if ( !waitForMoreData( m_position >= m_data.length() ) ) {
- throw ImapParserException( "Unable to read more data" );
- }
+ if ( !waitForMoreData( m_position >= m_data.length() ) )
+ throw ImapParserException("Unable to read more data");
int savedPos = m_position;
stripLeadingSpaces();
int pos = m_position;
m_position = savedPos;
- if ( m_data.at( pos ) == ')' ) {
+ if ( m_data.at(pos) == ')' )
+ {
m_position = pos + 1;
return true;
}
+
return false;
}
QList<QByteArray> ImapStreamParser::readParenthesizedList()
{
QList<QByteArray> result;
- if ( !waitForMoreData( m_data.length() <= m_position ) ) {
- throw ImapParserException( "Unable to read more data" );
- }
+ if (! waitForMoreData( m_data.length() <= m_position ) )
+ throw ImapParserException("Unable to read more data");
stripLeadingSpaces();
- if ( m_data.at( m_position ) != '(' ) {
+ if ( m_data.at(m_position) != '(' )
return result; //no list found
- }
bool concatToLast = false;
int count = 0;
int sublistbegin = m_position;
int i = m_position + 1;
Q_FOREVER {
- if ( !waitForMoreData( m_data.length() <= i ) ) {
+ if ( !waitForMoreData( m_data.length() <= i ) )
+ {
m_position = i;
- throw ImapParserException( "Unable to read more data" );
+ throw ImapParserException("Unable to read more data");
}
- if ( m_data.at( i ) == '(' ) {
+ if ( m_data.at(i) == '(' ) {
++count;
- if ( count == 1 ) {
+ if ( count == 1 )
sublistbegin = i;
- }
++i;
continue;
}
- if ( m_data.at( i ) == ')' ) {
+ if ( m_data.at(i) == ')' ) {
if ( count <= 0 ) {
m_position = i + 1;
return result;
}
- if ( count == 1 ) {
+ if ( count == 1 )
result.append( m_data.mid( sublistbegin, i - sublistbegin + 1 ) );
- }
--count;
++i;
continue;
}
- if ( m_data.at( i ) == ' ' ) {
+ if ( m_data.at(i) == ' ' ) {
++i;
continue;
}
- if ( m_data.at( i ) == '"' ) {
+ if ( m_data.at(i) == '"' ) {
if ( count > 0 ) {
m_position = i;
parseQuotedString();
@@ -250,27 +240,27 @@ QList<QByteArray> ImapStreamParser::readParenthesizedList()
continue;
}
}
- if ( m_data.at( i ) == '[' ) {
+ if ( m_data.at(i) == '[' ) {
concatToLast = true;
if ( result.isEmpty() ) {
result.append( QByteArray() );
}
- result.last() += '[';
+ result.last()+='[';
++i;
continue;
}
- if ( m_data.at( i ) == ']' ) {
+ if ( m_data.at(i) == ']' ) {
concatToLast = false;
- result.last() += ']';
+ result.last()+=']';
++i;
continue;
}
if ( count == 0 ) {
m_position = i;
QByteArray ba;
- if ( hasLiteral() ) {
- while ( !atLiteralEnd() ) {
- ba += readLiteralPart();
+ if (hasLiteral()) {
+ while (!atLiteralEnd()) {
+ ba+=readLiteralPart();
}
} else {
ba = readString();
@@ -278,14 +268,13 @@ QList<QByteArray> ImapStreamParser::readParenthesizedList()
// We might sometime get some unwanted CRLF, but we're still not at the end
// of the list, would make further string reads fail so eat the CRLFs.
- while ( ( m_position < m_data.size() ) &&
- ( m_data.at( m_position ) == '\r' || m_data.at( m_position ) == '\n' ) ) {
+ while ( ( m_position < m_data.size() ) && ( m_data.at(m_position) == '\r' || m_data.at(m_position) == '\n' ) ) {
m_position++;
}
i = m_position - 1;
- if ( concatToLast ) {
- result.last() += ba;
+ if (concatToLast) {
+ result.last()+=ba;
} else {
result.append( ba );
}
@@ -298,68 +287,68 @@ QList<QByteArray> ImapStreamParser::readParenthesizedList()
bool ImapStreamParser::hasResponseCode()
{
- if ( !waitForMoreData( m_position >= m_data.length() ) ) {
- throw ImapParserException( "Unable to read more data" );
- }
+ if ( !waitForMoreData( m_position >= m_data.length() ) )
+ throw ImapParserException("Unable to read more data");
int savedPos = m_position;
stripLeadingSpaces();
int pos = m_position;
m_position = savedPos;
- if ( m_data.at( pos ) == '[' ) {
+ if ( m_data.at(pos) == '[' )
+ {
m_position = pos + 1;
return true;
}
+
return false;
}
bool ImapStreamParser::atResponseCodeEnd()
{
- if ( !waitForMoreData( m_position >= m_data.length() ) ) {
- throw ImapParserException( "Unable to read more data" );
- }
+ if ( !waitForMoreData( m_position >= m_data.length() ) )
+ throw ImapParserException("Unable to read more data");
int savedPos = m_position;
stripLeadingSpaces();
int pos = m_position;
m_position = savedPos;
- if ( m_data.at( pos ) == ']' ) {
+ if ( m_data.at(pos) == ']' )
+ {
m_position = pos + 1;
return true;
}
+
return false;
}
QByteArray ImapStreamParser::parseQuotedString()
{
QByteArray result;
- if ( !waitForMoreData( m_data.length() == 0 ) ) {
- throw ImapParserException( "Unable to read more data" );
- }
+ if (! waitForMoreData( m_data.length() == 0 ) )
+ throw ImapParserException("Unable to read more data");
stripLeadingSpaces();
int end = m_position;
result.clear();
- if ( !waitForMoreData( m_position >= m_data.length() ) ) {
- throw ImapParserException( "Unable to read more data" );
- }
- if ( !waitForMoreData( m_position >= m_data.length() ) ) {
- throw ImapParserException( "Unable to read more data" );
- }
+ if ( !waitForMoreData( m_position >= m_data.length() ) )
+ throw ImapParserException("Unable to read more data");
+ if ( !waitForMoreData( m_position >= m_data.length() ) )
+ throw ImapParserException("Unable to read more data");
bool foundSlash = false;
// quoted string
- if ( m_data.at( m_position ) == '"' ) {
+ if ( m_data.at(m_position) == '"' ) {
++m_position;
int i = m_position;
Q_FOREVER {
- if ( !waitForMoreData( m_data.length() <= i ) ) {
+ if ( !waitForMoreData( m_data.length() <= i ) )
+ {
m_position = i;
- throw ImapParserException( "Unable to read more data" );
+ throw ImapParserException("Unable to read more data");
}
- if ( m_data.at( i ) == '\\' ) {
+ if ( m_data.at(i) == '\\' ) {
i += 2;
foundSlash = true;
continue;
}
- if ( m_data.at( i ) == '"' ) {
+ if ( m_data.at(i) == '"' ) {
result = m_data.mid( m_position, i - m_position );
end = i + 1; // skip the '"'
break;
@@ -373,42 +362,32 @@ QByteArray ImapStreamParser::parseQuotedString()
bool reachedInputEnd = true;
int i = m_position;
Q_FOREVER {
- if ( !waitForMoreData( m_data.length() <= i ) ) {
+ if ( !waitForMoreData( m_data.length() <= i ) )
+ {
m_position = i;
- throw ImapParserException( "Unable to read more data" );
+ throw ImapParserException("Unable to read more data");
}
- 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 ) == '"' ) {
+ 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) == '"') {
end = i;
reachedInputEnd = false;
break;
}
- if ( m_data.at( i ) == '\\' ) {
+ if (m_data.at(i) == '\\')
foundSlash = true;
- }
i++;
}
- if ( reachedInputEnd ) { //FIXME: how can it get here?
+ if ( reachedInputEnd ) //FIXME: how can it get here?
end = m_data.length();
- }
result = m_data.mid( m_position, end - m_position );
}
// strip quotes
if ( foundSlash ) {
- while ( result.contains( "\\\"" ) ) {
+ while ( result.contains( "\\\"" ) )
result.replace( "\\\"", "\"" );
- }
- while ( result.contains( "\\\\" ) ) {
+ while ( result.contains( "\\\\" ) )
result.replace( "\\\\", "\\" );
- }
}
m_position = end;
return result;
@@ -417,28 +396,24 @@ QByteArray ImapStreamParser::parseQuotedString()
qint64 ImapStreamParser::readNumber( bool * ok )
{
qint64 result;
- if ( ok ) {
+ if ( ok )
*ok = false;
- }
- if ( !waitForMoreData( m_data.length() == 0 ) ) {
- throw ImapParserException( "Unable to read more data" );
- }
+ if (! waitForMoreData( m_data.length() == 0 ) )
+ throw ImapParserException("Unable to read more data");
stripLeadingSpaces();
- if ( !waitForMoreData( m_position >= m_data.length() ) ) {
- throw ImapParserException( "Unable to read more data" );
- }
- if ( m_position >= m_data.length() ) {
- throw ImapParserException( "Unable to read more data" );
- }
+ if ( !waitForMoreData( m_position >= m_data.length() ) )
+ throw ImapParserException("Unable to read more data");
+ if ( m_position >= m_data.length() )
+ throw ImapParserException("Unable to read more data");
int i = m_position;
Q_FOREVER {
- if ( !waitForMoreData( m_data.length() <= i ) ) {
+ if ( !waitForMoreData( m_data.length() <= i ) )
+ {
m_position = i;
- throw ImapParserException( "Unable to read more data" );
+ throw ImapParserException("Unable to read more data");
}
- if ( !isdigit( m_data.at( i ) ) ) {
+ if ( !isdigit( m_data.at( i ) ) )
break;
- }
++i;
}
const QByteArray tmp = m_data.mid( m_position, i - m_position );
@@ -450,7 +425,8 @@ qint64 ImapStreamParser::readNumber( bool * ok )
void ImapStreamParser::stripLeadingSpaces()
{
for ( int i = m_position; i < m_data.length(); ++i ) {
- if ( m_data.at( i ) != ' ' ) {
+ if ( m_data.at(i) != ' ' )
+ {
m_position = i;
return;
}
@@ -462,9 +438,10 @@ bool ImapStreamParser::waitForMoreData( bool wait )
{
if ( wait ) {
if ( m_socket->bytesAvailable() > 0 ||
- m_socket->waitForReadyRead( 30000 ) ) {
+ m_socket->waitForReadyRead(30000) ) {
m_data.append( m_socket->readAll() );
- } else {
+ } else
+ {
return false;
}
}
@@ -478,31 +455,28 @@ void ImapStreamParser::setData( const QByteArray &data )
QByteArray ImapStreamParser::readRemainingData()
{
- return m_data.mid( m_position );
+ return m_data.mid(m_position);
}
int ImapStreamParser::availableDataSize() const
{
- return m_socket->bytesAvailable() + m_data.size() - m_position;
+ return m_socket->bytesAvailable()+m_data.size()-m_position;
}
bool ImapStreamParser::atCommandEnd()
{
int savedPos = m_position;
do {
- if ( !waitForMoreData( m_position >= m_data.length() ) ) {
- throw ImapParserException( "Unable to read more data" );
- }
+ if ( !waitForMoreData( m_position >= m_data.length() ) )
+ throw ImapParserException("Unable to read more data");
stripLeadingSpaces();
} while ( m_position >= m_data.size() );
- if ( m_data.at( m_position ) == '\n' || m_data.at( m_position ) == '\r' ) {
- if ( m_data.at( m_position ) == '\r' ) {
+ if ( m_data.at(m_position) == '\n' || m_data.at(m_position) == '\r') {
+ if ( m_data.at(m_position) == '\r' )
++m_position;
- }
- if ( m_position < m_data.length() && m_data.at( m_position ) == '\n' ) {
+ if ( m_position < m_data.length() && m_data.at(m_position) == '\n' )
++m_position;
- }
// We'd better empty m_data from time to time before it grows out of control
trimBuffer();
@@ -519,30 +493,29 @@ QByteArray ImapStreamParser::readUntilCommandEnd()
int i = m_position;
int paranthesisBalance = 0;
Q_FOREVER {
- if ( !waitForMoreData( m_data.length() <= i ) ) {
+ if ( !waitForMoreData( m_data.length() <= i ) )
+ {
m_position = i;
- throw ImapParserException( "Unable to read more data" );
+ throw ImapParserException("Unable to read more data");
}
- if ( m_data.at( i ) == '{' ) {
+ if ( m_data.at(i) == '{' )
+ {
m_position = i - 1;
hasLiteral(); //init literal size
- result.append( m_data.mid( i - 1, m_position - i + 1 ) );
- while ( !atLiteralEnd() ) {
+ result.append(m_data.mid(i-1, m_position - i +1));
+ while (!atLiteralEnd())
+ {
result.append( readLiteralPart() );
}
i = m_position;
}
- if ( m_data.at( i ) == '(' ) {
+ if ( m_data.at(i) == '(' )
paranthesisBalance++;
- }
- if ( m_data.at( i ) == ')' ) {
+ if ( m_data.at(i) == ')' )
paranthesisBalance--;
- }
- if ( ( i == m_data.length() && paranthesisBalance == 0 ) ||
- m_data.at( i ) == '\n' || m_data.at( i ) == '\r') {
+ if ( ( i == m_data.length() && paranthesisBalance == 0 ) || m_data.at(i) == '\n' || m_data.at(i) == '\r')
break; //command end
- }
- result.append( m_data.at( i ) );
+ result.append( m_data.at(i) );
++i;
}
m_position = i;
@@ -552,17 +525,16 @@ QByteArray ImapStreamParser::readUntilCommandEnd()
void ImapStreamParser::sendContinuationResponse( qint64 size )
{
- QByteArray block = "+ Ready for literal data (expecting " +
- QByteArray::number( size ) + " bytes)\r\n";
- m_socket->write( block );
- m_socket->waitForBytesWritten( 30000 );
+ QByteArray block = "+ Ready for literal data (expecting "
+ + QByteArray::number( size ) + " bytes)\r\n";
+ m_socket->write(block);
+ m_socket->waitForBytesWritten(30000);
}
void ImapStreamParser::trimBuffer()
{
- if ( m_position < 4096 ) { // right() is expensive, so don't do it for every line
+ if ( m_position < 4096 ) // right() is expensive, so don't do it for every line
return;
- }
- m_data = m_data.right( m_data.size() - m_position );
+ m_data = m_data.right(m_data.size()-m_position);
m_position = 0;
}