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