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