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