]> git.saurik.com Git - wxWidgets.git/blame - src/common/protocol.cpp
Improved size handling.
[wxWidgets.git] / src / common / protocol.cpp
CommitLineData
f4ada568
GL
1/////////////////////////////////////////////////////////////////////////////
2// Name: protocol.cpp
3// Purpose: Implement protocol base class
4// Author: Guilhem Lavaux
5// Modified by:
6// Created: 07/07/1997
7// RCS-ID: $Id$
8// Copyright: (c) 1997, 1998 Guilhem Lavaux
65571936 9// Licence: wxWindows licence
f4ada568
GL
10/////////////////////////////////////////////////////////////////////////////
11
fcc6dddd
JS
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#ifdef __BORLANDC__
2df7be7f 16 #pragma hdrstop
fcc6dddd
JS
17#endif
18
a5d46b73
VZ
19#if wxUSE_PROTOCOL
20
f4ada568
GL
21#include "wx/protocol/protocol.h"
22#include "wx/url.h"
3b4183d8 23#include "wx/module.h"
f4ada568 24
f61815af
GL
25#include <stdlib.h>
26
f4ada568
GL
27/////////////////////////////////////////////////////////////////
28// wxProtoInfo
29/////////////////////////////////////////////////////////////////
30
31/*
32 * --------------------------------------------------------------
33 * --------- wxProtoInfo CONSTRUCTOR ----------------------------
34 * --------------------------------------------------------------
35 */
36
4846abaf 37wxProtoInfo::wxProtoInfo(const wxChar *name, const wxChar *serv,
f4ada568 38 const bool need_host1, wxClassInfo *info)
69268d6d
VZ
39 : m_protoname(name),
40 m_servname(serv)
f4ada568 41{
2b5f62a0
VZ
42 m_cinfo = info;
43 m_needhost = need_host1;
34e0d9f8 44#if wxUSE_URL
2b5f62a0
VZ
45 next = wxURL::ms_protocols;
46 wxURL::ms_protocols = this;
34e0d9f8
JS
47#else
48 next = NULL;
49#endif
f4ada568
GL
50}
51
52/////////////////////////////////////////////////////////////////
53// wxProtocol ///////////////////////////////////////////////////
54/////////////////////////////////////////////////////////////////
55
8a4df159 56#if wxUSE_SOCKETS
f4ada568 57IMPLEMENT_ABSTRACT_CLASS(wxProtocol, wxSocketClient)
8a4df159
RR
58#else
59IMPLEMENT_ABSTRACT_CLASS(wxProtocol, wxObject)
60#endif
f4ada568
GL
61
62wxProtocol::wxProtocol()
8a4df159 63#if wxUSE_SOCKETS
f4ada568 64 : wxSocketClient()
8a4df159 65#endif
f4ada568
GL
66{
67}
68
a9cb577a 69#if wxUSE_SOCKETS
f4ada568
GL
70bool wxProtocol::Reconnect()
71{
2b5f62a0
VZ
72 wxIPV4address addr;
73
74 if (!GetPeer(addr))
75 {
76 Close();
7e548f6b 77 return false;
2b5f62a0
VZ
78 }
79
80 if (!Close())
7e548f6b
WS
81 return false;
82
2b5f62a0 83 if (!Connect(addr))
7e548f6b 84 return false;
2b5f62a0 85
7e548f6b 86 return true;
f4ada568
GL
87}
88
8e907a13
VZ
89// ----------------------------------------------------------------------------
90// Read a line from socket
91// ----------------------------------------------------------------------------
92
db7c5931 93/* static */
6adbb0bf 94wxProtocolError wxProtocol::ReadLine(wxSocketBase *sock, wxString& result)
8e907a13 95{
db7c5931
VZ
96 static const int LINE_BUF = 4095;
97
98 result.clear();
99
100 wxCharBuffer buf(LINE_BUF);
684dface 101 char *pBuf = buf.data();
db7c5931 102 while ( sock->WaitForRead() )
8e907a13 103 {
db7c5931 104 // peek at the socket to see if there is a CRLF
684dface 105 sock->Peek(pBuf, LINE_BUF);
db7c5931
VZ
106
107 size_t nRead = sock->LastCount();
108 if ( !nRead && sock->Error() )
109 return wxPROTO_NETERR;
110
111 // look for "\r\n" paying attention to a special case: "\r\n" could
112 // have been split by buffer boundary, so check also for \r at the end
113 // of the last chunk and \n at the beginning of this one
684dface
VZ
114 pBuf[nRead] = '\0';
115 const char *eol = strchr(pBuf, '\n');
db7c5931
VZ
116
117 // if we found '\n', is there a '\r' as well?
118 if ( eol )
8e907a13 119 {
684dface 120 if ( eol == pBuf )
db7c5931
VZ
121 {
122 // check for case of "\r\n" being split
123 if ( result.empty() || result.Last() != _T('\r') )
8e907a13 124 {
db7c5931
VZ
125 // ignore the stray '\n'
126 eol = NULL;
8e907a13 127 }
db7c5931 128 //else: ok, got real EOL
8e907a13 129
db7c5931
VZ
130 // read just this '\n' and restart
131 nRead = 1;
132 }
133 else // '\n' in the middle of the buffer
134 {
135 // in any case, read everything up to and including '\n'
684dface 136 nRead = eol - pBuf + 1;
db7c5931
VZ
137
138 if ( eol[-1] != '\r' )
8e907a13 139 {
db7c5931
VZ
140 // as above, simply ignore stray '\n'
141 eol = NULL;
8e907a13 142 }
db7c5931
VZ
143 }
144 }
145
684dface 146 sock->Read(pBuf, nRead);
db7c5931
VZ
147 if ( sock->LastCount() != nRead )
148 return wxPROTO_NETERR;
149
684dface
VZ
150 pBuf[nRead] = '\0';
151 result += wxString::FromAscii(pBuf);
db7c5931
VZ
152
153 if ( eol )
154 {
155 // remove trailing "\r\n"
156 result.RemoveLast(2);
8e907a13 157
db7c5931 158 return wxPROTO_NOERR;
8e907a13
VZ
159 }
160 }
161
162 return wxPROTO_NETERR;
163}
164
165wxProtocolError wxProtocol::ReadLine(wxString& result)
166{
167 return ReadLine(this, result);
168}
169
170// old function which only chops '\n' and not '\r\n'
2b5f62a0
VZ
171wxProtocolError GetLine(wxSocketBase *sock, wxString& result)
172{
f4ada568 173#define PROTO_BSIZE 2048
2b5f62a0
VZ
174 size_t avail, size;
175 char tmp_buf[PROTO_BSIZE], tmp_str[PROTO_BSIZE];
176 char *ret;
177 bool found;
178
179 avail = sock->Read(tmp_buf, PROTO_BSIZE).LastCount();
180 if (sock->Error() || avail == 0)
181 return wxPROTO_NETERR;
182
183 memcpy(tmp_str, tmp_buf, avail);
184
185 // Not implemented on all systems
186 // ret = (char *)memccpy(tmp_str, tmp_buf, '\n', avail);
7e548f6b 187 found = false;
2b5f62a0 188 for (ret=tmp_str;ret < (tmp_str+avail); ret++)
7e548f6b 189 if (*ret == '\n')
2b5f62a0 190 {
7e548f6b 191 found = true;
2b5f62a0
VZ
192 break;
193 }
f4ada568 194
2b5f62a0
VZ
195 if (!found)
196 return wxPROTO_PROTERR;
7e548f6b 197
2b5f62a0 198 *ret = 0;
f4ada568 199
2b5f62a0
VZ
200 result = wxString::FromAscii( tmp_str );
201 result = result.Left(result.Length()-1);
f4ada568 202
2b5f62a0
VZ
203 size = ret-tmp_str+1;
204 sock->Unread(&tmp_buf[size], avail-size);
7e548f6b 205
2b5f62a0 206 return wxPROTO_NOERR;
f4ada568
GL
207#undef PROTO_BSIZE
208}
a9cb577a 209#endif // wxUSE_SOCKETS
a5d46b73
VZ
210
211#endif // wxUSE_PROTOCOL
212