]> git.saurik.com Git - wxWidgets.git/blame - src/common/socket.cpp
Added a check for a '.' in the column name before prepending a table name to the...
[wxWidgets.git] / src / common / socket.cpp
CommitLineData
56d8adc0 1/////////////////////////////////////////////////////////////////////////////
f4ada568
GL
2// Name: socket.cpp
3// Purpose: Socket handler classes
56d8adc0 4// Authors: Guilhem Lavaux, Guillermo Rodriguez Garcia
f4ada568 5// Created: April 1997
d3ea6527
GRG
6// Copyright: (C) 1999-1997, Guilhem Lavaux
7// (C) 2000-1999, Guillermo Rodriguez Garcia
f4ada568 8// RCS_ID: $Id$
55d99c7a 9// License: see wxWindows licence
56d8adc0
GRG
10/////////////////////////////////////////////////////////////////////////////
11
bffc1eaa
GRG
12// ==========================================================================
13// Declarations
14// ==========================================================================
15
384b4373 16#ifdef __GNUG__
f4ada568 17#pragma implementation "socket.h"
f4ada568
GL
18#endif
19
fcc6dddd
JS
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24#pragma hdrstop
25#endif
26
35a4dab7
GL
27#if wxUSE_SOCKETS
28
dc5c1114 29#include "wx/app.h"
e2478fde 30#include "wx/apptrait.h"
56d8adc0
GRG
31#include "wx/defs.h"
32#include "wx/object.h"
33#include "wx/string.h"
34#include "wx/timer.h"
35#include "wx/utils.h"
36#include "wx/module.h"
37#include "wx/log.h"
58c837a4 38#include "wx/intl.h"
f187448d 39#include "wx/event.h"
52a07708 40
56d8adc0
GRG
41#include "wx/sckaddr.h"
42#include "wx/socket.h"
3b4183d8 43
34fdf762
VS
44// DLL options compatibility check:
45#include "wx/build.h"
46WX_CHECK_BUILD_OPTIONS("wxNet")
47
bffc1eaa
GRG
48// --------------------------------------------------------------------------
49// macros and constants
50// --------------------------------------------------------------------------
ef57d866 51
dc5c1114
GRG
52// discard buffer
53#define MAX_DISCARD_SIZE (10 * 1024)
96db102a 54
e2478fde
VZ
55// what to do within waits: we have 2 cases: from the main thread itself we
56// have to call wxYield() to let the events (including the GUI events and the
57// low-level (not wxWindows) events from GSocket) be processed. From another
58// thread it is enough to just call wxThread::Yield() which will give away the
59// rest of our time slice: the explanation is that the events will be processed
60// by the main thread anyhow, without calling wxYield(), but we don't want to
61// eat the CPU time uselessly while sitting in the loop waiting for the data
62#if wxUSE_THREADS
63 #define PROCESS_EVENTS() \
64 { \
65 if ( wxThread::IsMain() ) \
66 wxYield(); \
67 else \
68 wxThread::Yield(); \
69 }
70#else // !wxUSE_THREADS
71 #define PROCESS_EVENTS() wxYield()
72#endif // wxUSE_THREADS/!wxUSE_THREADS
96db102a 73
007c77ab
RL
74#define wxTRACE_Socket _T("wxSocket")
75
ef57d866 76// --------------------------------------------------------------------------
bffc1eaa 77// wxWin macros
ef57d866 78// --------------------------------------------------------------------------
81b92e17 79
a737331d
GL
80IMPLEMENT_CLASS(wxSocketBase, wxObject)
81IMPLEMENT_CLASS(wxSocketServer, wxSocketBase)
82IMPLEMENT_CLASS(wxSocketClient, wxSocketBase)
dc5c1114 83IMPLEMENT_CLASS(wxDatagramSocket, wxSocketBase)
a737331d 84IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent)
f4ada568 85
bffc1eaa
GRG
86// --------------------------------------------------------------------------
87// private classes
88// --------------------------------------------------------------------------
89
56d8adc0
GRG
90class wxSocketState : public wxObject
91{
a324a7bc 92public:
71622a7a 93 wxSocketFlags m_flags;
bffc1eaa
GRG
94 wxSocketEventFlags m_eventmask;
95 bool m_notify;
96 void *m_clientData;
97#if WXWIN_COMPATIBILITY
81b92e17
GRG
98 wxSocketBase::wxSockCbk m_cbk;
99 char *m_cdata;
bffc1eaa 100#endif // WXWIN_COMPATIBILITY
a324a7bc
GL
101
102public:
103 wxSocketState() : wxObject() {}
22f3361e
VZ
104
105 DECLARE_NO_COPY_CLASS(wxSocketState)
a324a7bc
GL
106};
107
ef57d866
GRG
108// ==========================================================================
109// wxSocketBase
110// ==========================================================================
111
6c0d0845
VZ
112// --------------------------------------------------------------------------
113// Initialization and shutdown
114// --------------------------------------------------------------------------
115
116// FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses
117// to m_countInit with a crit section
118size_t wxSocketBase::m_countInit = 0;
119
120bool wxSocketBase::IsInitialized()
121{
122 return m_countInit > 0;
123}
124
125bool wxSocketBase::Initialize()
126{
127 if ( !m_countInit++ )
128 {
129 if ( !GSocket_Init() )
130 {
131 m_countInit--;
132
133 return FALSE;
134 }
135 }
136
137 return TRUE;
138}
139
140void wxSocketBase::Shutdown()
141{
142 // we should be initialized
143 wxASSERT_MSG( m_countInit, _T("extra call to Shutdown()") );
144 if ( !--m_countInit )
145 {
146 GSocket_Cleanup();
147 }
148}
149
ef57d866
GRG
150// --------------------------------------------------------------------------
151// Ctor and dtor
152// --------------------------------------------------------------------------
56d8adc0 153
71622a7a 154void wxSocketBase::Init()
f4ada568 155{
71622a7a
GRG
156 m_socket = NULL;
157 m_type = wxSOCKET_UNINIT;
158
159 // state
160 m_flags = 0;
161 m_connected =
162 m_establishing =
163 m_reading =
164 m_writing =
165 m_error = FALSE;
166 m_lcount = 0;
167 m_timeout = 600;
168 m_beingDeleted = FALSE;
169
170 // pushback buffer
171 m_unread = NULL;
172 m_unrd_size = 0;
173 m_unrd_cur = 0;
174
175 // events
71622a7a 176 m_id = -1;
f187448d
GRG
177 m_handler = NULL;
178 m_clientData = NULL;
bffc1eaa
GRG
179 m_notify = FALSE;
180 m_eventmask = 0;
181#if WXWIN_COMPATIBILITY
71622a7a
GRG
182 m_cbk = NULL;
183 m_cdata = NULL;
bffc1eaa 184#endif // WXWIN_COMPATIBILITY
6c0d0845
VZ
185
186 if ( !IsInitialized() )
187 {
188 // this Initialize() will be undone by wxSocketModule::OnExit(), all the
189 // other calls to it should be matched by a call to Shutdown()
190 Initialize();
191 }
f4ada568
GL
192}
193
f187448d
GRG
194wxSocketBase::wxSocketBase()
195{
196 Init();
197}
71622a7a
GRG
198
199wxSocketBase::wxSocketBase(wxSocketFlags flags, wxSocketType type)
f4ada568 200{
71622a7a
GRG
201 Init();
202
203 m_flags = flags;
204 m_type = type;
f4ada568
GL
205}
206
f4ada568
GL
207wxSocketBase::~wxSocketBase()
208{
9181a383
GRG
209 // Just in case the app called Destroy() *and* then deleted
210 // the socket immediately: don't leave dangling pointers.
e2478fde
VZ
211 wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL;
212 if ( traits )
213 traits->RemoveFromPendingDelete(this);
a737331d 214
56d8adc0 215 // Shutdown and close the socket
9181a383
GRG
216 if (!m_beingDeleted)
217 Close();
f4ada568 218
56d8adc0 219 // Destroy the GSocket object
a324a7bc
GL
220 if (m_socket)
221 GSocket_destroy(m_socket);
9181a383
GRG
222
223 // Free the pushback buffer
224 if (m_unread)
225 free(m_unread);
f4ada568
GL
226}
227
ef57d866
GRG
228bool wxSocketBase::Destroy()
229{
230 // Delayed destruction: the socket will be deleted during the next
231 // idle loop iteration. This ensures that all pending events have
232 // been processed.
ef57d866 233 m_beingDeleted = TRUE;
9181a383
GRG
234
235 // Shutdown and close the socket
ef57d866
GRG
236 Close();
237
bffc1eaa
GRG
238 // Supress events from now on
239 Notify(FALSE);
240
e2478fde
VZ
241 // schedule this object for deletion
242 wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL;
243 if ( traits )
244 {
245 // let the traits object decide what to do with us
246 traits->ScheduleForDestroy(this);
247 }
248 else // no app or no traits
249 {
250 // in wxBase we might have no app object at all, don't leak memory
251 delete this;
252 }
ef57d866
GRG
253
254 return TRUE;
255}
9181a383 256
ef57d866 257// --------------------------------------------------------------------------
bffc1eaa 258// Basic IO calls
ef57d866
GRG
259// --------------------------------------------------------------------------
260
261// The following IO operations update m_error and m_lcount:
262// {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
263//
264// TODO: Should Connect, Accept and AcceptWith update m_error?
265
f4ada568
GL
266bool wxSocketBase::Close()
267{
81b92e17 268 // Interrupt pending waits
02d15cad 269 InterruptWait();
81b92e17 270
31528cd3 271 if (m_socket)
8c14576d 272 {
56d8adc0
GRG
273 // Disable callbacks
274 GSocket_UnsetCallback(m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
275 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG);
f4ada568 276
56d8adc0 277 // Shutdown the connection
a324a7bc 278 GSocket_Shutdown(m_socket);
f4ada568
GL
279 }
280
ef57d866 281 m_connected = FALSE;
04e1eb03 282 m_establishing = FALSE;
f4ada568
GL
283 return TRUE;
284}
285
f187448d 286wxSocketBase& wxSocketBase::Read(void* buffer, wxUint32 nbytes)
f4ada568 287{
96db102a
GRG
288 // Mask read events
289 m_reading = TRUE;
a324a7bc 290
96db102a 291 m_lcount = _Read(buffer, nbytes);
17aa2bec 292
d3ea6527
GRG
293 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
294 if (m_flags & wxSOCKET_WAITALL)
96db102a
GRG
295 m_error = (m_lcount != nbytes);
296 else
297 m_error = (m_lcount == 0);
f4ada568 298
dc5c1114 299 // Allow read events from now on
96db102a 300 m_reading = FALSE;
17aa2bec 301
96db102a
GRG
302 return *this;
303}
304
f187448d 305wxUint32 wxSocketBase::_Read(void* buffer, wxUint32 nbytes)
96db102a
GRG
306{
307 int total;
308 int ret = 1;
a324a7bc 309
04e1eb03 310 // Try the pushback buffer first
96db102a
GRG
311 total = GetPushback(buffer, nbytes, FALSE);
312 nbytes -= total;
f187448d 313 buffer = (char *)buffer + total;
96db102a 314
5f3629ba
GRG
315 // Return now in one of the following cases:
316 // - the socket is invalid,
317 // - we got all the data,
318 // - we got *some* data and we are not using wxSOCKET_WAITALL.
319 if ( !m_socket ||
320 !nbytes ||
321 ((total != 0) && !(m_flags & wxSOCKET_WAITALL)) )
96db102a 322 return total;
f4ada568 323
af2fd961 324 // Possible combinations (they are checked in this order)
81b92e17 325 // wxSOCKET_NOWAIT
5c9eff30 326 // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
81b92e17
GRG
327 // wxSOCKET_BLOCK
328 // wxSOCKET_NONE
af2fd961 329 //
81b92e17 330 if (m_flags & wxSOCKET_NOWAIT)
af2fd961 331 {
5c9eff30 332 GSocket_SetNonBlocking(m_socket, 1);
f187448d 333 ret = GSocket_Read(m_socket, (char *)buffer, nbytes);
5c9eff30 334 GSocket_SetNonBlocking(m_socket, 0);
af2fd961
GRG
335
336 if (ret > 0)
96db102a 337 total += ret;
af2fd961 338 }
5c9eff30 339 else
56d8adc0 340 {
5c9eff30
GRG
341 bool more = TRUE;
342
343 while (more)
56d8adc0 344 {
5c9eff30
GRG
345 if ( !(m_flags & wxSOCKET_BLOCK) && !WaitForRead() )
346 break;
81b92e17 347
f187448d 348 ret = GSocket_Read(m_socket, (char *)buffer, nbytes);
a324a7bc 349
81b92e17
GRG
350 if (ret > 0)
351 {
352 total += ret;
81b92e17 353 nbytes -= ret;
f187448d 354 buffer = (char *)buffer + ret;
81b92e17 355 }
a324a7bc 356
5c9eff30
GRG
357 // If we got here and wxSOCKET_WAITALL is not set, we can leave
358 // now. Otherwise, wait until we recv all the data or until there
359 // is an error.
360 //
361 more = (ret > 0 && nbytes > 0 && (m_flags & wxSOCKET_WAITALL));
81b92e17 362 }
a324a7bc 363 }
f4ada568 364
96db102a 365 return total;
f4ada568
GL
366}
367
f187448d 368wxSocketBase& wxSocketBase::ReadMsg(void* buffer, wxUint32 nbytes)
062c4861 369{
96db102a
GRG
370 wxUint32 len, len2, sig, total;
371 bool error;
17aa2bec 372 int old_flags;
17aa2bec
GRG
373 struct
374 {
96db102a
GRG
375 unsigned char sig[4];
376 unsigned char len[4];
062c4861
GL
377 } msg;
378
96db102a
GRG
379 // Mask read events
380 m_reading = TRUE;
062c4861 381
96db102a
GRG
382 total = 0;
383 error = TRUE;
17aa2bec 384 old_flags = m_flags;
81b92e17 385 SetFlags((m_flags & wxSOCKET_BLOCK) | wxSOCKET_WAITALL);
17aa2bec 386
f187448d 387 if (_Read(&msg, sizeof(msg)) != sizeof(msg))
96db102a 388 goto exit;
062c4861 389
f187448d 390 sig = (wxUint32)msg.sig[0];
96db102a
GRG
391 sig |= (wxUint32)(msg.sig[1] << 8);
392 sig |= (wxUint32)(msg.sig[2] << 16);
393 sig |= (wxUint32)(msg.sig[3] << 24);
062c4861
GL
394
395 if (sig != 0xfeeddead)
17aa2bec 396 {
5c9eff30 397 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
96db102a 398 goto exit;
17aa2bec
GRG
399 }
400
96db102a
GRG
401 len = (wxUint32)msg.len[0];
402 len |= (wxUint32)(msg.len[1] << 8);
403 len |= (wxUint32)(msg.len[2] << 16);
404 len |= (wxUint32)(msg.len[3] << 24);
405
17aa2bec
GRG
406 if (len > nbytes)
407 {
062c4861
GL
408 len2 = len - nbytes;
409 len = nbytes;
410 }
411 else
412 len2 = 0;
413
04e1eb03 414 // Don't attemp to read if the msg was zero bytes long.
96db102a 415 if (len)
17aa2bec 416 {
96db102a
GRG
417 total = _Read(buffer, len);
418
419 if (total != len)
420 goto exit;
17aa2bec
GRG
421 }
422 if (len2)
423 {
96db102a 424 char *discard_buffer = new char[MAX_DISCARD_SIZE];
17aa2bec
GRG
425 long discard_len;
426
96db102a 427 // NOTE: discarded bytes don't add to m_lcount.
17aa2bec
GRG
428 do
429 {
96db102a 430 discard_len = ((len2 > MAX_DISCARD_SIZE)? MAX_DISCARD_SIZE : len2);
479cd5de
VZ
431 discard_len = _Read(discard_buffer, (wxUint32)discard_len);
432 len2 -= (wxUint32)discard_len;
17aa2bec
GRG
433 }
434 while ((discard_len > 0) && len2);
435
436 delete [] discard_buffer;
437
438 if (len2 != 0)
96db102a 439 goto exit;
17aa2bec 440 }
f187448d 441 if (_Read(&msg, sizeof(msg)) != sizeof(msg))
96db102a 442 goto exit;
062c4861 443
96db102a
GRG
444 sig = (wxUint32)msg.sig[0];
445 sig |= (wxUint32)(msg.sig[1] << 8);
446 sig |= (wxUint32)(msg.sig[2] << 16);
447 sig |= (wxUint32)(msg.sig[3] << 24);
a324a7bc 448
062c4861 449 if (sig != 0xdeadfeed)
17aa2bec 450 {
5c9eff30 451 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
96db102a 452 goto exit;
17aa2bec 453 }
062c4861 454
96db102a
GRG
455 // everything was OK
456 error = FALSE;
457
458exit:
459 m_error = error;
460 m_lcount = total;
461 m_reading = FALSE;
17aa2bec 462 SetFlags(old_flags);
96db102a 463
062c4861
GL
464 return *this;
465}
466
f187448d 467wxSocketBase& wxSocketBase::Peek(void* buffer, wxUint32 nbytes)
f4ada568 468{
96db102a
GRG
469 // Mask read events
470 m_reading = TRUE;
471
472 m_lcount = _Read(buffer, nbytes);
dc5c1114 473 Pushback(buffer, m_lcount);
96db102a 474
81b92e17
GRG
475 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
476 if (m_flags & wxSOCKET_WAITALL)
96db102a
GRG
477 m_error = (m_lcount != nbytes);
478 else
479 m_error = (m_lcount == 0);
480
dc5c1114 481 // Allow read events again
96db102a 482 m_reading = FALSE;
f4ada568
GL
483
484 return *this;
485}
486
f187448d 487wxSocketBase& wxSocketBase::Write(const void *buffer, wxUint32 nbytes)
f4ada568 488{
96db102a
GRG
489 // Mask write events
490 m_writing = TRUE;
56d8adc0 491
96db102a
GRG
492 m_lcount = _Write(buffer, nbytes);
493
81b92e17
GRG
494 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
495 if (m_flags & wxSOCKET_WAITALL)
96db102a
GRG
496 m_error = (m_lcount != nbytes);
497 else
498 m_error = (m_lcount == 0);
499
dc5c1114 500 // Allow write events again
96db102a
GRG
501 m_writing = FALSE;
502
96db102a
GRG
503 return *this;
504}
505
f187448d 506wxUint32 wxSocketBase::_Write(const void *buffer, wxUint32 nbytes)
96db102a
GRG
507{
508 wxUint32 total = 0;
509 int ret = 1;
56d8adc0 510
5c9eff30
GRG
511 // If the socket is invalid or parameters are ill, return immediately
512 if (!m_socket || !buffer || !nbytes)
96db102a 513 return 0;
a324a7bc 514
af2fd961 515 // Possible combinations (they are checked in this order)
81b92e17 516 // wxSOCKET_NOWAIT
5c9eff30 517 // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
81b92e17
GRG
518 // wxSOCKET_BLOCK
519 // wxSOCKET_NONE
af2fd961 520 //
81b92e17 521 if (m_flags & wxSOCKET_NOWAIT)
af2fd961 522 {
5c9eff30 523 GSocket_SetNonBlocking(m_socket, 1);
f187448d 524 ret = GSocket_Write(m_socket, (const char *)buffer, nbytes);
5c9eff30 525 GSocket_SetNonBlocking(m_socket, 0);
af2fd961
GRG
526
527 if (ret > 0)
96db102a 528 total = ret;
af2fd961 529 }
5c9eff30 530 else
56d8adc0 531 {
5c9eff30
GRG
532 bool more = TRUE;
533
c3e646b4 534 while (more)
56d8adc0 535 {
5c9eff30
GRG
536 if ( !(m_flags & wxSOCKET_BLOCK) && !WaitForWrite() )
537 break;
81b92e17 538
f187448d 539 ret = GSocket_Write(m_socket, (const char *)buffer, nbytes);
5c9eff30 540
81b92e17
GRG
541 if (ret > 0)
542 {
543 total += ret;
81b92e17 544 nbytes -= ret;
f187448d 545 buffer = (const char *)buffer + ret;
81b92e17 546 }
a324a7bc 547
5c9eff30
GRG
548 // If we got here and wxSOCKET_WAITALL is not set, we can leave
549 // now. Otherwise, wait until we send all the data or until there
550 // is an error.
551 //
552 more = (ret > 0 && nbytes > 0 && (m_flags & wxSOCKET_WAITALL));
81b92e17 553 }
56d8adc0 554 }
a324a7bc 555
96db102a 556 return total;
f4ada568
GL
557}
558
f187448d 559wxSocketBase& wxSocketBase::WriteMsg(const void *buffer, wxUint32 nbytes)
062c4861 560{
96db102a
GRG
561 wxUint32 total;
562 bool error;
17aa2bec 563 int old_flags;
f187448d
GRG
564 struct
565 {
96db102a
GRG
566 unsigned char sig[4];
567 unsigned char len[4];
062c4861
GL
568 } msg;
569
96db102a
GRG
570 // Mask write events
571 m_writing = TRUE;
572
573 error = TRUE;
574 total = 0;
575 old_flags = m_flags;
81b92e17 576 SetFlags((m_flags & wxSOCKET_BLOCK) | wxSOCKET_WAITALL);
96db102a 577
96db102a
GRG
578 msg.sig[0] = (unsigned char) 0xad;
579 msg.sig[1] = (unsigned char) 0xde;
580 msg.sig[2] = (unsigned char) 0xed;
581 msg.sig[3] = (unsigned char) 0xfe;
062c4861 582
04e1eb03
GRG
583 msg.len[0] = (unsigned char) (nbytes & 0xff);
584 msg.len[1] = (unsigned char) ((nbytes >> 8) & 0xff);
585 msg.len[2] = (unsigned char) ((nbytes >> 16) & 0xff);
586 msg.len[3] = (unsigned char) ((nbytes >> 24) & 0xff);
17aa2bec 587
f187448d 588 if (_Write(&msg, sizeof(msg)) < sizeof(msg))
96db102a
GRG
589 goto exit;
590
591 total = _Write(buffer, nbytes);
592
593 if (total < nbytes)
594 goto exit;
062c4861 595
96db102a
GRG
596 msg.sig[0] = (unsigned char) 0xed;
597 msg.sig[1] = (unsigned char) 0xfe;
598 msg.sig[2] = (unsigned char) 0xad;
599 msg.sig[3] = (unsigned char) 0xde;
062c4861 600 msg.len[0] = msg.len[1] = msg.len[2] = msg.len[3] = (char) 0;
062c4861 601
f187448d 602 if ((_Write(&msg, sizeof(msg))) < sizeof(msg))
96db102a 603 goto exit;
17aa2bec 604
96db102a
GRG
605 // everything was OK
606 error = FALSE;
607
608exit:
609 m_error = error;
610 m_lcount = total;
611 m_writing = FALSE;
612
062c4861 613 return *this;
062c4861
GL
614}
615
f187448d 616wxSocketBase& wxSocketBase::Unread(const void *buffer, wxUint32 nbytes)
f4ada568 617{
56d8adc0 618 if (nbytes != 0)
96db102a 619 Pushback(buffer, nbytes);
f4ada568 620
96db102a
GRG
621 m_error = FALSE;
622 m_lcount = nbytes;
f4ada568 623
96db102a 624 return *this;
a324a7bc
GL
625}
626
96db102a 627wxSocketBase& wxSocketBase::Discard()
f4ada568 628{
96db102a 629 int old_flags;
04e1eb03
GRG
630 char *buffer = new char[MAX_DISCARD_SIZE];
631 wxUint32 ret;
17aa2bec 632 wxUint32 total = 0;
f4ada568 633
96db102a
GRG
634 // Mask read events
635 m_reading = TRUE;
636
637 old_flags = m_flags;
81b92e17 638 SetFlags(wxSOCKET_NOWAIT);
384b4373 639
04e1eb03 640 do
8c14576d 641 {
04e1eb03
GRG
642 ret = _Read(buffer, MAX_DISCARD_SIZE);
643 total += ret;
f4ada568 644 }
04e1eb03 645 while (ret == MAX_DISCARD_SIZE);
f4ada568 646
04e1eb03 647 delete[] buffer;
17aa2bec 648 m_lcount = total;
04e1eb03 649 m_error = FALSE;
17aa2bec 650
dc5c1114 651 // Allow read events again
96db102a
GRG
652 m_reading = FALSE;
653
96db102a 654 return *this;
f4ada568
GL
655}
656
ef57d866
GRG
657// --------------------------------------------------------------------------
658// Wait functions
659// --------------------------------------------------------------------------
f4ada568 660
ef57d866
GRG
661// All Wait functions poll the socket using GSocket_Select() to
662// check for the specified combination of conditions, until one
663// of these conditions become true, an error occurs, or the
664// timeout elapses. The polling loop calls PROCESS_EVENTS(), so
665// this won't block the GUI.
f4ada568 666
bffc1eaa
GRG
667bool wxSocketBase::_Wait(long seconds,
668 long milliseconds,
d3ea6527 669 wxSocketEventFlags flags)
375abe3d 670{
56d8adc0 671 GSocketEventFlags result;
56d8adc0 672 long timeout;
375abe3d 673
81b92e17
GRG
674 // Set this to TRUE to interrupt ongoing waits
675 m_interrupt = FALSE;
676
ef57d866 677 // Check for valid socket
af2fd961
GRG
678 if (!m_socket)
679 return FALSE;
680
71622a7a 681 // Check for valid timeout value.
56d8adc0
GRG
682 if (seconds != -1)
683 timeout = seconds * 1000 + milliseconds;
684 else
685 timeout = m_timeout * 1000;
a324a7bc 686
bffc1eaa 687 // Wait in an active polling loop.
af2fd961 688 //
bffc1eaa
GRG
689 // NOTE: We duplicate some of the code in OnRequest, but this doesn't
690 // hurt. It has to be here because the (GSocket) event might arrive
691 // a bit delayed, and it has to be in OnRequest as well because we
692 // don't know whether the Wait functions are being used.
af2fd961 693 //
96db102a 694 // Do this at least once (important if timeout == 0, when
d3ea6527 695 // we are just polling). Also, if just polling, do not yield.
ef57d866 696
71622a7a
GRG
697 wxStopWatch chrono;
698 bool done = FALSE;
699
700 while (!done)
56d8adc0 701 {
af2fd961
GRG
702 result = GSocket_Select(m_socket, flags | GSOCK_LOST_FLAG);
703
af2fd961
GRG
704 // Incoming connection (server) or connection established (client)
705 if (result & GSOCK_CONNECTION_FLAG)
706 {
af2fd961
GRG
707 m_connected = TRUE;
708 m_establishing = FALSE;
709 return TRUE;
710 }
711
04e1eb03 712 // Data available or output buffer ready
81b92e17 713 if ((result & GSOCK_INPUT_FLAG) || (result & GSOCK_OUTPUT_FLAG))
af2fd961 714 {
81b92e17 715 return TRUE;
af2fd961
GRG
716 }
717
c0043a50
GRG
718 // Connection lost
719 if (result & GSOCK_LOST_FLAG)
720 {
ef57d866 721 m_connected = FALSE;
04e1eb03 722 m_establishing = FALSE;
378d2bd3 723 return (flags & GSOCK_LOST_FLAG) != 0;
c0043a50
GRG
724 }
725
81b92e17 726 // Wait more?
71622a7a
GRG
727 if ((!timeout) || (chrono.Time() > timeout) || (m_interrupt))
728 done = TRUE;
d3ea6527
GRG
729 else
730 PROCESS_EVENTS();
56d8adc0 731 }
f4ada568 732
af2fd961 733 return FALSE;
f4ada568 734}
f4ada568 735
a737331d 736bool wxSocketBase::Wait(long seconds, long milliseconds)
f4ada568 737{
d80d1aba
GRG
738 return _Wait(seconds, milliseconds, GSOCK_INPUT_FLAG |
739 GSOCK_OUTPUT_FLAG |
740 GSOCK_CONNECTION_FLAG |
741 GSOCK_LOST_FLAG);
f4ada568 742}
f4ada568 743
a737331d 744bool wxSocketBase::WaitForRead(long seconds, long milliseconds)
f4ada568 745{
ef57d866 746 // Check pushback buffer before entering _Wait
96db102a
GRG
747 if (m_unread)
748 return TRUE;
749
ef57d866
GRG
750 // Note that GSOCK_INPUT_LOST has to be explicitly passed to
751 // _Wait becuase of the semantics of WaitForRead: a return
752 // value of TRUE means that a GSocket_Read call will return
753 // immediately, not that there is actually data to read.
754
755 return _Wait(seconds, milliseconds, GSOCK_INPUT_FLAG |
756 GSOCK_LOST_FLAG);
f4ada568
GL
757}
758
a737331d 759bool wxSocketBase::WaitForWrite(long seconds, long milliseconds)
f4ada568 760{
af2fd961 761 return _Wait(seconds, milliseconds, GSOCK_OUTPUT_FLAG);
a737331d 762}
f4ada568 763
a737331d
GL
764bool wxSocketBase::WaitForLost(long seconds, long milliseconds)
765{
a324a7bc 766 return _Wait(seconds, milliseconds, GSOCK_LOST_FLAG);
f4ada568 767}
a737331d 768
ef57d866
GRG
769// --------------------------------------------------------------------------
770// Miscellaneous
771// --------------------------------------------------------------------------
772
773//
774// Get local or peer address
775//
776
777bool wxSocketBase::GetPeer(wxSockAddress& addr_man) const
778{
779 GAddress *peer;
780
781 if (!m_socket)
782 return FALSE;
783
784 peer = GSocket_GetPeer(m_socket);
007c77ab
RL
785
786 // copying a null address would just trigger an assert anyway
787
788 if (!peer)
789 return FALSE;
790
ef57d866
GRG
791 addr_man.SetAddress(peer);
792 GAddress_destroy(peer);
793
794 return TRUE;
795}
796
797bool wxSocketBase::GetLocal(wxSockAddress& addr_man) const
798{
799 GAddress *local;
800
801 if (!m_socket)
802 return FALSE;
803
804 local = GSocket_GetLocal(m_socket);
805 addr_man.SetAddress(local);
806 GAddress_destroy(local);
807
808 return TRUE;
809}
810
811//
812// Save and restore socket state
813//
814
815void wxSocketBase::SaveState()
816{
817 wxSocketState *state;
818
819 state = new wxSocketState();
820
bffc1eaa
GRG
821 state->m_flags = m_flags;
822 state->m_notify = m_notify;
823 state->m_eventmask = m_eventmask;
824 state->m_clientData = m_clientData;
825#if WXWIN_COMPATIBILITY
826 state->m_cbk = m_cbk;
827 state->m_cdata = m_cdata;
828#endif // WXWIN_COMPATIBILITY
ef57d866
GRG
829
830 m_states.Append(state);
831}
832
833void wxSocketBase::RestoreState()
834{
df5168c4 835 wxList::compatibility_iterator node;
ef57d866
GRG
836 wxSocketState *state;
837
b1d4dd7a 838 node = m_states.GetLast();
ef57d866
GRG
839 if (!node)
840 return;
841
b1d4dd7a 842 state = (wxSocketState *)node->GetData();
ef57d866 843
bffc1eaa
GRG
844 m_flags = state->m_flags;
845 m_notify = state->m_notify;
846 m_eventmask = state->m_eventmask;
847 m_clientData = state->m_clientData;
848#if WXWIN_COMPATIBILITY
849 m_cbk = state->m_cbk;
850 m_cdata = state->m_cdata;
851#endif // WXWIN_COMPATIBILITY
ef57d866 852
df5168c4 853 m_states.Erase(node);
ef57d866
GRG
854 delete state;
855}
856
857//
858// Timeout and flags
859//
860
17aa2bec
GRG
861void wxSocketBase::SetTimeout(long seconds)
862{
863 m_timeout = seconds;
864
865 if (m_socket)
e8f4c584 866 GSocket_SetTimeout(m_socket, m_timeout * 1000);
17aa2bec
GRG
867}
868
71622a7a 869void wxSocketBase::SetFlags(wxSocketFlags flags)
f4ada568 870{
71622a7a 871 m_flags = flags;
f4ada568 872}
f0a56ab0 873
f187448d 874
ef57d866
GRG
875// --------------------------------------------------------------------------
876// Callbacks (now obsolete - use events instead)
877// --------------------------------------------------------------------------
56d8adc0 878
bffc1eaa
GRG
879#if WXWIN_COMPATIBILITY
880
56d8adc0 881wxSocketBase::wxSockCbk wxSocketBase::Callback(wxSockCbk cbk_)
f4ada568 882{
56d8adc0 883 wxSockCbk old_cbk = cbk_;
f4ada568 884
56d8adc0
GRG
885 m_cbk = cbk_;
886 return old_cbk;
887}
888
889char *wxSocketBase::CallbackData(char *data)
890{
891 char *old_data = m_cdata;
892
893 m_cdata = data;
894 return old_data;
f4ada568
GL
895}
896
bffc1eaa
GRG
897#endif // WXWIN_COMPATIBILITY
898
ef57d866 899// --------------------------------------------------------------------------
f187448d 900// Event handling
ef57d866 901// --------------------------------------------------------------------------
a324a7bc 902
bffc1eaa
GRG
903// A note on how events are processed, which is probably the most
904// difficult thing to get working right while keeping the same API
905// and functionality for all platforms.
906//
907// When GSocket detects an event, it calls wx_socket_callback, which in
908// turn just calls wxSocketBase::OnRequest in the corresponding wxSocket
909// object. OnRequest does some housekeeping, and if the event is to be
910// propagated to the user, it creates a new wxSocketEvent object and
911// posts it. The event is not processed immediately, but delayed with
912// AddPendingEvent instead. This is necessary in order to decouple the
913// event processing from wx_socket_callback; otherwise, subsequent IO
914// calls made from the user event handler would fail, as gtk callbacks
915// are not reentrant.
916//
917// Note that, unlike events, user callbacks (now deprecated) are _not_
918// decoupled from wx_socket_callback and thus they suffer from a variety
919// of problems. Avoid them where possible and use events instead.
96db102a 920
90350682
VZ
921extern "C"
922void LINKAGEMODE wx_socket_callback(GSocket * WXUNUSED(socket),
923 GSocketEvent notification,
924 char *cdata)
a324a7bc
GL
925{
926 wxSocketBase *sckobj = (wxSocketBase *)cdata;
927
bffc1eaa 928 sckobj->OnRequest((wxSocketNotify) notification);
56d8adc0 929}
a324a7bc 930
bffc1eaa 931void wxSocketBase::OnRequest(wxSocketNotify notification)
f4ada568 932{
bffc1eaa
GRG
933 // NOTE: We duplicate some of the code in _Wait, but this doesn't
934 // hurt. It has to be here because the (GSocket) event might arrive
935 // a bit delayed, and it has to be in _Wait as well because we don't
936 // know whether the Wait functions are being used.
ef57d866 937
bffc1eaa 938 switch(notification)
d80d1aba 939 {
04e1eb03
GRG
940 case wxSOCKET_CONNECTION:
941 m_establishing = FALSE;
942 m_connected = TRUE;
943 break;
944
d3ea6527
GRG
945 // If we are in the middle of a R/W operation, do not
946 // propagate events to users. Also, filter 'late' events
947 // which are no longer valid.
ef57d866 948
04e1eb03
GRG
949 case wxSOCKET_INPUT:
950 if (m_reading || !GSocket_Select(m_socket, GSOCK_INPUT_FLAG))
951 return;
952 break;
953
954 case wxSOCKET_OUTPUT:
955 if (m_writing || !GSocket_Select(m_socket, GSOCK_OUTPUT_FLAG))
956 return;
957 break;
958
959 case wxSOCKET_LOST:
960 m_connected = FALSE;
961 m_establishing = FALSE;
962 break;
963
964 default:
965 break;
96db102a
GRG
966 }
967
f187448d
GRG
968 // Schedule the event
969
52fbdb58 970 wxSocketEventFlags flag = 0;
bffc1eaa 971 switch (notification)
f187448d
GRG
972 {
973 case GSOCK_INPUT: flag = GSOCK_INPUT_FLAG; break;
974 case GSOCK_OUTPUT: flag = GSOCK_OUTPUT_FLAG; break;
975 case GSOCK_CONNECTION: flag = GSOCK_CONNECTION_FLAG; break;
976 case GSOCK_LOST: flag = GSOCK_LOST_FLAG; break;
52fbdb58 977 default:
5c9eff30 978 wxLogWarning(_("wxSocket: unknown event!."));
52fbdb58 979 return;
f187448d
GRG
980 }
981
bffc1eaa 982 if (((m_eventmask & flag) == flag) && m_notify)
d80d1aba 983 {
f187448d 984 if (m_handler)
bffc1eaa
GRG
985 {
986 wxSocketEvent event(m_id);
987 event.m_event = notification;
988 event.m_clientData = m_clientData;
989 event.SetEventObject(this);
990
f187448d 991 m_handler->AddPendingEvent(event);
bffc1eaa 992 }
56d8adc0 993
bffc1eaa 994#if WXWIN_COMPATIBILITY
56d8adc0 995 if (m_cbk)
bffc1eaa
GRG
996 m_cbk(*this, notification, m_cdata);
997#endif // WXWIN_COMPATIBILITY
f4ada568 998 }
f4ada568
GL
999}
1000
f187448d
GRG
1001void wxSocketBase::Notify(bool notify)
1002{
bffc1eaa 1003 m_notify = notify;
f187448d
GRG
1004}
1005
1006void wxSocketBase::SetNotify(wxSocketEventFlags flags)
1007{
bffc1eaa 1008 m_eventmask = flags;
f187448d
GRG
1009}
1010
71622a7a 1011void wxSocketBase::SetEventHandler(wxEvtHandler& handler, int id)
f4ada568 1012{
71622a7a
GRG
1013 m_handler = &handler;
1014 m_id = id;
f4ada568
GL
1015}
1016
ef57d866
GRG
1017// --------------------------------------------------------------------------
1018// Pushback buffer
1019// --------------------------------------------------------------------------
db131261 1020
f187448d 1021void wxSocketBase::Pushback(const void *buffer, wxUint32 size)
f4ada568 1022{
dc5c1114
GRG
1023 if (!size) return;
1024
a324a7bc 1025 if (m_unread == NULL)
f187448d 1026 m_unread = malloc(size);
dc5c1114
GRG
1027 else
1028 {
f187448d 1029 void *tmp;
f4ada568 1030
f187448d
GRG
1031 tmp = malloc(m_unrd_size + size);
1032 memcpy((char *)tmp + size, m_unread, m_unrd_size);
41895a05 1033 free(m_unread);
a324a7bc
GL
1034
1035 m_unread = tmp;
41895a05 1036 }
31528cd3 1037
f4ada568 1038 m_unrd_size += size;
a324a7bc
GL
1039
1040 memcpy(m_unread, buffer, size);
f4ada568
GL
1041}
1042
f187448d 1043wxUint32 wxSocketBase::GetPushback(void *buffer, wxUint32 size, bool peek)
f4ada568
GL
1044{
1045 if (!m_unrd_size)
1046 return 0;
1047
a324a7bc
GL
1048 if (size > (m_unrd_size-m_unrd_cur))
1049 size = m_unrd_size-m_unrd_cur;
96db102a 1050
f187448d 1051 memcpy(buffer, (char *)m_unread + m_unrd_cur, size);
f4ada568 1052
dc5c1114
GRG
1053 if (!peek)
1054 {
a324a7bc 1055 m_unrd_cur += size;
dc5c1114
GRG
1056 if (m_unrd_size == m_unrd_cur)
1057 {
f4ada568
GL
1058 free(m_unread);
1059 m_unread = NULL;
a324a7bc
GL
1060 m_unrd_size = 0;
1061 m_unrd_cur = 0;
f4ada568
GL
1062 }
1063 }
1064
1065 return size;
1066}
1067
f187448d 1068
ef57d866 1069// ==========================================================================
c3e646b4 1070// wxSocketServer
ef57d866 1071// ==========================================================================
f4ada568 1072
ef57d866
GRG
1073// --------------------------------------------------------------------------
1074// Ctor
1075// --------------------------------------------------------------------------
56d8adc0 1076
f4ada568 1077wxSocketServer::wxSocketServer(wxSockAddress& addr_man,
71622a7a
GRG
1078 wxSocketFlags flags)
1079 : wxSocketBase(flags, wxSOCKET_SERVER)
f4ada568 1080{
007c77ab 1081 wxLogTrace( wxTRACE_Socket, _T("Opening wxSocketServer") );
f4ada568 1082
007c77ab 1083 m_socket = GSocket_new();
384b4373 1084
007c77ab
RL
1085 if (!m_socket)
1086 {
1087 wxLogTrace( wxTRACE_Socket, _T("*** GSocket_new failed") );
1088 return;
1089 }
a737331d 1090
007c77ab 1091 // Setup the socket as server
56d8adc0 1092
007c77ab
RL
1093 GSocket_SetLocal(m_socket, addr_man.GetAddress());
1094 if (GSocket_SetServer(m_socket) != GSOCK_NOERROR)
1095 {
1096 GSocket_destroy(m_socket);
1097 m_socket = NULL;
1098
1099 wxLogTrace( wxTRACE_Socket, _T("*** GSocket_SetServer failed") );
1100 return;
1101 }
1102
1103 GSocket_SetTimeout(m_socket, m_timeout * 1000);
1104 GSocket_SetCallback(m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1105 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1106 wx_socket_callback, (char *)this);
f4ada568
GL
1107}
1108
ef57d866
GRG
1109// --------------------------------------------------------------------------
1110// Accept
1111// --------------------------------------------------------------------------
8c14576d 1112
d80d1aba 1113bool wxSocketServer::AcceptWith(wxSocketBase& sock, bool wait)
f4ada568 1114{
a324a7bc 1115 GSocket *child_socket;
f4ada568 1116
17aa2bec
GRG
1117 if (!m_socket)
1118 return FALSE;
1119
04e1eb03 1120 // If wait == FALSE, then the call should be nonblocking.
56d8adc0
GRG
1121 // When we are finished, we put the socket to blocking mode
1122 // again.
d80d1aba
GRG
1123
1124 if (!wait)
5c9eff30 1125 GSocket_SetNonBlocking(m_socket, 1);
d80d1aba 1126
a324a7bc 1127 child_socket = GSocket_WaitConnection(m_socket);
384b4373 1128
d80d1aba 1129 if (!wait)
5c9eff30 1130 GSocket_SetNonBlocking(m_socket, 0);
d80d1aba 1131
04e1eb03 1132 if (!child_socket)
d80d1aba
GRG
1133 return FALSE;
1134
71622a7a 1135 sock.m_type = wxSOCKET_BASE;
a324a7bc 1136 sock.m_socket = child_socket;
f4ada568
GL
1137 sock.m_connected = TRUE;
1138
e8f4c584 1139 GSocket_SetTimeout(sock.m_socket, sock.m_timeout * 1000);
56d8adc0
GRG
1140 GSocket_SetCallback(sock.m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1141 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1142 wx_socket_callback, (char *)&sock);
1143
f4ada568
GL
1144 return TRUE;
1145}
1146
d80d1aba 1147wxSocketBase *wxSocketServer::Accept(bool wait)
f4ada568
GL
1148{
1149 wxSocketBase* sock = new wxSocketBase();
1150
71622a7a 1151 sock->SetFlags(m_flags);
f4ada568 1152
d80d1aba 1153 if (!AcceptWith(*sock, wait))
c3e646b4
VZ
1154 {
1155 sock->Destroy();
1156 sock = NULL;
1157 }
f4ada568 1158
f4ada568
GL
1159 return sock;
1160}
1161
17aa2bec 1162bool wxSocketServer::WaitForAccept(long seconds, long milliseconds)
d80d1aba 1163{
af2fd961 1164 return _Wait(seconds, milliseconds, GSOCK_CONNECTION_FLAG);
d80d1aba
GRG
1165}
1166
ef57d866 1167// ==========================================================================
8c14576d 1168// wxSocketClient
ef57d866 1169// ==========================================================================
f4ada568 1170
ef57d866
GRG
1171// --------------------------------------------------------------------------
1172// Ctor and dtor
1173// --------------------------------------------------------------------------
56d8adc0 1174
71622a7a
GRG
1175wxSocketClient::wxSocketClient(wxSocketFlags flags)
1176 : wxSocketBase(flags, wxSOCKET_CLIENT)
f4ada568
GL
1177{
1178}
1179
f4ada568
GL
1180wxSocketClient::~wxSocketClient()
1181{
1182}
1183
ef57d866
GRG
1184// --------------------------------------------------------------------------
1185// Connect
1186// --------------------------------------------------------------------------
dc5c1114 1187
791b24c4 1188bool wxSocketClient::Connect(wxSockAddress& addr_man, bool wait)
f4ada568 1189{
791b24c4
GRG
1190 GSocketError err;
1191
ef57d866 1192 if (m_socket)
04e1eb03
GRG
1193 {
1194 // Shutdown and destroy the socket
f4ada568 1195 Close();
a324a7bc 1196 GSocket_destroy(m_socket);
04e1eb03 1197 }
a324a7bc 1198
a324a7bc 1199 m_socket = GSocket_new();
d80d1aba
GRG
1200 m_connected = FALSE;
1201 m_establishing = FALSE;
384b4373 1202
a324a7bc 1203 if (!m_socket)
f4ada568 1204 return FALSE;
384b4373 1205
e8f4c584 1206 GSocket_SetTimeout(m_socket, m_timeout * 1000);
96db102a
GRG
1207 GSocket_SetCallback(m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1208 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1209 wx_socket_callback, (char *)this);
56d8adc0 1210
04e1eb03 1211 // If wait == FALSE, then the call should be nonblocking.
56d8adc0
GRG
1212 // When we are finished, we put the socket to blocking mode
1213 // again.
f4ada568 1214
791b24c4 1215 if (!wait)
5c9eff30 1216 GSocket_SetNonBlocking(m_socket, 1);
791b24c4 1217
a324a7bc 1218 GSocket_SetPeer(m_socket, addr_man.GetAddress());
791b24c4
GRG
1219 err = GSocket_Connect(m_socket, GSOCK_STREAMED);
1220
1221 if (!wait)
5c9eff30 1222 GSocket_SetNonBlocking(m_socket, 0);
791b24c4
GRG
1223
1224 if (err != GSOCK_NOERROR)
56d8adc0
GRG
1225 {
1226 if (err == GSOCK_WOULDBLOCK)
1227 m_establishing = TRUE;
1228
f4ada568 1229 return FALSE;
56d8adc0 1230 }
9111db68 1231
f4ada568
GL
1232 m_connected = TRUE;
1233 return TRUE;
1234}
1235
d80d1aba 1236bool wxSocketClient::WaitOnConnect(long seconds, long milliseconds)
f4ada568 1237{
af2fd961 1238 if (m_connected) // Already connected
d80d1aba
GRG
1239 return TRUE;
1240
af2fd961 1241 if (!m_establishing || !m_socket) // No connection in progress
d80d1aba
GRG
1242 return FALSE;
1243
2b396caa
GRG
1244 return _Wait(seconds, milliseconds, GSOCK_CONNECTION_FLAG |
1245 GSOCK_LOST_FLAG);
f4ada568
GL
1246}
1247
ef57d866 1248// ==========================================================================
dc5c1114 1249// wxDatagramSocket
ef57d866 1250// ==========================================================================
dc5c1114
GRG
1251
1252/* NOTE: experimental stuff - might change */
1253
71622a7a
GRG
1254wxDatagramSocket::wxDatagramSocket( wxSockAddress& addr,
1255 wxSocketFlags flags )
1256 : wxSocketBase( flags, wxSOCKET_DATAGRAM )
dc5c1114
GRG
1257{
1258 // Create the socket
1259 m_socket = GSocket_new();
1260
1261 if(!m_socket)
1262 return;
1263
1264 // Setup the socket as non connection oriented
1265 GSocket_SetLocal(m_socket, addr.GetAddress());
1266 if( GSocket_SetNonOriented(m_socket) != GSOCK_NOERROR )
1267 {
1268 GSocket_destroy(m_socket);
1269 m_socket = NULL;
1270 return;
1271 }
1272
1273 // Initialize all stuff
1274 m_connected = FALSE;
1275 m_establishing = FALSE;
1276 GSocket_SetTimeout( m_socket, m_timeout );
1277 GSocket_SetCallback( m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1278 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1279 wx_socket_callback, (char*)this );
1280
1281}
1282
1283wxDatagramSocket& wxDatagramSocket::RecvFrom( wxSockAddress& addr,
f187448d 1284 void* buf,
dc5c1114
GRG
1285 wxUint32 nBytes )
1286{
1287 Read(buf, nBytes);
1288 GetPeer(addr);
1289 return (*this);
1290}
1291
1292wxDatagramSocket& wxDatagramSocket::SendTo( wxSockAddress& addr,
f187448d 1293 const void* buf,
dc5c1114
GRG
1294 wxUint32 nBytes )
1295{
1296 GSocket_SetPeer(m_socket, addr.GetAddress());
1297 Write(buf, nBytes);
1298 return (*this);
1299}
1300
ef57d866 1301// ==========================================================================
a58d5df4 1302// wxSocketModule
ef57d866 1303// ==========================================================================
dc5c1114 1304
ed4c6c69 1305class wxSocketModule : public wxModule
dc5c1114 1306{
dc5c1114 1307public:
6c0d0845
VZ
1308 virtual bool OnInit()
1309 {
1310 // wxSocketBase will call GSocket_Init() itself when/if needed
1311 return TRUE;
1312 }
1313
1314 virtual void OnExit()
1315 {
1316 if ( wxSocketBase::IsInitialized() )
1317 wxSocketBase::Shutdown();
1318 }
1319
1320private:
1321 DECLARE_DYNAMIC_CLASS(wxSocketModule)
a58d5df4
GL
1322};
1323
1324IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule)
1325
35a4dab7
GL
1326#endif
1327 // wxUSE_SOCKETS
007c77ab
RL
1328
1329// vi:sts=4:sw=4:et