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:
Vadim Zeitlin
2004-09-18 14:21:56 +00:00
parent 1a838ff58b
commit db7c5931ed

View File

@@ -90,40 +90,71 @@ bool wxProtocol::Reconnect()
// Read a line from socket // Read a line from socket
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// TODO ReadLine() should use buffers private to wxProtocol for efficiency! /* static */
// static
wxProtocolError wxProtocol::ReadLine(wxSocketBase *socket, wxString& result) wxProtocolError wxProtocol::ReadLine(wxSocketBase *socket, wxString& result)
{ {
result.Empty(); static const int LINE_BUF = 4095;
char ch, chLast = '\0';
while ( !socket->Read(&ch, sizeof(ch)).Error() ) 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': if ( eol == buf.data() )
// remember it, if the following is '\n', we're done {
chLast = '\r'; // check for case of "\r\n" being split
break; if ( result.empty() || result.Last() != _T('\r') )
case '\n':
// only ends line if the previous character was '\r'
if ( chLast == '\r' )
{ {
// EOL found // ignore the stray '\n'
return wxPROTO_NOERR; eol = NULL;
} }
//else: fall through //else: ok, got real EOL
default: // read just this '\n' and restart
// normal char nRead = 1;
if ( chLast ) }
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 ); // as above, simply ignore stray '\n'
chLast = '\0'; 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;
} }
} }