Fixed multi-line terminator spanning on multiple incoming packets.

This commit is contained in:
Vincent Richard 2005-06-16 19:52:57 +00:00
parent fbfa4f0b86
commit 090c817611

View File

@ -24,6 +24,7 @@
#include "vmime/platformDependant.hpp" #include "vmime/platformDependant.hpp"
#include "vmime/messageId.hpp" #include "vmime/messageId.hpp"
#include "vmime/utility/md5.hpp" #include "vmime/utility/md5.hpp"
#include "vmime/utility/filteredStream.hpp"
#include <algorithm> #include <algorithm>
@ -412,7 +413,6 @@ void POP3Store::readResponse(string& buffer, const bool multiLine,
void POP3Store::readResponse(utility::outputStream& os, void POP3Store::readResponse(utility::outputStream& os,
utility::progressionListener* progress, const int predictedSize) utility::progressionListener* progress, const int predictedSize)
{ {
bool foundTerminator = false;
int current = 0, total = predictedSize; int current = 0, total = predictedSize;
string temp; string temp;
@ -424,9 +424,14 @@ void POP3Store::readResponse(utility::outputStream& os,
if (m_timeoutHandler) if (m_timeoutHandler)
m_timeoutHandler->resetTimeOut(); m_timeoutHandler->resetTimeOut();
string::value_type last1 = '\0', last2 = '\0'; utility::inputStreamSocketAdapter sis(*m_socket);
utility::stopSequenceFilteredInputStream <5> sfis1(sis, "\r\n.\r\n");
utility::stopSequenceFilteredInputStream <3> sfis2(sfis1, "\n.\n");
utility::dotFilteredInputStream dfis(sfis2); // "\n.." --> "\n."
for ( ; !foundTerminator ; ) utility::inputStream& is = dfis;
while (!is.eof())
{ {
#if 0 // not supported #if 0 // not supported
// Check for possible cancellation // Check for possible cancellation
@ -442,10 +447,10 @@ void POP3Store::readResponse(utility::outputStream& os,
} }
// Receive data from the socket // Receive data from the socket
string receiveBuffer; utility::stream::value_type buffer[65536];
m_socket->receive(receiveBuffer); const utility::stream::size_type read = is.read(buffer, sizeof(buffer));
if (receiveBuffer.empty()) // buffer is empty if (read == 0) // buffer is empty
{ {
platformDependant::getHandler()->wait(); platformDependant::getHandler()->wait();
continue; continue;
@ -455,32 +460,10 @@ void POP3Store::readResponse(utility::outputStream& os,
if (m_timeoutHandler) if (m_timeoutHandler)
m_timeoutHandler->resetTimeOut(); m_timeoutHandler->resetTimeOut();
// Check for transparent characters: '\n..' becomes '\n.'
const string::value_type first = receiveBuffer[0];
if (first == '.' && last2 == '\n' && last1 == '.')
{
receiveBuffer.erase(receiveBuffer.begin());
}
else if (receiveBuffer.length() >= 2 && first == '.' &&
receiveBuffer[1] == '.' && last1 == '\n')
{
receiveBuffer.erase(receiveBuffer.begin());
}
for (string::size_type trans ;
string::npos != (trans = receiveBuffer.find("\n..")) ; )
{
receiveBuffer.replace(trans, 3, "\n.");
}
last1 = receiveBuffer[receiveBuffer.length() - 1];
last2 = (receiveBuffer.length() >= 2) ? receiveBuffer[receiveBuffer.length() - 2] : 0;
// If we don't have extracted the response code yet // If we don't have extracted the response code yet
if (!codeDone) if (!codeDone)
{ {
temp += receiveBuffer; temp += string(buffer, read);
string firstLine; string firstLine;
@ -489,21 +472,19 @@ void POP3Store::readResponse(utility::outputStream& os,
if (!isSuccessResponse(firstLine)) if (!isSuccessResponse(firstLine))
throw exceptions::command_error("?", firstLine); throw exceptions::command_error("?", firstLine);
receiveBuffer = temp; codeDone = true;
os.write(temp.data(), temp.length());
temp.clear(); temp.clear();
codeDone = true; continue;
} }
} }
else
if (codeDone)
{ {
// Check for terminator string (and strip it if present)
foundTerminator = checkTerminator(receiveBuffer, true);
// Inject the data into the output stream // Inject the data into the output stream
os.write(receiveBuffer.data(), receiveBuffer.length()); os.write(buffer, read);
current += receiveBuffer.length(); current += read;
// Notify progression // Notify progression
if (progress) if (progress)
@ -649,3 +630,4 @@ const std::vector <serviceInfos::property> POP3Store::_infos::getAvailableProper
} // pop3 } // pop3
} // messaging } // messaging
} // vmime } // vmime