]> git.saurik.com Git - wxWidgets.git/blob - src/common/protocol.cpp
Added slightly better font dialog for Mac
[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 // 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/url.h"
23 #include "wx/module.h"
24
25 #include <stdlib.h>
26
27 /////////////////////////////////////////////////////////////////
28 // wxProtoInfo
29 /////////////////////////////////////////////////////////////////
30
31 /*
32  * --------------------------------------------------------------
33  * --------- wxProtoInfo CONSTRUCTOR ----------------------------
34  * --------------------------------------------------------------
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 // 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     char *pBuf = buf.data();
102     while ( sock->WaitForRead() )
103     {
104         // peek at the socket to see if there is a CRLF
105         sock->Peek(pBuf, LINE_BUF);
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
114         pBuf[nRead] = '\0';
115         const char *eol = strchr(pBuf, '\n');
116
117         // if we found '\n', is there a '\r' as well?
118         if ( eol )
119         {
120             if ( eol == pBuf )
121             {
122                 // check for case of "\r\n" being split
123                 if ( result.empty() || result.Last() != _T('\r') )
124                 {
125                     // ignore the stray '\n'
126                     eol = NULL;
127                 }
128                 //else: ok, got real EOL
129
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'
136                 nRead = eol - pBuf + 1;
137
138                 if ( eol[-1] != '\r' )
139                 {
140                     // as above, simply ignore stray '\n'
141                     eol = NULL;
142                 }
143             }
144         }
145
146         sock->Read(pBuf, nRead);
147         if ( sock->LastCount() != nRead )
148             return wxPROTO_NETERR;
149
150         pBuf[nRead] = '\0';
151         result += wxString::FromAscii(pBuf);
152
153         if ( eol )
154         {
155             // remove trailing "\r\n"
156             result.RemoveLast(2);
157
158             return wxPROTO_NOERR;
159         }
160     }
161
162     return wxPROTO_NETERR;
163 }
164
165 wxProtocolError wxProtocol::ReadLine(wxString& result)
166 {
167     return ReadLine(this, result);
168 }
169
170 // old function which only chops '\n' and not '\r\n'
171 wxProtocolError GetLine(wxSocketBase *sock, wxString& result)
172 {
173 #define PROTO_BSIZE 2048
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);
187     found = false;
188     for (ret=tmp_str;ret < (tmp_str+avail); ret++)
189         if (*ret == '\n')
190         {
191             found = true;
192             break;
193         }
194
195     if (!found)
196         return wxPROTO_PROTERR;
197
198     *ret = 0;
199
200     result = wxString::FromAscii( tmp_str );
201     result = result.Left(result.Length()-1);
202
203     size = ret-tmp_str+1;
204     sock->Unread(&tmp_buf[size], avail-size);
205
206     return wxPROTO_NOERR;
207 #undef PROTO_BSIZE
208 }
209 #endif // wxUSE_SOCKETS
210
211 #endif // wxUSE_PROTOCOL
212