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