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