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