2001-09-28 20:14:13 +00:00
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
2004-04-17 18:33:16 +00:00
* Version : MPL 1.1 / GPL 2.0 / LGPL 2.1
1999-03-19 22:55:08 +00:00
*
2004-04-17 18:33:16 +00:00
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 ( the " License " ) ; you may not use this file except in compliance with
* the License . You may obtain a copy of the License at
* http : //www.mozilla.org/MPL/
1999-03-19 22:55:08 +00:00
*
2001-09-28 20:14:13 +00:00
* Software distributed under the License is distributed on an " AS IS " basis ,
* WITHOUT WARRANTY OF ANY KIND , either express or implied . See the License
* for the specific language governing rights and limitations under the
* License .
1999-03-19 22:55:08 +00:00
*
1999-11-06 03:43:54 +00:00
* The Original Code is mozilla . org code .
*
2004-04-17 18:33:16 +00:00
* The Initial Developer of the Original Code is
2001-09-28 20:14:13 +00:00
* Netscape Communications Corporation .
* Portions created by the Initial Developer are Copyright ( C ) 1999
* the Initial Developer . All Rights Reserved .
1999-11-06 03:43:54 +00:00
*
2001-09-28 20:14:13 +00:00
* Contributor ( s ) :
*
* Alternatively , the contents of this file may be used under the terms of
2004-04-17 18:33:16 +00:00
* either of the GNU General Public License Version 2 or later ( the " GPL " ) ,
* or the GNU Lesser General Public License Version 2.1 or later ( the " LGPL " ) ,
2001-09-28 20:14:13 +00:00
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above . If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL , and not to allow others to
2004-04-17 18:33:16 +00:00
* use your version of this file under the terms of the MPL , indicate your
2001-09-28 20:14:13 +00:00
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL . If you do not delete
* the provisions above , a recipient may use your version of this file under
2004-04-17 18:33:16 +00:00
* the terms of any one of the MPL , the GPL or the LGPL .
2001-09-28 20:14:13 +00:00
*
* * * * * * END LICENSE BLOCK * * * * * */
1999-03-19 22:55:08 +00:00
# include "msgCore.h"
1999-09-08 03:08:27 +00:00
# include "prlog.h"
2001-07-16 02:40:48 +00:00
# include "prmem.h"
1999-03-19 22:55:08 +00:00
# include "nsMsgLineBuffer.h"
1999-04-16 22:05:33 +00:00
# include "nsIInputStream.h" // used by nsMsgLineStreamBuffer
2001-01-27 23:31:15 +00:00
MOZ_DECL_CTOR_COUNTER ( nsByteArray )
1999-10-10 22:32:54 +00:00
1999-03-19 22:55:08 +00:00
nsByteArray : : nsByteArray ( )
{
2003-09-15 22:15:00 +00:00
MOZ_COUNT_CTOR ( nsByteArray ) ;
m_buffer = NULL ;
m_bufferSize = 0 ;
m_bufferPos = 0 ;
1999-03-19 22:55:08 +00:00
}
nsByteArray : : ~ nsByteArray ( )
{
2003-09-15 22:15:00 +00:00
MOZ_COUNT_DTOR ( nsByteArray ) ;
PR_FREEIF ( m_buffer ) ;
1999-03-19 22:55:08 +00:00
}
nsresult nsByteArray : : GrowBuffer ( PRUint32 desired_size , PRUint32 quantum )
{
2003-09-15 22:15:00 +00:00
if ( m_bufferSize < desired_size )
{
char * new_buf ;
PRUint32 increment = desired_size - m_bufferSize ;
if ( increment < quantum ) /* always grow by a minimum of N bytes */
increment = quantum ;
new_buf = ( m_buffer
? ( char * ) PR_REALLOC ( m_buffer , ( m_bufferSize + increment ) )
: ( char * ) PR_MALLOC ( m_bufferSize + increment ) ) ;
if ( ! new_buf )
return NS_ERROR_OUT_OF_MEMORY ;
m_buffer = new_buf ;
m_bufferSize + = increment ;
}
1999-03-19 22:55:08 +00:00
return 0 ;
}
nsresult nsByteArray : : AppendString ( const char * string )
{
2003-09-15 22:15:00 +00:00
PRUint32 strLength = ( string ) ? PL_strlen ( string ) : 0 ;
return AppendBuffer ( string , strLength ) ;
1999-03-19 22:55:08 +00:00
}
nsresult nsByteArray : : AppendBuffer ( const char * buffer , PRUint32 length )
{
2003-09-15 22:15:00 +00:00
nsresult ret = NS_OK ;
if ( m_bufferPos + length > m_bufferSize )
ret = GrowBuffer ( m_bufferPos + length , 1024 ) ;
if ( ret = = NS_OK )
{
memcpy ( m_buffer + m_bufferPos , buffer , length ) ;
m_bufferPos + = length ;
}
return ret ;
1999-03-19 22:55:08 +00:00
}
2001-01-27 23:31:15 +00:00
MOZ_DECL_CTOR_COUNTER ( nsMsgLineBuffer )
1999-10-10 22:32:54 +00:00
1999-03-19 22:55:08 +00:00
nsMsgLineBuffer : : nsMsgLineBuffer ( nsMsgLineBufferHandler * handler , PRBool convertNewlinesP )
{
2003-09-15 22:15:00 +00:00
MOZ_COUNT_CTOR ( nsMsgLineBuffer ) ;
m_handler = handler ;
m_convertNewlinesP = convertNewlinesP ;
m_lookingForCRLF = PR_TRUE ;
1999-03-19 22:55:08 +00:00
}
nsMsgLineBuffer : : ~ nsMsgLineBuffer ( )
{
2003-09-15 22:15:00 +00:00
MOZ_COUNT_DTOR ( nsMsgLineBuffer ) ;
1999-03-19 22:55:08 +00:00
}
1999-07-24 18:15:19 +00:00
void
nsMsgLineBuffer : : SetLookingForCRLF ( PRBool b )
{
m_lookingForCRLF = b ;
}
1999-03-19 22:55:08 +00:00
PRInt32 nsMsgLineBuffer : : BufferInput ( const char * net_buffer , PRInt32 net_buffer_size )
{
int status = 0 ;
2001-04-18 05:59:43 +00:00
if ( m_bufferPos > 0 & & m_buffer & & m_buffer [ m_bufferPos - 1 ] = = nsCRT : : CR & &
net_buffer_size > 0 & & net_buffer [ 0 ] ! = nsCRT : : LF ) {
1999-03-19 22:55:08 +00:00
/* The last buffer ended with a CR. The new buffer does not start
with a LF . This old buffer should be shipped out and discarded . */
PR_ASSERT ( m_bufferSize > m_bufferPos ) ;
if ( m_bufferSize < = m_bufferPos ) return - 1 ;
status = ConvertAndSendBuffer ( ) ;
if ( status < 0 )
2004-03-08 17:40:20 +00:00
return status ;
1999-03-19 22:55:08 +00:00
m_bufferPos = 0 ;
}
while ( net_buffer_size > 0 )
2004-03-08 17:40:20 +00:00
{
1999-03-19 22:55:08 +00:00
const char * net_buffer_end = net_buffer + net_buffer_size ;
const char * newline = 0 ;
const char * s ;
2005-02-04 15:45:56 +00:00
for ( s = net_buffer ; s < net_buffer_end ; s + + )
2004-03-08 17:40:20 +00:00
{
2005-02-04 15:45:56 +00:00
if ( m_lookingForCRLF ) {
/* Move forward in the buffer until the first newline.
Stop when we see CRLF , CR , or LF , or the end of the buffer .
* But * , if we see a lone CR at the * very end * of the buffer ,
treat this as if we had reached the end of the buffer without
seeing a line terminator . This is to catch the case of the
buffers splitting a CRLF pair , as in " FOO \r \n BAR \r " " \n BAZ \r \n " .
*/
if ( * s = = nsCRT : : CR | | * s = = nsCRT : : LF ) {
newline = s ;
if ( newline [ 0 ] = = nsCRT : : CR ) {
if ( s = = net_buffer_end - 1 ) {
/* CR at end - wait for the next character. */
newline = 0 ;
break ;
}
else if ( newline [ 1 ] = = nsCRT : : LF ) {
/* CRLF seen; swallow both. */
newline + + ;
1999-07-24 18:15:19 +00:00
}
2004-03-08 17:40:20 +00:00
}
2005-02-04 15:45:56 +00:00
newline + + ;
break ;
2004-03-08 17:40:20 +00:00
}
2005-02-04 15:45:56 +00:00
}
else {
/* if not looking for a CRLF, stop at CR or LF. (for example, when parsing the newsrc file). this fixes #9896, where we'd lose the last line of anything we'd parse that used CR as the line break. */
if ( * s = = nsCRT : : CR | | * s = = nsCRT : : LF ) {
newline = s ;
newline + + ;
break ;
1999-07-24 18:15:19 +00:00
}
}
2004-03-08 17:40:20 +00:00
}
1999-03-19 22:55:08 +00:00
/* Ensure room in the net_buffer and append some or all of the current
chunk of data to it . */
{
const char * end = ( newline ? newline : net_buffer_end ) ;
PRUint32 desired_size = ( end - net_buffer ) + m_bufferPos + 1 ;
if ( desired_size > = m_bufferSize )
{
status = GrowBuffer ( desired_size , 1024 ) ;
if ( status < 0 )
2004-07-17 19:38:56 +00:00
return status ;
1999-03-19 22:55:08 +00:00
}
memcpy ( m_buffer + m_bufferPos , net_buffer , ( end - net_buffer ) ) ;
m_bufferPos + = ( end - net_buffer ) ;
}
/* Now m_buffer contains either a complete line, or as complete
a line as we have read so far .
If we have a line , process it , and then remove it from ` m_buffer ' .
Then go around the loop again , until we drain the incoming data .
*/
if ( ! newline )
return 0 ;
status = ConvertAndSendBuffer ( ) ;
if ( status < 0 ) return status ;
net_buffer_size - = ( newline - net_buffer ) ;
net_buffer = newline ;
m_bufferPos = 0 ;
2004-07-17 19:38:56 +00:00
}
1999-03-19 22:55:08 +00:00
return 0 ;
}
PRInt32 nsMsgLineBuffer : : HandleLine ( char * line , PRUint32 line_length )
{
1999-09-08 03:08:27 +00:00
NS_ASSERTION ( PR_FALSE , " must override this method if you don't provide a handler " ) ;
1999-03-19 22:55:08 +00:00
return 0 ;
}
PRInt32 nsMsgLineBuffer : : ConvertAndSendBuffer ( )
{
/* Convert the line terminator to the native form.
*/
2004-07-17 19:38:56 +00:00
char * buf = m_buffer ;
PRInt32 length = m_bufferPos ;
1999-03-19 22:55:08 +00:00
char * newline ;
PR_ASSERT ( buf & & length > 0 ) ;
if ( ! buf | | length < = 0 )
2004-07-17 19:38:56 +00:00
return - 1 ;
1999-03-19 22:55:08 +00:00
newline = buf + length ;
2001-04-18 05:59:43 +00:00
PR_ASSERT ( newline [ - 1 ] = = nsCRT : : CR | | newline [ - 1 ] = = nsCRT : : LF ) ;
if ( newline [ - 1 ] ! = nsCRT : : CR & & newline [ - 1 ] ! = nsCRT : : LF )
2004-07-17 19:38:56 +00:00
return - 1 ;
1999-03-19 22:55:08 +00:00
2004-07-17 19:38:56 +00:00
if ( m_convertNewlinesP )
{
1999-04-27 03:06:34 +00:00
# if (MSG_LINEBREAK_LEN == 1)
2004-07-17 19:38:56 +00:00
if ( ( newline - buf ) > = 2 & &
newline [ - 2 ] = = nsCRT : : CR & &
newline [ - 1 ] = = nsCRT : : LF )
{
1999-03-19 22:55:08 +00:00
/* CRLF -> CR or LF */
1999-04-27 03:06:34 +00:00
buf [ length - 2 ] = MSG_LINEBREAK [ 0 ] ;
1999-03-19 22:55:08 +00:00
length - - ;
2004-07-17 19:38:56 +00:00
}
else if ( newline > buf + 1 & &
1999-04-27 03:06:34 +00:00
newline [ - 1 ] ! = MSG_LINEBREAK [ 0 ] )
2004-07-17 19:38:56 +00:00
{
1999-03-19 22:55:08 +00:00
/* CR -> LF or LF -> CR */
1999-04-27 03:06:34 +00:00
buf [ length - 1 ] = MSG_LINEBREAK [ 0 ] ;
2004-07-17 19:38:56 +00:00
}
1999-03-19 22:55:08 +00:00
# else
2004-07-17 19:38:56 +00:00
if ( ( ( newline - buf ) > = 2 & & newline [ - 2 ] ! = nsCRT : : CR ) | |
( ( newline - buf ) > = 1 & & newline [ - 1 ] ! = nsCRT : : LF ) )
{
1999-03-19 22:55:08 +00:00
/* LF -> CRLF or CR -> CRLF */
length + + ;
1999-04-27 03:06:34 +00:00
buf [ length - 2 ] = MSG_LINEBREAK [ 0 ] ;
buf [ length - 1 ] = MSG_LINEBREAK [ 1 ] ;
2004-07-17 19:38:56 +00:00
}
1999-03-19 22:55:08 +00:00
# endif
2004-07-17 19:38:56 +00:00
}
1999-03-19 22:55:08 +00:00
return ( m_handler ) ? m_handler - > HandleLine ( buf , length ) : HandleLine ( buf , length ) ;
}
// If there's still some data (non CRLF terminated) flush it out
PRInt32 nsMsgLineBuffer : : FlushLastLine ( )
{
char * buf = m_buffer + m_bufferPos ;
PRInt32 length = m_bufferPos - 1 ;
if ( length > 0 )
return ( m_handler ) ? m_handler - > HandleLine ( buf , length ) : HandleLine ( buf , length ) ;
else
return 0 ;
}
1999-04-16 22:05:33 +00:00
///////////////////////////////////////////////////////////////////////////////////////////////////
// This is a utility class used to efficiently extract lines from an input stream by buffering
// read but unprocessed stream data in a buffer.
///////////////////////////////////////////////////////////////////////////////////////////////////
2002-05-03 21:36:33 +00:00
nsMsgLineStreamBuffer : : nsMsgLineStreamBuffer ( PRUint32 aBufferSize , PRBool aAllocateNewLines , PRBool aEatCRLFs , char aLineToken )
: m_eatCRLFs ( aEatCRLFs ) , m_allocateNewLines ( aAllocateNewLines ) , m_lineToken ( aLineToken )
1999-04-16 22:05:33 +00:00
{
NS_PRECONDITION ( aBufferSize > 0 , " invalid buffer size!!! " ) ;
m_dataBuffer = nsnull ;
1999-12-20 14:58:05 +00:00
m_startPos = 0 ;
m_numBytesInBuffer = 0 ;
1999-04-16 22:05:33 +00:00
// used to buffer incoming data by ReadNextLineFromInput
if ( aBufferSize > 0 )
{
m_dataBuffer = ( char * ) PR_CALLOC ( sizeof ( char ) * aBufferSize ) ;
}
m_dataBufferSize = aBufferSize ;
}
nsMsgLineStreamBuffer : : ~ nsMsgLineStreamBuffer ( )
{
2003-09-13 14:59:47 +00:00
PR_FREEIF ( m_dataBuffer ) ; // release our buffer...
1999-04-16 22:05:33 +00:00
}
2000-04-13 05:53:56 +00:00
nsresult nsMsgLineStreamBuffer : : GrowBuffer ( PRInt32 desiredSize )
{
m_dataBuffer = ( char * ) PR_REALLOC ( m_dataBuffer , desiredSize ) ;
if ( ! m_dataBuffer )
return NS_ERROR_OUT_OF_MEMORY ;
m_dataBufferSize = desiredSize ;
return NS_OK ;
}
2004-07-17 19:38:56 +00:00
void nsMsgLineStreamBuffer : : ClearBuffer ( )
{
m_startPos = 0 ;
m_numBytesInBuffer = 0 ;
}
1999-04-16 22:05:33 +00:00
// aInputStream - the input stream we want to read a line from
// aPauseForMoreData is returned as PR_TRUE if the stream does not yet contain a line and we must wait for more
// data to come into the stream.
// Note to people wishing to modify this function: Be *VERY CAREFUL* this is a critical function used by all of
// our mail protocols including imap, nntp, and pop. If you screw it up, you could break a lot of stuff.....
2005-02-04 15:45:56 +00:00
char * nsMsgLineStreamBuffer : : ReadNextLine ( nsIInputStream * aInputStream , PRUint32 & aNumBytesInLine , PRBool & aPauseForMoreData , nsresult * prv , PRBool addLineTerminator )
1999-04-16 22:05:33 +00:00
{
2003-09-13 14:59:47 +00:00
// try to extract a line from m_inputBuffer. If we don't have an entire line,
// then read more bytes out from the stream. If the stream is empty then wait
// on the monitor for more data to come in.
NS_PRECONDITION ( m_dataBuffer & & m_dataBufferSize > 0 , " invalid input arguments for read next line from input " ) ;
2003-09-14 22:56:51 +00:00
if ( prv )
* prv = NS_OK ;
2003-09-13 14:59:47 +00:00
// initialize out values
aPauseForMoreData = PR_FALSE ;
aNumBytesInLine = 0 ;
char * endOfLine = nsnull ;
char * startOfLine = m_dataBuffer + m_startPos ;
if ( m_numBytesInBuffer > 0 ) // any data in our internal buffer?
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
// so aInputStream will be nsnull...
if ( ! endOfLine & & aInputStream ) // get some more data from the server
{
2003-09-15 22:15:00 +00:00
nsresult rv ;
2003-09-13 14:59:47 +00:00
PRUint32 numBytesInStream = 0 ;
PRUint32 numBytesCopied = 0 ;
2003-09-15 22:15:00 +00:00
PRBool nonBlockingStream ;
aInputStream - > IsNonBlocking ( & nonBlockingStream ) ;
rv = aInputStream - > Available ( & numBytesInStream ) ;
2003-09-13 14:59:47 +00:00
if ( NS_FAILED ( rv ) )
{
if ( prv )
* prv = rv ;
return nsnull ;
}
2003-09-15 22:15:00 +00:00
if ( ! nonBlockingStream & & numBytesInStream = = 0 ) // if no data available,
numBytesInStream = m_dataBufferSize / 2 ; // ask for half the data buffer size.
2003-09-13 14:59:47 +00:00
// if the number of bytes we want to read from the stream, is greater than the number
// of bytes left in our buffer, then we need to shift the start pos and its contents
// down to the beginning of m_dataBuffer...
PRUint32 numFreeBytesInBuffer = m_dataBufferSize - m_startPos - m_numBytesInBuffer ;
if ( numBytesInStream > = numFreeBytesInBuffer )
{
2004-07-17 19:38:56 +00:00
if ( m_startPos )
2000-04-13 05:53:56 +00:00
{
2003-09-13 14:59:47 +00:00
memmove ( m_dataBuffer , startOfLine , m_numBytesInBuffer ) ;
2004-07-17 19:38:56 +00:00
// make sure the end of the buffer is terminated
m_dataBuffer [ m_numBytesInBuffer ] = ' \0 ' ;
2003-09-13 14:59:47 +00:00
m_startPos = 0 ;
startOfLine = m_dataBuffer ;
numFreeBytesInBuffer = m_dataBufferSize - m_numBytesInBuffer ;
2004-07-17 19:38:56 +00:00
//printf("moving data in read line around because buffer filling up\n");
2000-04-13 05:53:56 +00:00
}
2004-07-17 19:38:56 +00:00
else
2000-04-13 05:53:56 +00:00
{
2003-10-30 01:32:59 +00:00
PRInt32 growBy = ( numBytesInStream - numFreeBytesInBuffer ) * 2 + 1 ;
2000-04-13 05:53:56 +00:00
// try growing buffer by twice as much as we need.
nsresult rv = GrowBuffer ( m_dataBufferSize + growBy ) ;
// if we can't grow the buffer, we have to bail.
2001-11-19 06:45:00 +00:00
if ( NS_FAILED ( rv ) )
2000-04-13 05:53:56 +00:00
return nsnull ;
startOfLine = m_dataBuffer ;
numFreeBytesInBuffer + = growBy ;
}
NS_ASSERTION ( m_startPos = = 0 , " m_startPos should be 0 ..... \n " ) ;
2003-09-13 14:59:47 +00:00
}
PRUint32 numBytesToCopy = PR_MIN ( numFreeBytesInBuffer - 1 /* leave one for a null terminator */ , numBytesInStream ) ;
if ( numBytesToCopy > 0 )
{
2004-07-17 19:38:56 +00:00
// read the data into the end of our data buffer
2003-09-13 14:59:47 +00:00
rv = aInputStream - > Read ( startOfLine + m_numBytesInBuffer , numBytesToCopy ,
& numBytesCopied ) ;
if ( prv )
* prv = rv ;
2003-06-29 01:06:29 +00:00
PRUint32 i ;
2003-10-30 01:32:59 +00:00
PRUint32 endBufPos = m_numBytesInBuffer + numBytesCopied ;
2004-07-17 19:38:56 +00:00
for ( i = m_numBytesInBuffer ; i < endBufPos ; i + + ) // replace nulls with spaces
2002-05-03 21:36:33 +00:00
{
2003-09-13 14:59:47 +00:00
if ( ! startOfLine [ i ] )
startOfLine [ i ] = ' ' ;
2002-05-03 21:36:33 +00:00
}
2003-06-29 01:06:29 +00:00
m_numBytesInBuffer + = numBytesCopied ;
2003-10-30 01:32:59 +00:00
m_dataBuffer [ m_startPos + m_numBytesInBuffer ] = ' \0 ' ;
2004-07-17 19:38:56 +00:00
// okay, now that we've tried to read in more data from the stream,
// look for another end of line character
endOfLine = PL_strchr ( startOfLine , m_lineToken ) ;
2003-09-13 14:59:47 +00:00
}
}
// okay, now check again for endOfLine.
if ( endOfLine )
{
if ( ! m_eatCRLFs )
endOfLine + = 1 ; // count for LF or CR
2002-05-03 21:36:33 +00:00
aNumBytesInLine = endOfLine - startOfLine ;
2003-09-13 14:59:47 +00:00
2002-05-03 21:36:33 +00:00
if ( m_eatCRLFs & & aNumBytesInLine > 0 & & startOfLine [ aNumBytesInLine - 1 ] = = ' \r ' ) // Remove the CR in a CRLF sequence
aNumBytesInLine - - ;
2003-09-13 14:59:47 +00:00
// PR_CALLOC zeros out the allocated line
2005-02-04 15:45:56 +00:00
char * newLine = ( char * ) PR_CALLOC ( aNumBytesInLine + ( addLineTerminator ? MSG_LINEBREAK_LEN : 0 ) + 1 ) ;
2003-09-13 14:59:47 +00:00
if ( ! newLine )
2002-05-03 21:36:33 +00:00
{
aNumBytesInLine = 0 ;
aPauseForMoreData = PR_TRUE ;
2003-09-13 14:59:47 +00:00
return nsnull ;
2002-05-03 21:36:33 +00:00
}
2003-09-13 14:59:47 +00:00
memcpy ( newLine , startOfLine , aNumBytesInLine ) ; // copy the string into the new line buffer
2005-02-04 15:45:56 +00:00
if ( addLineTerminator )
{
memcpy ( newLine + aNumBytesInLine , MSG_LINEBREAK , MSG_LINEBREAK_LEN ) ;
aNumBytesInLine + = MSG_LINEBREAK_LEN ;
}
2003-09-13 14:59:47 +00:00
if ( m_eatCRLFs )
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.
2002-05-03 21:36:33 +00:00
m_numBytesInBuffer - = ( endOfLine - startOfLine ) ;
if ( m_numBytesInBuffer )
2003-09-13 14:59:47 +00:00
m_startPos = endOfLine - m_dataBuffer ;
2002-05-03 21:36:33 +00:00
else
2003-09-13 14:59:47 +00:00
m_startPos = 0 ;
return newLine ;
}
aPauseForMoreData = PR_TRUE ;
return nsnull ; // if we somehow got here. we don't have another line in the buffer yet...need to wait for more data...
1999-04-16 22:05:33 +00:00
}
2004-03-05 15:31:13 +00:00
PRBool nsMsgLineStreamBuffer : : NextLineAvailable ( )
{
return ( m_numBytesInBuffer > 0 & & PL_strchr ( m_dataBuffer + m_startPos , m_lineToken ) ) ;
}