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