/////////////////////////////////////////////////////////////////////////////
-// 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_PROTOCOL
+
#include "wx/protocol/protocol.h"
+
+#ifndef WX_PRECOMP
+ #include "wx/module.h"
+#endif
+
#include "wx/url.h"
-#include "wx/module.h"
#include <stdlib.h>
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
}
/////////////////////////////////////////////////////////////////
#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;
+// ----------------------------------------------------------------------------
+// Read a line from socket
+// ----------------------------------------------------------------------------
- result = tmp_str;
- result = result.Left(result.Length()-1);
+/* 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() != _T('\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;
+ }
+ }
- size = ret-tmp_str+1;
- sock->Unread(&tmp_buf[size], avail-size);
- return wxPROTO_NOERR;
-#undef PROTO_BSIZE
+ return wxPROTO_NETERR;
}
-#endif
-// ----------------------------------------------------------------------
-// Module
-// ----------------------------------------------------------------------
+wxProtocolError wxProtocol::ReadLine(wxString& result)
+{
+ return ReadLine(this, result);
+}
-class wxProtocolModule: public wxModule {
- DECLARE_DYNAMIC_CLASS(wxProtocolModule)
-public:
- wxProtocolModule() {}
- bool OnInit();
- void OnExit();
-};
+// old function which only chops '\n' and not '\r\n'
+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 !USE_SHARED_LIBRARY
-IMPLEMENT_DYNAMIC_CLASS(wxProtocolModule, wxModule)
-#endif
+ avail = sock->Read(tmp_buf, PROTO_BSIZE).LastCount();
+ if (sock->Error() || avail == 0)
+ return wxPROTO_NETERR;
-bool wxProtocolModule::OnInit()
-{
-#if wxUSE_SOCKETS
- char *env_http_prox;
+ memcpy(tmp_str, tmp_buf, avail);
- 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;
-}
+ // 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;
+ }
-void wxProtocolModule::OnExit()
-{
-#if wxUSE_SOCKETS
- if (wxURL::g_proxy)
- delete wxURL::g_proxy;
- wxURL::g_proxy = NULL;
-#endif
+ if (!found)
+ return wxPROTO_PROTERR;
+
+ *ret = 0;
+
+ result = wxString::FromAscii( tmp_str );
+ result = result.Left(result.length()-1);
+
+ size = ret-tmp_str+1;
+ sock->Unread(&tmp_buf[size], avail-size);
+
+ return wxPROTO_NOERR;
+#undef PROTO_BSIZE
}
+#endif // wxUSE_SOCKETS
+#endif // wxUSE_PROTOCOL