]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/protocol.cpp
As small as possible reorganization within wxDateTime to please PCH in DLL build...
[wxWidgets.git] / src / common / protocol.cpp
... / ...
CommitLineData
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
41wxProtoInfo::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#if wxUSE_URL
49 next = wxURL::ms_protocols;
50 wxURL::ms_protocols = this;
51#else
52 next = NULL;
53#endif
54}
55
56/////////////////////////////////////////////////////////////////
57// wxProtocol ///////////////////////////////////////////////////
58/////////////////////////////////////////////////////////////////
59
60#if wxUSE_SOCKETS
61IMPLEMENT_ABSTRACT_CLASS(wxProtocol, wxSocketClient)
62#else
63IMPLEMENT_ABSTRACT_CLASS(wxProtocol, wxObject)
64#endif
65
66wxProtocol::wxProtocol()
67#if wxUSE_SOCKETS
68 : wxSocketClient()
69#endif
70{
71}
72
73#if wxUSE_SOCKETS
74bool 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// ----------------------------------------------------------------------------
94// Read a line from socket
95// ----------------------------------------------------------------------------
96
97/* static */
98wxProtocolError wxProtocol::ReadLine(wxSocketBase *sock, wxString& result)
99{
100 static const int LINE_BUF = 4095;
101
102 result.clear();
103
104 wxCharBuffer buf(LINE_BUF);
105 char *pBuf = buf.data();
106 while ( sock->WaitForRead() )
107 {
108 // peek at the socket to see if there is a CRLF
109 sock->Peek(pBuf, LINE_BUF);
110
111 size_t nRead = sock->LastCount();
112 if ( !nRead && sock->Error() )
113 return wxPROTO_NETERR;
114
115 // look for "\r\n" paying attention to a special case: "\r\n" could
116 // have been split by buffer boundary, so check also for \r at the end
117 // of the last chunk and \n at the beginning of this one
118 pBuf[nRead] = '\0';
119 const char *eol = strchr(pBuf, '\n');
120
121 // if we found '\n', is there a '\r' as well?
122 if ( eol )
123 {
124 if ( eol == pBuf )
125 {
126 // check for case of "\r\n" being split
127 if ( result.empty() || result.Last() != _T('\r') )
128 {
129 // ignore the stray '\n'
130 eol = NULL;
131 }
132 //else: ok, got real EOL
133
134 // read just this '\n' and restart
135 nRead = 1;
136 }
137 else // '\n' in the middle of the buffer
138 {
139 // in any case, read everything up to and including '\n'
140 nRead = eol - pBuf + 1;
141
142 if ( eol[-1] != '\r' )
143 {
144 // as above, simply ignore stray '\n'
145 eol = NULL;
146 }
147 }
148 }
149
150 sock->Read(pBuf, nRead);
151 if ( sock->LastCount() != nRead )
152 return wxPROTO_NETERR;
153
154 pBuf[nRead] = '\0';
155 result += wxString::FromAscii(pBuf);
156
157 if ( eol )
158 {
159 // remove trailing "\r\n"
160 result.RemoveLast(2);
161
162 return wxPROTO_NOERR;
163 }
164 }
165
166 return wxPROTO_NETERR;
167}
168
169wxProtocolError wxProtocol::ReadLine(wxString& result)
170{
171 return ReadLine(this, result);
172}
173
174// old function which only chops '\n' and not '\r\n'
175wxProtocolError GetLine(wxSocketBase *sock, wxString& result)
176{
177#define PROTO_BSIZE 2048
178 size_t avail, size;
179 char tmp_buf[PROTO_BSIZE], tmp_str[PROTO_BSIZE];
180 char *ret;
181 bool found;
182
183 avail = sock->Read(tmp_buf, PROTO_BSIZE).LastCount();
184 if (sock->Error() || avail == 0)
185 return wxPROTO_NETERR;
186
187 memcpy(tmp_str, tmp_buf, avail);
188
189 // Not implemented on all systems
190 // ret = (char *)memccpy(tmp_str, tmp_buf, '\n', avail);
191 found = false;
192 for (ret=tmp_str;ret < (tmp_str+avail); ret++)
193 if (*ret == '\n')
194 {
195 found = true;
196 break;
197 }
198
199 if (!found)
200 return wxPROTO_PROTERR;
201
202 *ret = 0;
203
204 result = wxString::FromAscii( tmp_str );
205 result = result.Left(result.Length()-1);
206
207 size = ret-tmp_str+1;
208 sock->Unread(&tmp_buf[size], avail-size);
209
210 return wxPROTO_NOERR;
211#undef PROTO_BSIZE
212}
213#endif // wxUSE_SOCKETS
214
215#endif // wxUSE_PROTOCOL
216