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