X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2df7be7f2cca699a02ee0c9ce69de9bfe6b0922f..62354609e69487e1066e1b1129c254c886cfa0fb:/src/common/protocol.cpp diff --git a/src/common/protocol.cpp b/src/common/protocol.cpp index 736b38fd13..0173b097b7 100644 --- a/src/common/protocol.cpp +++ b/src/common/protocol.cpp @@ -1,140 +1,219 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: protocol.cpp +// Name: src/common/protocol.cpp // Purpose: Implement protocol base class // Author: Guilhem Lavaux // Modified by: // Created: 07/07/1997 // RCS-ID: $Id$ // Copyright: (c) 1997, 1998 Guilhem Lavaux -// Licence: wxWindows license +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ -#pragma implementation "protocol.h" -#endif - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ - #pragma hdrstop + #pragma hdrstop #endif -#if wxUSE_SOCKETS +#if wxUSE_PROTOCOL #include "wx/protocol/protocol.h" +#include "wx/protocol/log.h" + +#ifndef WX_PRECOMP + #include "wx/module.h" +#endif + #include "wx/url.h" -#include "wx/module.h" +#include "wx/log.h" + +#include -///////////////////////////////////////////////////////////////// +// ---------------------------------------------------------------------------- // wxProtoInfo -///////////////////////////////////////////////////////////////// +// ---------------------------------------------------------------------------- -/* - * -------------------------------------------------------------- - * --------- wxProtoInfo CONSTRUCTOR ---------------------------- - * -------------------------------------------------------------- - */ +IMPLEMENT_CLASS(wxProtoInfo, wxObject) 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; +#if wxUSE_URL + next = wxURL::ms_protocols; + wxURL::ms_protocols = this; +#else + next = NULL; +#endif } -///////////////////////////////////////////////////////////////// -// wxProtocol /////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////// +// ---------------------------------------------------------------------------- +// wxProtocol +// ---------------------------------------------------------------------------- + +#if wxUSE_SOCKETS IMPLEMENT_ABSTRACT_CLASS(wxProtocol, wxSocketClient) +#else +IMPLEMENT_ABSTRACT_CLASS(wxProtocol, wxObject) +#endif wxProtocol::wxProtocol() +#if wxUSE_SOCKETS : wxSocketClient() +#endif { + m_lastError = wxPROTO_NOERR; + m_log = NULL; + SetDefaultTimeout(60); // default timeout is 60 seconds } +#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; -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; + if (!GetPeer(addr)) + { + Close(); + return false; + } - avail = sock->Read(tmp_buf, PROTO_BSIZE).LastCount(); - if (sock->LastError() != 0 || avail == 0) - return wxPROTO_NETERR; + if (!Close()) + return false; - memcpy(tmp_str, tmp_buf, avail); + if (!Connect(addr)) + return false; -// 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; - } + return true; +} - if (!found) - return wxPROTO_PROTERR; - *ret = 0; +void wxProtocol::SetDefaultTimeout(wxUint32 Value) +{ + m_uiDefaultTimeout = Value; +#if wxUSE_SOCKETS + wxSocketBase::SetTimeout(Value); // sets it for this socket +#endif +} + +wxProtocol::~wxProtocol() +{ + delete m_log; +} - result = tmp_str; - result = result.Left(result.Length()-1); +// ---------------------------------------------------------------------------- +// Read a line from socket +// ---------------------------------------------------------------------------- + +/* static */ +wxProtocolError wxProtocol::ReadLine(wxSocketBase *sock, wxString& result) +{ + static const int LINE_BUF = 4095; + + result.clear(); + + wxCharBuffer buf(LINE_BUF); + char *pBuf = buf.data(); + while ( sock->WaitForRead() ) + { + // 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 ) + { + if ( eol == pBuf ) + { + // check for case of "\r\n" being split + if ( result.empty() || result.Last() != wxT('\r') ) + { + // ignore the stray '\n' + eol = NULL; + } + //else: ok, got real EOL + + // 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' ) + { + // 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); + + return wxPROTO_NOERR; + } + } + + return wxPROTO_NETERR; +} - size = ret-tmp_str+1; - sock->CreatePushbackBefore(&tmp_buf[size], avail-size); - return wxPROTO_NOERR; -#undef PROTO_BSIZE +wxProtocolError wxProtocol::ReadLine(wxString& result) +{ + return ReadLine(this, result); } -// ---------------------------------------------------------------------- -// Module -// ---------------------------------------------------------------------- +#endif // wxUSE_SOCKETS -class wxProtocolModule: public wxModule { - DECLARE_DYNAMIC_CLASS(wxProtocolModule) -public: - wxProtocolModule() {} - bool OnInit(); - void OnExit(); -}; +// ---------------------------------------------------------------------------- +// logging +// ---------------------------------------------------------------------------- -#if !USE_SHARED_LIBRARY -IMPLEMENT_DYNAMIC_CLASS(wxProtocolModule, wxModule) -#endif +void wxProtocol::SetLog(wxProtocolLog *log) +{ + delete m_log; + m_log = log; +} -bool wxProtocolModule::OnInit() +void wxProtocol::LogRequest(const wxString& str) { - wxURL::g_proxy = new wxHTTP(); - return TRUE; + if ( m_log ) + m_log->LogRequest(str); } -void wxProtocolModule::OnExit() +void wxProtocol::LogResponse(const wxString& str) { - delete wxURL::g_proxy; - wxURL::g_proxy = NULL; + if ( m_log ) + m_log->LogResponse(str); } -#endif - // wxUSE_SOCKETS +void wxProtocolLog::DoLogString(const wxString& str) +{ + wxUnusedVar(str); // unused if wxLogTrace() is disabled + wxLogTrace(m_traceMask, "%s", str); +} + +#endif // wxUSE_PROTOCOL