Skip to content

Commit

Permalink
Merge pull request #37 from nemomobile-packages/imap-buffer
Browse files Browse the repository at this point in the history
[qmf] Prevents IMAP4 incoming data read from stopping when handling large requests.
  • Loading branch information
VDVsx committed May 21, 2014
2 parents 38f86d7 + 7a5ecbd commit 85e21a9
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 1 deletion.
16 changes: 16 additions & 0 deletions qmf/src/libraries/qmfmessageserver/qmailtransport.cpp
Expand Up @@ -382,6 +382,14 @@ bool QMailTransport::canReadLine() const
return mSocket->canReadLine();
}

/*!
Returns true if the transport is readable and there are bytes available to read; otherwise returns false.
*/
bool QMailTransport::bytesAvailable() const
{
return mSocket->isReadable() && mSocket->bytesAvailable();
}

/*!
Reads a line from the device, but no more than \a maxSize characters, and returns the result as a QByteArray.
*/
Expand All @@ -390,6 +398,14 @@ QByteArray QMailTransport::readLine(qint64 maxSize)
return mSocket->readLine(maxSize);
}

/*!
Reads all the data available in the device, and returns the result as a QByteArray.
*/
QByteArray QMailTransport::readAll()
{
return mSocket->readAll();
}

/*! \internal */
void QMailTransport::connectionEstablished()
{
Expand Down
2 changes: 2 additions & 0 deletions qmf/src/libraries/qmfmessageserver/qmailtransport.h
Expand Up @@ -102,7 +102,9 @@ class MESSAGESERVER_EXPORT QMailTransport : public QObject

// Read line-oriented data from the transport (must have an open connection)
bool canReadLine() const;
bool bytesAvailable() const;
QByteArray readLine(qint64 maxSize = 0);
QByteArray readAll();

// Assists with counting bytes written to the device
void mark();
Expand Down
10 changes: 10 additions & 0 deletions qmf/src/plugins/messageservices/imap/imapprotocol.cpp
Expand Up @@ -3319,6 +3319,11 @@ QString ImapProtocol::sendCommandLiteral(const QString &cmd, uint length)

void ImapProtocol::incomingData()
{
if (!_lineBuffer.isEmpty() && _transport->imapCanReadLine()) {
processResponse(QString::fromLatin1(_lineBuffer + _transport->imapReadLine()));
_lineBuffer.clear();
}

int readLines = 0;
while (_transport->imapCanReadLine()) {
processResponse(QString::fromLatin1(_transport->imapReadLine()));
Expand All @@ -3330,6 +3335,11 @@ void ImapProtocol::incomingData()
}
}

if (_transport->bytesAvailable()) {
// If there is an incomplete line, read it from the socket buffer to ensure we get readyRead signal next time
_lineBuffer.append(_transport->readAll());
}

_incomingDataTimer.stop();
}

Expand Down
1 change: 1 addition & 0 deletions qmf/src/plugins/messageservices/imap/imapprotocol.h
Expand Up @@ -318,6 +318,7 @@ protected slots:
bool _receivedCapabilities;

static const int MAX_LINES = 30;
QByteArray _lineBuffer;
};

#endif
34 changes: 34 additions & 0 deletions qmf/src/plugins/messageservices/imap/imaptransport.cpp
Expand Up @@ -126,7 +126,9 @@ class Rfc1951Decompressor

bool consume(QIODevice *in);
bool canReadLine() const;
bool bytesAvailable() const;
QByteArray readLine();
QByteArray readAll();

private:
int _chunkSize;
Expand Down Expand Up @@ -183,6 +185,11 @@ bool Rfc1951Decompressor::canReadLine() const
return _output.contains('\n');
}

bool Rfc1951Decompressor::bytesAvailable() const
{
return !_output.isEmpty();
}

QByteArray Rfc1951Decompressor::readLine()
{
int eolPos = _output.indexOf('\n');
Expand All @@ -194,6 +201,13 @@ QByteArray Rfc1951Decompressor::readLine()
_output = _output.mid(eolPos + 1);
return result;
}

QByteArray Rfc1951Decompressor::readAll()
{
QByteArray result = _output;
_output.clear();
return result;
}
#else
class Rfc1951Compressor
{
Expand All @@ -212,7 +226,9 @@ class Rfc1951Decompressor

bool consume(QIODevice *) { return true; }
bool canReadLine() const { return true; }
bool bytesAvailable() const { return true; }
QByteArray readLine() { return QByteArray(); }
QByteArray readAll() { return QByteArray(); }
};
#endif

Expand Down Expand Up @@ -242,6 +258,15 @@ bool ImapTransport::imapCanReadLine()
}
}

bool ImapTransport::imapBytesAvailable()
{
if(!compress()) {
return bytesAvailable();
} else {
return _decompressor->bytesAvailable();
}
}

QByteArray ImapTransport::imapReadLine()
{
if (!compress()) {
Expand All @@ -251,6 +276,15 @@ QByteArray ImapTransport::imapReadLine()
}
}

QByteArray ImapTransport::imapReadAll()
{
if (!compress()) {
return readAll();
} else {
return _decompressor->readAll();
}
}

bool ImapTransport::imapWrite(QByteArray *in)
{
if (!compress()) {
Expand Down
2 changes: 2 additions & 0 deletions qmf/src/plugins/messageservices/imap/imaptransport.h
Expand Up @@ -63,7 +63,9 @@ class ImapTransport : public QMailTransport

// Read line-oriented data from the transport (must have an open connection)
bool imapCanReadLine();
bool imapBytesAvailable();
QByteArray imapReadLine();
QByteArray imapReadAll();

// Write data to the transport (must have an open connection)
bool imapWrite(QByteArray *in);
Expand Down
2 changes: 1 addition & 1 deletion rpm/qmf-qt5.spec
@@ -1,6 +1,6 @@
Name: qmf-qt5
Summary: Qt Messaging Framework (QMF) Qt5
Version: 4.0.4+git13
Version: 4.0.4+git17
Release: 1
Group: System/Libraries
License: LGPLv2.1 with exception or GPLv3
Expand Down

0 comments on commit 85e21a9

Please sign in to comment.