X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/8e907a13eae0ef1cd0eb4a318c824ba095a64684..c932709d31bf359c994dc2050bec1b3b986bbd62:/src/common/protocol.cpp diff --git a/src/common/protocol.cpp b/src/common/protocol.cpp index 875ad85af0..955a11de66 100644 --- a/src/common/protocol.cpp +++ b/src/common/protocol.cpp @@ -6,10 +6,10 @@ // Created: 07/07/1997 // RCS-ID: $Id$ // Copyright: (c) 1997, 1998 Guilhem Lavaux -// Licence: wxWindows license +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "protocol.h" #endif @@ -20,6 +20,8 @@ #pragma hdrstop #endif +#if wxUSE_PROTOCOL + #include "wx/protocol/protocol.h" #include "wx/url.h" #include "wx/module.h" @@ -38,13 +40,13 @@ wxProtoInfo::wxProtoInfo(const wxChar *name, const wxChar *serv, const bool need_host1, wxClassInfo *info) + : m_protoname(name), + m_servname(serv) { - m_protoname = name; - m_servname = serv; - m_cinfo = info; - m_needhost = need_host1; - next = wxURL::g_protocols; - wxURL::g_protocols = this; + m_cinfo = info; + m_needhost = need_host1; + next = wxURL::ms_protocols; + wxURL::ms_protocols = this; } ///////////////////////////////////////////////////////////////// @@ -67,59 +69,93 @@ wxProtocol::wxProtocol() #if wxUSE_SOCKETS bool wxProtocol::Reconnect() { - wxIPV4address addr; - - if (!GetPeer(addr)) - { - Close(); - return FALSE; - } - if (!Close()) - return FALSE; - if (!Connect(addr)) - return FALSE; - - return TRUE; + wxIPV4address addr; + + if (!GetPeer(addr)) + { + Close(); + return false; + } + + if (!Close()) + return false; + + if (!Connect(addr)) + return false; + + return true; } // ---------------------------------------------------------------------------- // Read a line from socket // ---------------------------------------------------------------------------- -// TODO ReadLine() should use buffers private to wxProtocol for efficiency! - -// static -wxProtocolError wxProtocol::ReadLine(wxSocketBase *socket, wxString& result) +/* static */ +wxProtocolError wxProtocol::ReadLine(wxSocketBase *sock, 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); + char *pBuf = buf.data(); + while ( sock->WaitForRead() ) { - switch ( ch ) + // peek at the socket to see if there is a CRLF + sock->Peek(pBuf, 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 + pBuf[nRead] = '\0'; + const char *eol = strchr(pBuf, '\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 == pBuf ) + { + // 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 - pBuf + 1; + + if ( eol[-1] != '\r' ) { - result += chLast; - chLast = '\0'; + // as above, simply ignore stray '\n' + eol = NULL; } + } + } + + sock->Read(pBuf, nRead); + if ( sock->LastCount() != nRead ) + return wxPROTO_NETERR; + + pBuf[nRead] = '\0'; + result += wxString::FromAscii(pBuf); + + if ( eol ) + { + // remove trailing "\r\n" + result.RemoveLast(2); - result += ch; + return wxPROTO_NOERR; } } @@ -132,77 +168,45 @@ wxProtocolError wxProtocol::ReadLine(wxString& result) } // old function which only chops '\n' and not '\r\n' -wxProtocolError GetLine(wxSocketBase *sock, wxString& result) { +wxProtocolError GetLine(wxSocketBase *sock, wxString& result) +{ #define PROTO_BSIZE 2048 - size_t avail, size; - char tmp_buf[PROTO_BSIZE], tmp_str[PROTO_BSIZE]; - char *ret; - bool found; - - avail = sock->Read(tmp_buf, PROTO_BSIZE).LastCount(); - if (sock->Error() || avail == 0) - return wxPROTO_NETERR; + size_t avail, size; + char tmp_buf[PROTO_BSIZE], tmp_str[PROTO_BSIZE]; + char *ret; + bool found; + + avail = sock->Read(tmp_buf, PROTO_BSIZE).LastCount(); + if (sock->Error() || avail == 0) + return wxPROTO_NETERR; + + memcpy(tmp_str, tmp_buf, avail); + + // Not implemented on all systems + // ret = (char *)memccpy(tmp_str, tmp_buf, '\n', avail); + found = false; + for (ret=tmp_str;ret < (tmp_str+avail); ret++) + if (*ret == '\n') + { + found = true; + break; + } - memcpy(tmp_str, tmp_buf, avail); + if (!found) + return wxPROTO_PROTERR; -// Not implemented on all systems -// ret = (char *)memccpy(tmp_str, tmp_buf, '\n', avail); - found = FALSE; - for (ret=tmp_str;ret < (tmp_str+avail); ret++) - if (*ret == '\n') { - found = TRUE; - break; - } + *ret = 0; - if (!found) - return wxPROTO_PROTERR; - *ret = 0; + result = wxString::FromAscii( tmp_str ); + result = result.Left(result.Length()-1); - result = tmp_str; - result = result.Left(result.Length()-1); + size = ret-tmp_str+1; + sock->Unread(&tmp_buf[size], avail-size); - size = ret-tmp_str+1; - sock->Unread(&tmp_buf[size], avail-size); - return wxPROTO_NOERR; + return wxPROTO_NOERR; #undef PROTO_BSIZE } -#endif - -// ---------------------------------------------------------------------- -// Module -// ---------------------------------------------------------------------- - -class wxProtocolModule: public wxModule { - DECLARE_DYNAMIC_CLASS(wxProtocolModule) -public: - wxProtocolModule() {} - bool OnInit(); - void OnExit(); -}; +#endif // wxUSE_SOCKETS -IMPLEMENT_DYNAMIC_CLASS(wxProtocolModule, wxModule) - -bool wxProtocolModule::OnInit() -{ -#if wxUSE_SOCKETS - char *env_http_prox; - - wxURL::g_proxy = NULL; - // Initialize the proxy when HTTP_PROXY is defined - env_http_prox = getenv("HTTP_PROXY"); - if (env_http_prox) - wxURL::SetDefaultProxy(env_http_prox); -#endif - - return TRUE; -} - -void wxProtocolModule::OnExit() -{ -#if wxUSE_SOCKETS - if (wxURL::g_proxy) - delete wxURL::g_proxy; - wxURL::g_proxy = NULL; -#endif -} +#endif // wxUSE_PROTOCOL