]> git.saurik.com Git - wxWidgets.git/blob - src/common/protocol.cpp
Do wait for connection in the server socket.
[wxWidgets.git] / src / common / protocol.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/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 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 #if wxUSE_PROTOCOL
20
21 #include "wx/protocol/protocol.h"
22 #include "wx/protocol/log.h"
23
24 #ifndef WX_PRECOMP
25 #include "wx/module.h"
26 #endif
27
28 #include "wx/url.h"
29 #include "wx/log.h"
30
31 #include <stdlib.h>
32
33 // ----------------------------------------------------------------------------
34 // wxProtoInfo
35 // ----------------------------------------------------------------------------
36
37 wxProtoInfo::wxProtoInfo(const wxChar *name, const wxChar *serv,
38 const bool need_host1, wxClassInfo *info)
39 : m_protoname(name),
40 m_servname(serv)
41 {
42 m_cinfo = info;
43 m_needhost = need_host1;
44 #if wxUSE_URL
45 next = wxURL::ms_protocols;
46 wxURL::ms_protocols = this;
47 #else
48 next = NULL;
49 #endif
50 }
51
52
53 // ----------------------------------------------------------------------------
54 // wxProtocol
55 // ----------------------------------------------------------------------------
56
57 #if wxUSE_SOCKETS
58 IMPLEMENT_ABSTRACT_CLASS(wxProtocol, wxSocketClient)
59 #else
60 IMPLEMENT_ABSTRACT_CLASS(wxProtocol, wxObject)
61 #endif
62
63 wxProtocol::wxProtocol()
64 #if wxUSE_SOCKETS
65 : wxSocketClient()
66 #endif
67 {
68 m_lastError = wxPROTO_NOERR;
69 m_log = NULL;
70 SetDefaultTimeout(60); // default timeout is 60 seconds
71 }
72
73 #if wxUSE_SOCKETS
74 bool wxProtocol::Reconnect()
75 {
76 wxIPV4address addr;
77
78 if (!GetPeer(addr))
79 {
80 Close();
81 return false;
82 }
83
84 if (!Close())
85 return false;
86
87 if (!Connect(addr))
88 return false;
89
90 return true;
91 }
92
93 void wxProtocol::SetDefaultTimeout(wxUint32 Value)
94 {
95 m_uiDefaultTimeout = Value;
96 #if wxUSE_SOCKETS
97 wxSocketBase::SetTimeout(Value); // sets it for this socket
98 #endif
99 }
100
101 wxProtocol::~wxProtocol()
102 {
103 delete m_log;
104 }
105
106 // ----------------------------------------------------------------------------
107 // Read a line from socket
108 // ----------------------------------------------------------------------------
109
110 /* static */
111 wxProtocolError wxProtocol::ReadLine(wxSocketBase *sock, wxString& result)
112 {
113 static const int LINE_BUF = 4095;
114
115 result.clear();
116
117 wxCharBuffer buf(LINE_BUF);
118 char *pBuf = buf.data();
119 while ( sock->WaitForRead() )
120 {
121 // peek at the socket to see if there is a CRLF
122 sock->Peek(pBuf, LINE_BUF);
123
124 size_t nRead = sock->LastCount();
125 if ( !nRead && sock->Error() )
126 return wxPROTO_NETERR;
127
128 // look for "\r\n" paying attention to a special case: "\r\n" could
129 // have been split by buffer boundary, so check also for \r at the end
130 // of the last chunk and \n at the beginning of this one
131 pBuf[nRead] = '\0';
132 const char *eol = strchr(pBuf, '\n');
133
134 // if we found '\n', is there a '\r' as well?
135 if ( eol )
136 {
137 if ( eol == pBuf )
138 {
139 // check for case of "\r\n" being split
140 if ( result.empty() || result.Last() != wxT('\r') )
141 {
142 // ignore the stray '\n'
143 eol = NULL;
144 }
145 //else: ok, got real EOL
146
147 // read just this '\n' and restart
148 nRead = 1;
149 }
150 else // '\n' in the middle of the buffer
151 {
152 // in any case, read everything up to and including '\n'
153 nRead = eol - pBuf + 1;
154
155 if ( eol[-1] != '\r' )
156 {
157 // as above, simply ignore stray '\n'
158 eol = NULL;
159 }
160 }
161 }
162
163 sock->Read(pBuf, nRead);
164 if ( sock->LastCount() != nRead )
165 return wxPROTO_NETERR;
166
167 pBuf[nRead] = '\0';
168 result += wxString::FromAscii(pBuf);
169
170 if ( eol )
171 {
172 // remove trailing "\r\n"
173 result.RemoveLast(2);
174
175 return wxPROTO_NOERR;
176 }
177 }
178
179 return wxPROTO_NETERR;
180 }
181
182 wxProtocolError wxProtocol::ReadLine(wxString& result)
183 {
184 return ReadLine(this, result);
185 }
186
187 #endif // wxUSE_SOCKETS
188
189 // ----------------------------------------------------------------------------
190 // logging
191 // ----------------------------------------------------------------------------
192
193 void wxProtocol::SetLog(wxProtocolLog *log)
194 {
195 delete m_log;
196 m_log = log;
197 }
198
199 void wxProtocol::LogRequest(const wxString& str)
200 {
201 if ( m_log )
202 m_log->LogRequest(str);
203 }
204
205 void wxProtocol::LogResponse(const wxString& str)
206 {
207 if ( m_log )
208 m_log->LogResponse(str);
209 }
210
211 void wxProtocolLog::DoLogString(const wxString& str)
212 {
213 wxUnusedVar(str); // unused if wxLogTrace() is disabled
214 wxLogTrace(m_traceMask, "%s", str);
215 }
216
217 #endif // wxUSE_PROTOCOL