Fix for bug 135279. Need to be able to specify a line token other than LF when reading a stream buffer. Local file on Mac or CR as line ending. R=naving, SR=mscott

This commit is contained in:
ducarroz%netscape.com 2002-05-03 21:36:33 +00:00
parent f16077b06e
commit 8cc82f489f
3 changed files with 46 additions and 40 deletions

View File

@ -286,8 +286,8 @@ PRInt32 nsMsgLineBuffer::FlushLastLine()
// read but unprocessed stream data in a buffer. // read but unprocessed stream data in a buffer.
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
nsMsgLineStreamBuffer::nsMsgLineStreamBuffer(PRUint32 aBufferSize, PRBool aAllocateNewLines, PRBool aEatCRLFs) nsMsgLineStreamBuffer::nsMsgLineStreamBuffer(PRUint32 aBufferSize, PRBool aAllocateNewLines, PRBool aEatCRLFs, char aLineToken)
: m_eatCRLFs(aEatCRLFs), m_allocateNewLines(aAllocateNewLines) : m_eatCRLFs(aEatCRLFs), m_allocateNewLines(aAllocateNewLines), m_lineToken(aLineToken)
{ {
NS_PRECONDITION(aBufferSize > 0, "invalid buffer size!!!"); NS_PRECONDITION(aBufferSize > 0, "invalid buffer size!!!");
m_dataBuffer = nsnull; m_dataBuffer = nsnull;
@ -339,7 +339,7 @@ char * nsMsgLineStreamBuffer::ReadNextLine(nsIInputStream * aInputStream, PRUint
char * startOfLine = m_dataBuffer+m_startPos; char * startOfLine = m_dataBuffer+m_startPos;
if (m_numBytesInBuffer > 0) // any data in our internal buffer? if (m_numBytesInBuffer > 0) // any data in our internal buffer?
endOfLine = PL_strchr(startOfLine, '\n'); // see if we already have a line ending... endOfLine = PL_strchr(startOfLine, m_lineToken); // see if we already have a line ending...
// it's possible that we got here before the first time we receive data from the server // it's possible that we got here before the first time we receive data from the server
// so aInputStream will be nsnull... // so aInputStream will be nsnull...
@ -385,63 +385,62 @@ char * nsMsgLineStreamBuffer::ReadNextLine(nsIInputStream * aInputStream, PRUint
{ {
aInputStream->Read(startOfLine + m_numBytesInBuffer, aInputStream->Read(startOfLine + m_numBytesInBuffer,
numBytesToCopy, &numBytesCopied); numBytesToCopy, &numBytesCopied);
m_numBytesInBuffer += numBytesCopied; m_numBytesInBuffer += numBytesCopied;
m_dataBuffer[m_startPos+m_numBytesInBuffer] = '\0'; m_dataBuffer[m_startPos+m_numBytesInBuffer] = '\0';
PRUint32 i,j=0; PRUint32 i,j=0;
for (i=0;i <m_numBytesInBuffer;i++) //strip nulls for (i=0;i <m_numBytesInBuffer;i++) //strip nulls
{ {
if (startOfLine[i]) if (startOfLine[i])
startOfLine[j++] = startOfLine[i]; startOfLine[j++] = startOfLine[i];
} }
if (i != j) if (i != j)
{ {
startOfLine[j] = '\0'; startOfLine[j] = '\0';
m_numBytesInBuffer = j; m_numBytesInBuffer = j;
} }
} }
else if (!m_numBytesInBuffer) else if (!m_numBytesInBuffer)
{ {
aPauseForMoreData = PR_TRUE; aPauseForMoreData = PR_TRUE;
return nsnull; return nsnull;
} }
// okay, now that we've tried to read in more data from the stream, look for another end of line // okay, now that we've tried to read in more data from the stream, look for another end of line
// character // character
endOfLine = PL_strchr(startOfLine, '\n'); endOfLine = PL_strchr(startOfLine, m_lineToken);
} }
// okay, now check again for endOfLine. // okay, now check again for endOfLine.
if (endOfLine) if (endOfLine)
{ {
if (!m_eatCRLFs) if (!m_eatCRLFs)
endOfLine += 1; // count for LF endOfLine += 1; // count for LF or CR
aNumBytesInLine = endOfLine - startOfLine; aNumBytesInLine = endOfLine - startOfLine;
if (startOfLine[aNumBytesInLine-1] == '\r') if (m_eatCRLFs && aNumBytesInLine > 0 && startOfLine[aNumBytesInLine-1] == '\r') // Remove the CR in a CRLF sequence
aNumBytesInLine--; aNumBytesInLine--;
// PR_CALLOC zeros out the allocated line // PR_CALLOC zeros out the allocated line
char* newLine = (char*) PR_CALLOC(aNumBytesInLine+1); char* newLine = (char*) PR_CALLOC(aNumBytesInLine+1);
if (!newLine) if (!newLine)
{ {
aNumBytesInLine = 0; aNumBytesInLine = 0;
aPauseForMoreData = PR_TRUE; aPauseForMoreData = PR_TRUE;
return nsnull; return nsnull;
} }
memcpy(newLine, startOfLine, aNumBytesInLine); // copy the string into the new line buffer memcpy(newLine, startOfLine, aNumBytesInLine); // copy the string into the new line buffer
if (m_eatCRLFs) if (m_eatCRLFs)
endOfLine += 1; // advance past LF if we haven't already done so... endOfLine += 1; // advance past LF or CR if we haven't already done so...
// now we need to update the data buffer to go past the line we just read out. // now we need to update the data buffer to go past the line we just read out.
m_numBytesInBuffer -= (endOfLine - startOfLine); m_numBytesInBuffer -= (endOfLine - startOfLine);
if (m_numBytesInBuffer) if (m_numBytesInBuffer)
m_startPos = endOfLine - m_dataBuffer; m_startPos = endOfLine - m_dataBuffer;
else else
m_startPos = 0; m_startPos = 0;
return newLine; return newLine;
} }

View File

@ -111,7 +111,9 @@ public:
// ReadNextLine will alter the data so your ptr only has a life time of a per call. // ReadNextLine will alter the data so your ptr only has a life time of a per call.
// aEatCRLFs -- PR_TRUE if you don't want to see the CRLFs on the lines returned by ReadNextLine. // aEatCRLFs -- PR_TRUE if you don't want to see the CRLFs on the lines returned by ReadNextLine.
// PR_FALSE if you do want to see them. // PR_FALSE if you do want to see them.
nsMsgLineStreamBuffer(PRUint32 aBufferSize, PRBool aAllocateNewLines, PRBool aEatCRLFs = PR_TRUE); // specify the size of the buffer you want the class to use.... // aLineToken -- Specify the line token to look for, by default is LF ('\n') which cover as well CRLF. If
// lines are terminated with a CR only, you need to set aLineToken to CR ('\r')
nsMsgLineStreamBuffer(PRUint32 aBufferSize, PRBool aAllocateNewLines, PRBool aEatCRLFs = PR_TRUE, char aLineToken = '\n'); // specify the size of the buffer you want the class to use....
virtual ~nsMsgLineStreamBuffer(); virtual ~nsMsgLineStreamBuffer();
// Caller must free the line returned using PR_Free // Caller must free the line returned using PR_Free
@ -125,8 +127,9 @@ protected:
PRBool m_allocateNewLines; PRBool m_allocateNewLines;
char * m_dataBuffer; char * m_dataBuffer;
PRUint32 m_dataBufferSize; PRUint32 m_dataBufferSize;
PRUint32 m_startPos; PRUint32 m_startPos;
PRUint32 m_numBytesInBuffer; PRUint32 m_numBytesInBuffer;
char m_lineToken;
}; };

View File

@ -217,7 +217,11 @@ nsresult nsMailboxProtocol::Initialize(nsIURI * aURL)
} }
} }
#if defined(XP_MAC)
m_lineStreamBuffer = new nsMsgLineStreamBuffer(OUTPUT_BUFFER_SIZE, PR_TRUE, PR_TRUE, '\r');
#else
m_lineStreamBuffer = new nsMsgLineStreamBuffer(OUTPUT_BUFFER_SIZE, PR_TRUE); m_lineStreamBuffer = new nsMsgLineStreamBuffer(OUTPUT_BUFFER_SIZE, PR_TRUE);
#endif
m_nextState = MAILBOX_READ_FOLDER; m_nextState = MAILBOX_READ_FOLDER;
m_initialState = MAILBOX_READ_FOLDER; m_initialState = MAILBOX_READ_FOLDER;