зеркало из https://github.com/mozilla/pjs.git
Remove old & slow ReadLine code. Replace it with nsMsgLineStreamBuffer. This also involved cleaning out a lot of code for displaying messages as the logic of the read line loop changed.
This commit is contained in:
Родитель
b013207c0e
Коммит
2f08be5390
|
@ -24,6 +24,7 @@
|
||||||
#include "nsIOutputStream.h"
|
#include "nsIOutputStream.h"
|
||||||
#include "nsINetService.h"
|
#include "nsINetService.h"
|
||||||
#include "nsIMsgDatabase.h"
|
#include "nsIMsgDatabase.h"
|
||||||
|
#include "nsMsgLineBuffer.h"
|
||||||
#include "nsIMessage.h"
|
#include "nsIMessage.h"
|
||||||
#include "nsMsgDBCID.h"
|
#include "nsMsgDBCID.h"
|
||||||
|
|
||||||
|
@ -80,14 +81,15 @@ nsMailboxProtocol::~nsMailboxProtocol()
|
||||||
// release all of our event sinks
|
// release all of our event sinks
|
||||||
NS_IF_RELEASE(m_mailboxParser);
|
NS_IF_RELEASE(m_mailboxParser);
|
||||||
|
|
||||||
// free our local state
|
|
||||||
PR_FREEIF(m_dataBuf);
|
|
||||||
|
|
||||||
// free handles on all networking objects...
|
// free handles on all networking objects...
|
||||||
NS_IF_RELEASE(m_outputStream);
|
NS_IF_RELEASE(m_outputStream);
|
||||||
NS_IF_RELEASE(m_outputConsumer);
|
NS_IF_RELEASE(m_outputConsumer);
|
||||||
NS_IF_RELEASE(m_transport);
|
NS_IF_RELEASE(m_transport);
|
||||||
NS_IF_RELEASE(m_runningUrl);
|
NS_IF_RELEASE(m_runningUrl);
|
||||||
|
|
||||||
|
// free our local state
|
||||||
|
if (m_lineStreamBuffer)
|
||||||
|
delete m_lineStreamBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsMailboxProtocol::Initialize(nsIURL * aURL)
|
void nsMailboxProtocol::Initialize(nsIURL * aURL)
|
||||||
|
@ -136,10 +138,10 @@ void nsMailboxProtocol::Initialize(nsIURL * aURL)
|
||||||
rv = m_transport->SetInputStreamConsumer((nsIStreamListener *) this);
|
rv = m_transport->SetInputStreamConsumer((nsIStreamListener *) this);
|
||||||
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to register MAILBOX instance as a consumer on the socket");
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to register MAILBOX instance as a consumer on the socket");
|
||||||
|
|
||||||
m_dataBuf = (char *) PR_Malloc(sizeof(char) * OUTPUT_BUFFER_SIZE);
|
|
||||||
m_dataBufSize = OUTPUT_BUFFER_SIZE;
|
|
||||||
m_mailboxParser = nsnull;
|
m_mailboxParser = nsnull;
|
||||||
|
|
||||||
|
m_lineStreamBuffer = new nsMsgLineStreamBuffer(OUTPUT_BUFFER_SIZE, PR_TRUE);
|
||||||
|
|
||||||
m_nextState = MAILBOX_READ_FOLDER;
|
m_nextState = MAILBOX_READ_FOLDER;
|
||||||
m_initialState = MAILBOX_READ_FOLDER;
|
m_initialState = MAILBOX_READ_FOLDER;
|
||||||
|
|
||||||
|
@ -245,55 +247,6 @@ NS_IMETHODIMP nsMailboxProtocol::OnStopBinding(nsIURL* aURL, nsresult aStatus, c
|
||||||
// End of nsIStreamListenerSupport
|
// End of nsIStreamListenerSupport
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
PRInt32 nsMailboxProtocol::ReadLine(nsIInputStream * inputStream, PRUint32 length, char ** line)
|
|
||||||
{
|
|
||||||
// I haven't looked into writing this yet. We have a couple of possibilities:
|
|
||||||
// (1) insert ReadLine *yuck* into here or better yet into the nsIInputStream
|
|
||||||
// then we can just turn around and call it here.
|
|
||||||
// OR
|
|
||||||
// (2) we write "protocol" specific code for news which looks for a CRLF in the incoming
|
|
||||||
// stream. If it finds it, that's our new line that we put into @param line. We'd
|
|
||||||
// need a buffer (m_dataBuf) to store extra info read in from the stream.....
|
|
||||||
|
|
||||||
// read out everything we've gotten back and return it in line...this won't work for much but it does
|
|
||||||
// get us going...
|
|
||||||
|
|
||||||
// XXX: please don't hold this quick "algorithm" against me. I just want to read just one
|
|
||||||
// line for the stream. I promise this is ONLY temporary to test out NNTP. We need a generic
|
|
||||||
// way to read one line from a stream. For now I'm going to read out one character at a time.
|
|
||||||
// (I said it was only temporary =)) and test for newline...
|
|
||||||
|
|
||||||
PRUint32 numBytesToRead = 0; // MAX # bytes to read from the stream
|
|
||||||
PRUint32 numBytesRead = 0; // total number bytes we have read from the stream during this call
|
|
||||||
inputStream->GetLength(&length); // refresh the length in case it has changed...
|
|
||||||
|
|
||||||
if (length > OUTPUT_BUFFER_SIZE)
|
|
||||||
numBytesToRead = OUTPUT_BUFFER_SIZE;
|
|
||||||
else
|
|
||||||
numBytesToRead = length;
|
|
||||||
|
|
||||||
m_dataBuf[0] = '\0';
|
|
||||||
PRUint32 numBytesLastRead = 0; // total number of bytes read in the last cycle...
|
|
||||||
do
|
|
||||||
{
|
|
||||||
inputStream->Read(m_dataBuf + numBytesRead /* offset into m_dataBuf */, 1 /* read just one byte */, &numBytesLastRead);
|
|
||||||
numBytesRead += numBytesLastRead;
|
|
||||||
} while (numBytesRead <= numBytesToRead && numBytesLastRead > 0 && m_dataBuf[numBytesRead-1] != '\n');
|
|
||||||
|
|
||||||
m_dataBuf[numBytesRead] = '\0'; // null terminate the string.
|
|
||||||
|
|
||||||
// oops....we also want to eat up the '\n' and the \r'...
|
|
||||||
if (numBytesRead > 1 && m_dataBuf[numBytesRead-2] == '\r')
|
|
||||||
m_dataBuf[numBytesRead-2] = '\0'; // hit both cr and lf...
|
|
||||||
else
|
|
||||||
if (numBytesRead > 0 && (m_dataBuf[numBytesRead-1] == '\r' || m_dataBuf[numBytesRead-1] == '\n'))
|
|
||||||
m_dataBuf[numBytesRead-1] = '\0';
|
|
||||||
|
|
||||||
if (line)
|
|
||||||
*line = m_dataBuf;
|
|
||||||
return numBytesRead;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Writes the data contained in dataBuffer into the current output stream. It also informs
|
* Writes the data contained in dataBuffer into the current output stream. It also informs
|
||||||
* the transport layer that this data is now available for transmission.
|
* the transport layer that this data is now available for transmission.
|
||||||
|
@ -481,7 +434,7 @@ PRInt32 nsMailboxProtocol::ReadFolderResponse(nsIInputStream * inputStream, PRUi
|
||||||
|
|
||||||
PRInt32 nsMailboxProtocol::ReadMessageResponse(nsIInputStream * inputStream, PRUint32 length)
|
PRInt32 nsMailboxProtocol::ReadMessageResponse(nsIInputStream * inputStream, PRUint32 length)
|
||||||
{
|
{
|
||||||
char *line;
|
char *line = nsnull;
|
||||||
PRInt32 status = 0;
|
PRInt32 status = 0;
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
|
|
||||||
|
@ -495,54 +448,20 @@ PRInt32 nsMailboxProtocol::ReadMessageResponse(nsIInputStream * inputStream, PRU
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char outputBuffer[OUTPUT_BUFFER_SIZE];
|
PRBool pauseForMoreData = PR_FALSE;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
status = ReadLine(inputStream, length, &line);
|
line = m_lineStreamBuffer->ReadNextLine(inputStream, pauseForMoreData);
|
||||||
if(status == 0)
|
|
||||||
{
|
|
||||||
m_nextState = MAILBOX_ERROR_DONE;
|
|
||||||
ClearFlag(MAILBOX_PAUSE_FOR_READ);
|
|
||||||
m_runningUrl->SetErrorMessage("error message not implemented yet");
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status > length)
|
|
||||||
length = 0;
|
|
||||||
else
|
|
||||||
length -= status;
|
|
||||||
|
|
||||||
if(!line)
|
|
||||||
return(status); /* no line yet or error */
|
|
||||||
|
|
||||||
if (!line || (line[0] == '.' && line[1] == 0))
|
if (!line || (line[0] == '.' && line[1] == 0))
|
||||||
{
|
{
|
||||||
m_nextState = MAILBOX_DONE;
|
// we reached the end of the message!
|
||||||
// and close the article file if it was open....
|
|
||||||
if (m_tempMessageFile)
|
|
||||||
PR_Close(m_tempMessageFile);
|
|
||||||
|
|
||||||
// mscott: hack alert...now that the file is done...turn around and fire a file url
|
|
||||||
// to display the message....
|
|
||||||
if (m_displayConsumer)
|
|
||||||
{
|
|
||||||
nsFilePath filePath(MESSAGE_PATH);
|
|
||||||
nsFileURL fileURL(filePath);
|
|
||||||
char * message_path_url = PL_strdup(fileURL.GetAsString());
|
|
||||||
|
|
||||||
m_displayConsumer->LoadURL(nsAutoString(message_path_url), nsnull, PR_TRUE, nsURLReload, 0);
|
|
||||||
|
|
||||||
PR_FREEIF(message_path_url);
|
|
||||||
}
|
|
||||||
|
|
||||||
ClearFlag(MAILBOX_PAUSE_FOR_READ);
|
ClearFlag(MAILBOX_PAUSE_FOR_READ);
|
||||||
} // otherwise process the line
|
} // otherwise process the line
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (line[0] == '.')
|
if (line[0] == '.')
|
||||||
PL_strcpy (outputBuffer, line + 1);
|
line++; // skip over the '.'
|
||||||
else
|
|
||||||
PL_strcpy (outputBuffer, line);
|
|
||||||
|
|
||||||
/* When we're sending this line to a converter (ie,
|
/* When we're sending this line to a converter (ie,
|
||||||
it's a message/rfc822) use the local line termination
|
it's a message/rfc822) use the local line termination
|
||||||
|
@ -553,15 +472,15 @@ PRInt32 nsMailboxProtocol::ReadMessageResponse(nsIInputStream * inputStream, PRU
|
||||||
terminator as it is read.
|
terminator as it is read.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
PL_strcat (outputBuffer, LINEBREAK);
|
|
||||||
|
|
||||||
if (m_tempMessageFile)
|
if (m_tempMessageFile)
|
||||||
PR_Write(m_tempMessageFile,(void *) outputBuffer,PL_strlen(outputBuffer));
|
{
|
||||||
|
if (line)
|
||||||
|
PR_Write(m_tempMessageFile,(void *) line,PL_strlen(line));
|
||||||
|
PR_Write(m_tempMessageFile, (void *) LINEBREAK, PL_strlen(CRLF));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
while (length > 0 && status > 0);
|
}
|
||||||
|
while (line && !pauseForMoreData);
|
||||||
}
|
}
|
||||||
|
|
||||||
SetFlag(MAILBOX_PAUSE_FOR_READ); // wait for more data to become available...
|
SetFlag(MAILBOX_PAUSE_FOR_READ); // wait for more data to become available...
|
||||||
|
|
|
@ -69,6 +69,8 @@ typedef enum _MailboxStatesEnum {
|
||||||
MAILBOX_FINISH_COPY_MESSAGES
|
MAILBOX_FINISH_COPY_MESSAGES
|
||||||
} MailboxStatesEnum;
|
} MailboxStatesEnum;
|
||||||
|
|
||||||
|
class nsMsgLineStreamBuffer;
|
||||||
|
|
||||||
class nsMailboxProtocol : public nsIStreamListener
|
class nsMailboxProtocol : public nsIStreamListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -124,8 +126,6 @@ private:
|
||||||
PRUint32 m_flags; // used to store flag information
|
PRUint32 m_flags; // used to store flag information
|
||||||
nsIMailboxUrl *m_runningUrl; // the nsIMailboxURL that is currently running
|
nsIMailboxUrl *m_runningUrl; // the nsIMailboxURL that is currently running
|
||||||
nsMailboxAction m_mailboxAction; // current mailbox action associated with this connnection...
|
nsMailboxAction m_mailboxAction; // current mailbox action associated with this connnection...
|
||||||
char *m_dataBuf;
|
|
||||||
PRUint32 m_dataBufSize;
|
|
||||||
PRInt32 m_originalContentLength; /* the content length at the time of calling graph progress */
|
PRInt32 m_originalContentLength; /* the content length at the time of calling graph progress */
|
||||||
|
|
||||||
// Event sink handles
|
// Event sink handles
|
||||||
|
@ -138,6 +138,7 @@ private:
|
||||||
nsITransport * m_transport;
|
nsITransport * m_transport;
|
||||||
nsIOutputStream * m_outputStream; // this will be obtained from the transport interface
|
nsIOutputStream * m_outputStream; // this will be obtained from the transport interface
|
||||||
nsIStreamListener * m_outputConsumer; // this will be obtained from the transport interface
|
nsIStreamListener * m_outputConsumer; // this will be obtained from the transport interface
|
||||||
|
nsMsgLineStreamBuffer * m_lineStreamBuffer; // used to efficiently extract lines from the incoming data stream
|
||||||
|
|
||||||
// Generic state information -- What state are we in? What state do we want to go to
|
// Generic state information -- What state are we in? What state do we want to go to
|
||||||
// after the next response? What was the last response code? etc.
|
// after the next response? What was the last response code? etc.
|
||||||
|
@ -161,8 +162,6 @@ private:
|
||||||
// Communication methods --> Reading and writing protocol
|
// Communication methods --> Reading and writing protocol
|
||||||
////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
PRInt32 ReadLine(nsIInputStream * inputStream, PRUint32 length, char ** line);
|
|
||||||
|
|
||||||
// SendData not only writes the NULL terminated data in dataBuffer to our output stream
|
// SendData not only writes the NULL terminated data in dataBuffer to our output stream
|
||||||
// but it also informs the consumer that the data has been written to the stream.
|
// but it also informs the consumer that the data has been written to the stream.
|
||||||
PRInt32 SendData(const char * dataBuffer);
|
PRInt32 SendData(const char * dataBuffer);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче