use 4K buffer instead of reading characters one by one in ReadLine()
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@29202 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
1a838ff58b
commit
db7c5931ed
@ -90,40 +90,71 @@ bool wxProtocol::Reconnect()
|
||||
// Read a line from socket
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// TODO ReadLine() should use buffers private to wxProtocol for efficiency!
|
||||
|
||||
// static
|
||||
/* static */
|
||||
wxProtocolError wxProtocol::ReadLine(wxSocketBase *socket, wxString& result)
|
||||
{
|
||||
result.Empty();
|
||||
char ch, chLast = '\0';
|
||||
while ( !socket->Read(&ch, sizeof(ch)).Error() )
|
||||
static const int LINE_BUF = 4095;
|
||||
|
||||
result.clear();
|
||||
|
||||
wxCharBuffer buf(LINE_BUF);
|
||||
while ( sock->WaitForRead() )
|
||||
{
|
||||
switch ( ch )
|
||||
// peek at the socket to see if there is a CRLF
|
||||
sock->Peek(buf.data(), LINE_BUF);
|
||||
|
||||
size_t nRead = sock->LastCount();
|
||||
if ( !nRead && sock->Error() )
|
||||
return wxPROTO_NETERR;
|
||||
|
||||
// look for "\r\n" paying attention to a special case: "\r\n" could
|
||||
// have been split by buffer boundary, so check also for \r at the end
|
||||
// of the last chunk and \n at the beginning of this one
|
||||
buf.data()[nRead] = '\0';
|
||||
const char *eol = strchr(buf, '\n');
|
||||
|
||||
// if we found '\n', is there a '\r' as well?
|
||||
if ( eol )
|
||||
{
|
||||
case '\r':
|
||||
// remember it, if the following is '\n', we're done
|
||||
chLast = '\r';
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
// only ends line if the previous character was '\r'
|
||||
if ( chLast == '\r' )
|
||||
if ( eol == buf.data() )
|
||||
{
|
||||
// check for case of "\r\n" being split
|
||||
if ( result.empty() || result.Last() != _T('\r') )
|
||||
{
|
||||
// EOL found
|
||||
return wxPROTO_NOERR;
|
||||
// ignore the stray '\n'
|
||||
eol = NULL;
|
||||
}
|
||||
//else: fall through
|
||||
//else: ok, got real EOL
|
||||
|
||||
default:
|
||||
// normal char
|
||||
if ( chLast )
|
||||
// read just this '\n' and restart
|
||||
nRead = 1;
|
||||
}
|
||||
else // '\n' in the middle of the buffer
|
||||
{
|
||||
// in any case, read everything up to and including '\n'
|
||||
nRead = eol - buf + 1;
|
||||
|
||||
if ( eol[-1] != '\r' )
|
||||
{
|
||||
result += wxString::FromAscii( chLast );
|
||||
chLast = '\0';
|
||||
// as above, simply ignore stray '\n'
|
||||
eol = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result += wxString::FromAscii( ch );
|
||||
sock->Read(buf.data(), nRead);
|
||||
if ( sock->LastCount() != nRead )
|
||||
return wxPROTO_NETERR;
|
||||
|
||||
buf.data()[nRead] = '\0';
|
||||
result += wxString::FromAscii(buf);
|
||||
|
||||
if ( eol )
|
||||
{
|
||||
// remove trailing "\r\n"
|
||||
result.RemoveLast(2);
|
||||
|
||||
return wxPROTO_NOERR;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user