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