dolphin/Externals/wxWidgets/src/common/protocol.cpp

216 lines
5.3 KiB
C++
Raw Normal View History

/////////////////////////////////////////////////////////////////////////////
// Name: src/common/protocol.cpp
// Purpose: Implement protocol base class
// Author: Guilhem Lavaux
// Modified by:
// Created: 07/07/1997
// RCS-ID: $Id: protocol.cpp 40943 2006-08-31 19:31:43Z ABX $
// Copyright: (c) 1997, 1998 Guilhem Lavaux
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#if wxUSE_PROTOCOL
#include "wx/protocol/protocol.h"
#ifndef WX_PRECOMP
#include "wx/module.h"
#endif
#include "wx/url.h"
#include <stdlib.h>
/////////////////////////////////////////////////////////////////
// wxProtoInfo
/////////////////////////////////////////////////////////////////
/*
* --------------------------------------------------------------
* --------- wxProtoInfo CONSTRUCTOR ----------------------------
* --------------------------------------------------------------
*/
wxProtoInfo::wxProtoInfo(const wxChar *name, const wxChar *serv,
const bool need_host1, wxClassInfo *info)
: m_protoname(name),
m_servname(serv)
{
m_cinfo = info;
m_needhost = need_host1;
#if wxUSE_URL
next = wxURL::ms_protocols;
wxURL::ms_protocols = this;
#else
next = NULL;
#endif
}
/////////////////////////////////////////////////////////////////
// wxProtocol ///////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
#if wxUSE_SOCKETS
IMPLEMENT_ABSTRACT_CLASS(wxProtocol, wxSocketClient)
#else
IMPLEMENT_ABSTRACT_CLASS(wxProtocol, wxObject)
#endif
wxProtocol::wxProtocol()
#if wxUSE_SOCKETS
: wxSocketClient()
#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;
}
// ----------------------------------------------------------------------------
// 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() != _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;
}
}
return wxPROTO_NETERR;
}
wxProtocolError wxProtocol::ReadLine(wxString& result)
{
return ReadLine(this, result);
}
// 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;
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;
}
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