]> git.saurik.com Git - wxWidgets.git/blob - src/common/socket.cpp
wxMotif compilation fixes for wxDataObject and PROCESS_EVENTS (wxSocket)
[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 // Updated: September 1999
7 // Copyright: (C) 1999, 1998, 1997, Guilhem Lavaux
8 // (C) 1999, Guillermo Rodriguez Garcia
9 // RCS_ID: $Id$
10 // License: see wxWindows license
11 /////////////////////////////////////////////////////////////////////////////
12
13 #ifdef __GNUG__
14 #pragma implementation "socket.h"
15 #endif
16
17 // For compilers that support precompilation, includes "wx.h".
18 #include "wx/wxprec.h"
19
20 #ifdef __BORLANDC__
21 #pragma hdrstop
22 #endif
23
24 #if wxUSE_SOCKETS
25
26 /////////////////////////////////////////////////////////////////////////////
27 // wxWindows headers
28 /////////////////////////////////////////////////////////////////////////////
29 #include "wx/defs.h"
30 #include "wx/object.h"
31 #include "wx/string.h"
32 #include "wx/timer.h"
33 #include "wx/utils.h"
34 #include "wx/module.h"
35 #include "wx/log.h"
36
37 #include <stdlib.h>
38 #include <string.h>
39 #include <ctype.h>
40
41 /////////////////////////////////////////////////////////////////////////////
42 // wxSocket headers
43 /////////////////////////////////////////////////////////////////////////////
44 #include "wx/sckaddr.h"
45 #include "wx/socket.h"
46
47
48 #if defined(__WXMSW__) || defined(__WXPM__) || defined(__WXMOTIF__)
49 #define PROCESS_EVENTS() wxYield()
50 #elif defined(__WXGTK__)
51 #include <gtk/gtk.h>
52 #define PROCESS_EVENTS() gtk_main_iteration()
53 #endif
54
55
56 // --------------------------------------------------------------
57 // ClassInfos
58 // --------------------------------------------------------------
59 #if !USE_SHARED_LIBRARY
60 IMPLEMENT_CLASS(wxSocketBase, wxObject)
61 IMPLEMENT_CLASS(wxSocketServer, wxSocketBase)
62 IMPLEMENT_CLASS(wxSocketClient, wxSocketBase)
63 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent)
64 #endif
65
66 class wxSocketState : public wxObject
67 {
68 public:
69 bool notify_state;
70 GSocketEventFlags evt_notify_state;
71 wxSockFlags socket_flags;
72 wxSocketBase::wxSockCbk c_callback;
73 char *c_callback_data;
74
75 public:
76 wxSocketState() : wxObject() {}
77 };
78
79 // --------------------------------------------------------------
80 // wxSocketBase ctor and dtor
81 // --------------------------------------------------------------
82
83 wxSocketBase::wxSocketBase(wxSockFlags _flags, wxSockType _type) :
84 wxEvtHandler(),
85 m_socket(NULL), m_id(-1),
86 m_flags(_flags), m_type(_type),
87 m_neededreq(0), m_notify_state(FALSE),
88 m_connected(FALSE), m_establishing(FALSE),
89 m_reading(FALSE), m_writing(FALSE),
90 m_error(FALSE), m_lcount(0), m_timeout(600), m_states(),
91 m_unread(NULL), m_unrd_size(0), m_unrd_cur(0),
92 m_defering(NO_DEFER), m_defer_buffer(NULL), m_defer_timer(NULL),
93 m_cbk(NULL), m_cdata(NULL)
94 {
95 }
96
97 wxSocketBase::wxSocketBase() :
98 wxEvtHandler(),
99 m_socket(NULL), m_id(-1),
100 m_flags(NONE), m_type(SOCK_UNINIT),
101 m_neededreq(0), m_notify_state(FALSE),
102 m_connected(FALSE), m_establishing(FALSE),
103 m_reading(FALSE), m_writing(FALSE),
104 m_error(FALSE), m_lcount(0), m_timeout(600), m_states(),
105 m_unread(NULL), m_unrd_size(0), m_unrd_cur(0),
106 m_defering(NO_DEFER), m_defer_buffer(NULL), m_defer_timer(NULL),
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 bool wxSocketBase::Close()
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 m_connected = FALSE;
135 m_establishing = FALSE;
136 }
137
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 = m_new_val; // Change the value
159 }
160 };
161
162 wxUint32 wxSocketBase::DeferRead(char *buffer, wxUint32 nbytes)
163 {
164 // Timer for timeout
165 _wxSocketInternalTimer timer;
166
167 //wxLogMessage("Entrando a DeferRead, nbytes = %d", nbytes);
168 wxASSERT(m_defering == NO_DEFER);
169
170 // Set the defering mode to READ.
171 m_defering = DEFER_READ;
172
173 // Set the current buffer.
174 m_defer_buffer = buffer;
175 m_defer_nbytes = nbytes;
176 m_defer_timer = &timer;
177
178 timer.m_state = (int *)&m_defer_buffer;
179 timer.m_new_val = 0;
180
181 timer.Start(m_timeout * 1000, FALSE);
182
183 // If the socket is readable, call DoDefer for the first time
184 if (GSocket_Select(m_socket, GSOCK_INPUT_FLAG))
185 {
186 //wxLogMessage("Llamando al primer DoDefer");
187 DoDefer();
188 }
189
190 // Wait for buffer completion.
191 while (m_defer_buffer != NULL)
192 PROCESS_EVENTS();
193
194 timer.Stop();
195
196 // Disable defering mode.
197 m_defering = NO_DEFER;
198 m_defer_timer = NULL;
199
200 // Return the number of bytes read from the socket.
201 //wxLogMessage("Saliendo de DeferRead: total: %d bytes", nbytes - m_defer_nbytes);
202 return nbytes-m_defer_nbytes;
203 }
204
205 wxSocketBase& wxSocketBase::Read(char* buffer, wxUint32 nbytes)
206 {
207 // Mask read events
208 m_reading = TRUE;
209
210 m_lcount = _Read(buffer, nbytes);
211
212 // If in WAITALL mode, all bytes should have been read.
213 if (m_flags & WAITALL)
214 m_error = (m_lcount != nbytes);
215 else
216 m_error = (m_lcount == 0);
217
218 // Trigger another read event if there is still data available.
219 m_reading = FALSE;
220 // TODO: TriggerRead
221
222 return *this;
223 }
224
225 wxUint32 wxSocketBase::_Read(char* buffer, wxUint32 nbytes)
226 {
227 int total;
228 int ret = 1;
229
230 // we try this even if the connection has already been closed.
231 total = GetPushback(buffer, nbytes, FALSE);
232 nbytes -= total;
233 buffer += total;
234
235 // If the socket is not connected, or we have got the whole
236 // needed buffer, return immedately
237 if (!m_connected || !m_socket || !nbytes)
238 return total;
239
240 // Possible combinations (they are checked in this order)
241 // NOWAIT
242 // SPEED | WAITALL
243 // SPEED
244 // WAITALL
245 // NONE
246 //
247 if (m_flags & NOWAIT) // NOWAIT
248 {
249 GSocket_SetNonBlocking(m_socket, TRUE);
250 ret = GSocket_Read(m_socket, buffer, nbytes);
251 GSocket_SetNonBlocking(m_socket, FALSE);
252
253 if (ret > 0)
254 total += ret;
255 }
256 else if ((m_flags & SPEED) && (m_flags & WAITALL)) // SPEED, WAITALL
257 {
258 while (ret > 0 && nbytes > 0)
259 {
260 ret = GSocket_Read(m_socket, buffer, nbytes);
261 total += ret;
262 buffer += ret;
263 nbytes -= ret;
264 }
265 // In case the last call was an error ...
266 if (ret < 0)
267 total++;
268 }
269 else if (m_flags & SPEED) // SPEED, !WAITALL
270 {
271 ret = GSocket_Read(m_socket, buffer, nbytes);
272
273 if (ret > 0)
274 total += ret;
275 }
276 else // NONE or WAITALL
277 {
278 ret = DeferRead(buffer, nbytes);
279
280 if (ret > 0)
281 total += ret;
282 }
283
284 return total;
285 }
286
287 wxSocketBase& wxSocketBase::ReadMsg(char* buffer, wxUint32 nbytes)
288 {
289 #define MAX_DISCARD_SIZE (10 * 1024)
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 & SPEED) | WAITALL);
307
308 if (_Read((char *)&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 wxLogMessage(wxT("Warning: invalid signature returned to 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 //wxLogMessage("Readmsg: %d %d %d %d -> len == %d",
328 // msg.len[0], msg.len[1], msg.len[2], msg.len[3], len);
329
330 if (len > nbytes)
331 {
332 len2 = len - nbytes;
333 len = nbytes;
334 }
335 else
336 len2 = 0;
337
338 // This check is necessary so that we don't attemp to read if
339 // the msg was zero bytes long.
340 if (len)
341 {
342 total = _Read(buffer, len);
343
344 if (total != len)
345 goto exit;
346 }
347 if (len2)
348 {
349 char *discard_buffer = new char[MAX_DISCARD_SIZE];
350 long discard_len;
351
352 // NOTE: discarded bytes don't add to m_lcount.
353 do
354 {
355 discard_len = ((len2 > MAX_DISCARD_SIZE)? MAX_DISCARD_SIZE : len2);
356 discard_len = _Read(discard_buffer, discard_len);
357 len2 -= discard_len;
358 }
359 while ((discard_len > 0) && len2);
360
361 delete [] discard_buffer;
362
363 if (len2 != 0)
364 goto exit;
365 }
366 if (_Read((char *)&msg, sizeof(msg)) != sizeof(msg))
367 goto exit;
368
369 sig = (wxUint32)msg.sig[0];
370 sig |= (wxUint32)(msg.sig[1] << 8);
371 sig |= (wxUint32)(msg.sig[2] << 16);
372 sig |= (wxUint32)(msg.sig[3] << 24);
373
374 if (sig != 0xdeadfeed)
375 {
376 //wxLogMessage(wxT("Warning: invalid signature returned to ReadMsg"));
377 goto exit;
378 }
379
380 // everything was OK
381 error = FALSE;
382
383 exit:
384 m_error = error;
385 m_lcount = total;
386 m_reading = FALSE;
387 SetFlags(old_flags);
388
389 // TODO: TriggerRead
390 return *this;
391
392 #undef MAX_DISCARD_SIZE
393 }
394
395 wxSocketBase& wxSocketBase::Peek(char* buffer, wxUint32 nbytes)
396 {
397 // Mask read events
398 m_reading = TRUE;
399
400 m_lcount = _Read(buffer, nbytes);
401 Pushback(buffer, nbytes);
402
403 // If in WAITALL mode, all bytes should have been read.
404 if (m_flags & WAITALL)
405 m_error = (m_lcount != nbytes);
406 else
407 m_error = (m_lcount == 0);
408
409 // Trigger another read event if there is still data available.
410 m_reading = FALSE;
411
412 // TODO: TriggerRead
413 return *this;
414 }
415
416 wxUint32 wxSocketBase::DeferWrite(const char *buffer, wxUint32 nbytes)
417 {
418 // Timer for timeout
419 _wxSocketInternalTimer timer;
420
421 wxASSERT(m_defering == NO_DEFER);
422 //wxLogMessage("Entrando a DeferWrite");
423
424 m_defering = DEFER_WRITE;
425
426 // Set the current buffer
427 m_defer_buffer = (char *)buffer;
428 m_defer_nbytes = nbytes;
429 m_defer_timer = &timer;
430
431 // Start timer
432 timer.m_state = (int *)&m_defer_buffer;
433 timer.m_new_val = 0;
434
435 timer.Start(m_timeout * 1000, FALSE);
436
437 // If the socket is writable, call DoDefer for the first time
438 if (GSocket_Select(m_socket, GSOCK_OUTPUT_FLAG))
439 {
440 //wxLogMessage("Llamando al primer DoDefer");
441 DoDefer();
442 }
443
444 // Wait for buffer completion.
445 while (m_defer_buffer != NULL)
446 PROCESS_EVENTS();
447
448 timer.Stop();
449
450 // Disable defering mode
451 m_defer_timer = NULL;
452 m_defering = NO_DEFER;
453
454 wxString s;
455 s.Printf("Saliendo de DeferWrite: total %d bytes", nbytes-m_defer_nbytes);
456 //wxLogMessage(s);
457
458 return nbytes-m_defer_nbytes;
459 }
460
461 wxSocketBase& wxSocketBase::Write(const char *buffer, wxUint32 nbytes)
462 {
463 // Mask write events
464 m_writing = TRUE;
465
466 m_lcount = _Write(buffer, nbytes);
467
468 // If in WAITALL mode, all bytes should have been written.
469 if (m_flags & WAITALL)
470 m_error = (m_lcount != nbytes);
471 else
472 m_error = (m_lcount == 0);
473
474 // Trigger another write event if the socket is still writable
475 m_writing = FALSE;
476
477 // TODO: TriggerWrite
478 return *this;
479 }
480
481 wxUint32 wxSocketBase::_Write(const char *buffer, wxUint32 nbytes)
482 {
483 wxUint32 total = 0;
484 int ret = 1;
485
486 if (!m_connected || !m_socket)
487 return 0;
488
489 // Possible combinations (they are checked in this order)
490 // NOWAIT
491 // SPEED | WAITALL
492 // SPEED
493 // WAITALL
494 // NONE
495 //
496 if (m_flags & NOWAIT) // NOWAIT
497 {
498 GSocket_SetNonBlocking(m_socket, TRUE);
499 ret = GSocket_Write(m_socket, buffer, nbytes);
500 GSocket_SetNonBlocking(m_socket, FALSE);
501
502 if (ret > 0)
503 total = ret;
504 }
505 else if ((m_flags & SPEED) && (m_flags & WAITALL)) // SPEED, WAITALL
506 {
507 while (ret > 0 && nbytes > 0)
508 {
509 ret = GSocket_Write(m_socket, buffer, nbytes);
510 total += ret;
511 buffer += ret;
512 nbytes -= ret;
513 }
514 // In case the last call was an error ...
515 if (ret < 0)
516 total ++;
517 }
518 else if (m_flags & SPEED) // SPEED, !WAITALL
519 {
520 ret = GSocket_Write(m_socket, buffer, nbytes);
521
522 if (ret > 0)
523 total = ret;
524 }
525 else // NONE or WAITALL
526 {
527 ret = DeferWrite(buffer, nbytes);
528
529 if (ret > 0)
530 total = ret;
531 }
532
533 return total;
534 }
535
536 wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, wxUint32 nbytes)
537 {
538 wxUint32 total;
539 bool error;
540 int old_flags;
541 struct {
542 unsigned char sig[4];
543 unsigned char len[4];
544 } msg;
545
546 // Mask write events
547 m_writing = TRUE;
548
549 error = TRUE;
550 total = 0;
551 old_flags = m_flags;
552 SetFlags((m_flags & SPEED) | WAITALL);
553
554 // warning about 'cast truncates constant value'
555 #ifdef __VISUALC__
556 # pragma warning(disable: 4310)
557 #endif // __VISUALC__
558
559 msg.sig[0] = (unsigned char) 0xad;
560 msg.sig[1] = (unsigned char) 0xde;
561 msg.sig[2] = (unsigned char) 0xed;
562 msg.sig[3] = (unsigned char) 0xfe;
563
564 msg.len[0] = (unsigned char) nbytes & 0xff;
565 msg.len[1] = (unsigned char) (nbytes >> 8) & 0xff;
566 msg.len[2] = (unsigned char) (nbytes >> 16) & 0xff;
567 msg.len[3] = (unsigned char) (nbytes >> 24) & 0xff;
568
569 //wxLogMessage("Writemsg: %d %d %d %d -> %d",
570 // nbytes & 0xff,
571 // (nbytes >> 8) & 0xff,
572 // (nbytes >> 16) & 0xff,
573 // (nbytes >> 24) & 0xff,
574 // nbytes
575 // );
576
577 if (_Write((char *)&msg, sizeof(msg)) < sizeof(msg))
578 goto exit;
579
580 total = _Write(buffer, nbytes);
581
582 if (total < nbytes)
583 goto exit;
584
585 msg.sig[0] = (unsigned char) 0xed;
586 msg.sig[1] = (unsigned char) 0xfe;
587 msg.sig[2] = (unsigned char) 0xad;
588 msg.sig[3] = (unsigned char) 0xde;
589 msg.len[0] = msg.len[1] = msg.len[2] = msg.len[3] = (char) 0;
590
591 if ((_Write((char *)&msg, sizeof(msg))) < sizeof(msg))
592 goto exit;
593
594 // everything was OK
595 error = FALSE;
596
597 exit:
598 m_error = error;
599 m_lcount = total;
600 m_writing = FALSE;
601
602 // TODO: TriggerWrite
603 return *this;
604
605 #ifdef __VISUALC__
606 # pragma warning(default: 4310)
607 #endif // __VISUALC__
608 }
609
610 wxSocketBase& wxSocketBase::Unread(const char *buffer, wxUint32 nbytes)
611 {
612 if (nbytes != 0)
613 Pushback(buffer, nbytes);
614
615 m_error = FALSE;
616 m_lcount = nbytes;
617
618 return *this;
619 }
620
621 void wxSocketBase::DoDefer()
622 {
623 int ret;
624
625 if (!m_defer_buffer)
626 return;
627
628 switch(m_defering)
629 {
630 case DEFER_READ:
631 ret = GSocket_Read(m_socket, m_defer_buffer, m_defer_nbytes);
632 break;
633 case DEFER_WRITE:
634 ret = GSocket_Write(m_socket, m_defer_buffer, m_defer_nbytes);
635 break;
636 default:
637 ret = -1;
638 }
639
640 if (ret >= 0)
641 m_defer_nbytes -= ret;
642
643 // If we are waiting for all bytes to be acquired, keep the defering
644 // mode enabled.
645 if (!(m_flags & WAITALL) || !m_defer_nbytes || ret < 0)
646 {
647 m_defer_buffer = NULL;
648 }
649 else
650 {
651 m_defer_buffer += ret;
652 m_defer_timer->Start(m_timeout * 1000, FALSE);
653 }
654
655 //wxLogMessage("DoDefer ha transferido %d bytes", ret);
656 }
657
658 wxSocketBase& wxSocketBase::Discard()
659 {
660 #define MAX_BUFSIZE (10*1024)
661
662 int old_flags;
663 char *my_data = new char[MAX_BUFSIZE];
664 wxUint32 recv_size = MAX_BUFSIZE;
665 wxUint32 total = 0;
666
667 // Mask read events
668 m_reading = TRUE;
669
670 old_flags = m_flags;
671 SetFlags(NOWAIT);
672
673 while (recv_size == MAX_BUFSIZE)
674 {
675 recv_size = _Read(my_data, MAX_BUFSIZE);
676 total += recv_size;
677 }
678
679 delete [] my_data;
680 m_lcount = total;
681 m_error = FALSE;
682
683 // Trigger another read event if there is still data available.
684 m_reading = FALSE;
685
686 // TODO: TriggerRead
687 return *this;
688
689 #undef MAX_BUFSIZE
690 }
691
692 // --------------------------------------------------------------
693 // wxSocketBase get local or peer addresses
694 // --------------------------------------------------------------
695
696 bool wxSocketBase::GetPeer(wxSockAddress& addr_man) const
697 {
698 GAddress *peer;
699
700 if (!m_socket)
701 return FALSE;
702
703 peer = GSocket_GetPeer(m_socket);
704 addr_man.SetAddress(peer);
705 GAddress_destroy(peer);
706
707 return TRUE;
708 }
709
710 bool wxSocketBase::GetLocal(wxSockAddress& addr_man) const
711 {
712 GAddress *local;
713
714 if (!m_socket)
715 return FALSE;
716
717 local = GSocket_GetLocal(m_socket);
718 addr_man.SetAddress(local);
719 GAddress_destroy(local);
720
721 return TRUE;
722 }
723
724 // --------------------------------------------------------------
725 // wxSocketBase save and restore socket state
726 // --------------------------------------------------------------
727
728 void wxSocketBase::SaveState()
729 {
730 wxSocketState *state;
731
732 state = new wxSocketState();
733
734 state->notify_state = m_notify_state;
735 state->evt_notify_state = m_neededreq;
736 state->socket_flags = m_flags;
737 state->c_callback = m_cbk;
738 state->c_callback_data = m_cdata;
739
740 m_states.Append(state);
741 }
742
743 void wxSocketBase::RestoreState()
744 {
745 wxNode *node;
746 wxSocketState *state;
747
748 node = m_states.Last();
749 if (!node)
750 return;
751
752 state = (wxSocketState *)node->Data();
753
754 SetFlags(state->socket_flags);
755 m_neededreq = state->evt_notify_state;
756 m_cbk = state->c_callback;
757 m_cdata = state->c_callback_data;
758 Notify(state->notify_state);
759
760 delete node;
761 delete state;
762 }
763
764
765 // --------------------------------------------------------------
766 // wxSocketBase Wait functions
767 // --------------------------------------------------------------
768
769 // GRG: I have completely rewritten this family of functions
770 // so that they don't depend on event notifications; instead,
771 // they poll the socket, using GSocket_Select(), to check for
772 // the specified combination of event flags, until an event
773 // occurs or until the timeout ellapses. The polling loop
774 // calls PROCESS_EVENTS(), so this won't block the GUI.
775
776 bool wxSocketBase::_Wait(long seconds, long milliseconds, wxSocketEventFlags flags)
777 {
778 GSocketEventFlags result;
779 _wxSocketInternalTimer timer;
780 long timeout;
781 int state = -1;
782
783 // Check for valid socket
784 if (!m_socket)
785 return FALSE;
786
787 // If it is not a server, it must be connected or establishing connection
788 if ((m_type != SOCK_SERVER) && (!m_connected && !m_establishing))
789 return FALSE;
790
791 // Check for valid timeout value
792 if (seconds != -1)
793 timeout = seconds * 1000 + milliseconds;
794 else
795 timeout = m_timeout * 1000;
796
797 // Activate timer
798 if (timeout)
799 {
800 timer.m_state = &state;
801 timer.m_new_val = 0;
802 timer.Start(timeout, TRUE);
803 }
804
805 // Active polling (without using events)
806 //
807 // NOTE: this duplicates some of the code in OnRequest (lost
808 // connection and connection establishment handling) but this
809 // doesn't hurt. It has to be here because the event might
810 // be a bit delayed, and it has to be in OnRequest as well
811 // because maybe the WaitXXX functions are not being used.
812 //
813 // Do this at least once (important if timeout == 0, when
814 // we are just polling)
815 do
816 {
817 result = GSocket_Select(m_socket, flags | GSOCK_LOST_FLAG);
818
819 // Connection lost
820 if (result & GSOCK_LOST_FLAG)
821 {
822 timer.Stop();
823 m_defer_buffer = NULL;
824 Close();
825 return TRUE;
826 }
827
828 // Incoming connection (server) or connection established (client)
829 if (result & GSOCK_CONNECTION_FLAG)
830 {
831 timer.Stop();
832 m_connected = TRUE;
833 m_establishing = FALSE;
834 return TRUE;
835 }
836
837 // If we are in the middle of a R/W operation, do not propagate
838 // to users.
839 if ( ((result & GSOCK_INPUT_FLAG) || (result & GSOCK_OUTPUT_FLAG))
840 && (!m_writing) && (!m_reading) )
841 {
842 /* TODO: remove this
843 if (m_defer_buffer == NULL)
844 */
845 {
846 timer.Stop();
847 return TRUE;
848 }
849 }
850
851 if (timeout != 0)
852 PROCESS_EVENTS();
853 }
854 while ((state == -1) && timeout);
855
856 timer.Stop();
857 return FALSE;
858 }
859
860 bool wxSocketBase::Wait(long seconds, long milliseconds)
861 {
862 return _Wait(seconds, milliseconds, GSOCK_INPUT_FLAG |
863 GSOCK_OUTPUT_FLAG |
864 GSOCK_CONNECTION_FLAG |
865 GSOCK_LOST_FLAG);
866 }
867
868 bool wxSocketBase::WaitForRead(long seconds, long milliseconds)
869 {
870 // Check pushback buffer
871 if (m_unread)
872 return TRUE;
873
874 return _Wait(seconds, milliseconds, GSOCK_INPUT_FLAG);
875 }
876
877 bool wxSocketBase::WaitForWrite(long seconds, long milliseconds)
878 {
879 return _Wait(seconds, milliseconds, GSOCK_OUTPUT_FLAG);
880 }
881
882 bool wxSocketBase::WaitForLost(long seconds, long milliseconds)
883 {
884 return _Wait(seconds, milliseconds, GSOCK_LOST_FLAG);
885 }
886
887 void wxSocketBase::SetTimeout(long seconds)
888 {
889 m_timeout = seconds;
890
891 if (m_socket)
892 GSocket_SetTimeout(m_socket, m_timeout);
893 }
894
895 // --------------------------------------------------------------
896 // wxSocketBase flags
897 // --------------------------------------------------------------
898
899 void wxSocketBase::SetFlags(wxSockFlags _flags)
900 {
901 m_flags = _flags;
902 }
903
904 // --------------------------------------------------------------
905 // wxSocketBase callback management
906 // --------------------------------------------------------------
907
908 wxSocketBase::wxSockCbk wxSocketBase::Callback(wxSockCbk cbk_)
909 {
910 wxSockCbk old_cbk = cbk_;
911
912 m_cbk = cbk_;
913 return old_cbk;
914 }
915
916 char *wxSocketBase::CallbackData(char *data)
917 {
918 char *old_data = m_cdata;
919
920 m_cdata = data;
921 return old_data;
922 }
923
924 // --------------------------------------------------------------
925 // wxSocketBase automatic notifier
926 // --------------------------------------------------------------
927
928 // All events (INPUT, OUTPUT, CONNECTION, LOST) are now always
929 // internally watched; but users will only be notified of those
930 // events they are interested in.
931
932 static void LINKAGEMODE wx_socket_callback(GSocket * WXUNUSED(socket),
933 GSocketEvent event, char *cdata)
934 {
935 wxSocketBase *sckobj = (wxSocketBase *)cdata;
936
937 sckobj->OnRequest((wxSocketNotify)event);
938 }
939
940 wxSocketEventFlags wxSocketBase::EventToNotify(wxSocketNotify evt)
941 {
942 switch (evt)
943 {
944 case GSOCK_INPUT: return GSOCK_INPUT_FLAG;
945 case GSOCK_OUTPUT: return GSOCK_OUTPUT_FLAG;
946 case GSOCK_CONNECTION: return GSOCK_CONNECTION_FLAG;
947 case GSOCK_LOST: return GSOCK_LOST_FLAG;
948 }
949 return 0;
950 }
951
952 void wxSocketBase::SetNotify(wxSocketEventFlags flags)
953 {
954 m_neededreq = flags;
955 }
956
957 void wxSocketBase::Notify(bool notify)
958 {
959 m_notify_state = notify;
960 }
961
962 void wxSocketBase::OnRequest(wxSocketNotify req_evt)
963 {
964 wxSocketEvent event(m_id);
965 wxSocketEventFlags flag = EventToNotify(req_evt);
966
967 // fprintf(stderr, "%s: Entering OnRequest (evt %d)\n", (m_type == SOCK_CLIENT)? "client" : "server", req_evt);
968
969 // NOTE: this duplicates some of the code in _Wait (lost
970 // connection and connection establishment handling) but
971 // this doesn't hurt. It has to be here because maybe the
972 // WaitXXX are not being used, and it has to be in _Wait
973 // as well because the event might be a bit delayed.
974 //
975 switch(req_evt)
976 {
977 case wxSOCKET_CONNECTION:
978 m_establishing = FALSE;
979 m_connected = TRUE;
980 break;
981 case wxSOCKET_LOST:
982 m_defer_buffer = NULL;
983 Close();
984 break;
985 case wxSOCKET_INPUT:
986 case wxSOCKET_OUTPUT:
987 if (m_defer_buffer)
988 {
989 // fprintf(stderr, "%s: Habia buffer, evt %d skipped\n", (m_type == SOCK_CLIENT)? "client" : "server", req_evt);
990 DoDefer();
991 // Do not notify to user
992 return;
993 }
994 break;
995 }
996
997 // If we are in the middle of a R/W operation, do not
998 // propagate events to users.
999 if (((req_evt == wxSOCKET_INPUT) && m_reading) ||
1000 ((req_evt == wxSOCKET_OUTPUT) && m_writing))
1001 {
1002 // fprintf(stderr, "%s: Swallowed evt %d\n", (m_type == SOCK_CLIENT)? "client" : "server", req_evt);
1003 return;
1004 }
1005
1006 if (((m_neededreq & flag) == flag) && m_notify_state)
1007 {
1008 // fprintf(stderr, "%s: Evt %d delivered\n", (m_type == SOCK_CLIENT)? "client" : "server", req_evt);
1009 event.m_socket = this;
1010 event.m_skevt = req_evt;
1011 ProcessEvent(event);
1012 OldOnNotify(req_evt);
1013
1014 if (m_cbk)
1015 m_cbk(*this, req_evt, m_cdata);
1016 }
1017
1018 // fprintf(stderr, "%s: Exiting OnRequest (evt %d)\n", (m_type == SOCK_CLIENT)? "client" : "server", req_evt);
1019 }
1020
1021 void wxSocketBase::OldOnNotify(wxSocketNotify WXUNUSED(evt))
1022 {
1023 }
1024
1025 // --------------------------------------------------------------
1026 // wxSocketBase set event handler
1027 // --------------------------------------------------------------
1028
1029 void wxSocketBase::SetEventHandler(wxEvtHandler& h_evt, int id)
1030 {
1031 SetNextHandler(&h_evt);
1032 m_id = id;
1033 }
1034
1035 // --------------------------------------------------------------
1036 // wxSocketBase pushback
1037 // --------------------------------------------------------------
1038
1039 void wxSocketBase::Pushback(const char *buffer, wxUint32 size)
1040 {
1041 if (m_unread == NULL)
1042 m_unread = (char *)malloc(size);
1043 else {
1044 char *tmp;
1045
1046 tmp = (char *)malloc(m_unrd_size + size);
1047 memcpy(tmp+size, m_unread, m_unrd_size);
1048 free(m_unread);
1049
1050 m_unread = tmp;
1051 }
1052
1053 m_unrd_size += size;
1054
1055 memcpy(m_unread, buffer, size);
1056 }
1057
1058 wxUint32 wxSocketBase::GetPushback(char *buffer, wxUint32 size, bool peek)
1059 {
1060 if (!m_unrd_size)
1061 return 0;
1062
1063 if (size > (m_unrd_size-m_unrd_cur))
1064 size = m_unrd_size-m_unrd_cur;
1065
1066 memcpy(buffer, (m_unread+m_unrd_cur), size);
1067
1068 if (!peek) {
1069 m_unrd_cur += size;
1070 if (m_unrd_size == m_unrd_cur) {
1071 free(m_unread);
1072 m_unread = NULL;
1073 m_unrd_size = 0;
1074 m_unrd_cur = 0;
1075 }
1076 }
1077
1078 return size;
1079 }
1080
1081 // --------------------------------------------------------------
1082 // wxSocketServer
1083 // --------------------------------------------------------------
1084
1085 // --------------------------------------------------------------
1086 // wxSocketServer ctor and dtor
1087 // --------------------------------------------------------------
1088
1089 wxSocketServer::wxSocketServer(wxSockAddress& addr_man,
1090 wxSockFlags flags) :
1091 wxSocketBase(flags, SOCK_SERVER)
1092 {
1093 // Create the socket
1094 m_socket = GSocket_new();
1095
1096 if (!m_socket)
1097 return;
1098
1099 // Setup the socket as server
1100 GSocket_SetLocal(m_socket, addr_man.GetAddress());
1101 if (GSocket_SetServer(m_socket) != GSOCK_NOERROR)
1102 {
1103 GSocket_destroy(m_socket);
1104 m_socket = NULL;
1105 return;
1106 }
1107
1108 GSocket_SetTimeout(m_socket, m_timeout);
1109 GSocket_SetCallback(m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1110 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1111 wx_socket_callback, (char *)this);
1112
1113 }
1114
1115 // --------------------------------------------------------------
1116 // wxSocketServer Accept
1117 // --------------------------------------------------------------
1118
1119 bool wxSocketServer::AcceptWith(wxSocketBase& sock, bool wait)
1120 {
1121 GSocket *child_socket;
1122
1123 if (!m_socket)
1124 return FALSE;
1125
1126 // GRG: If wait == FALSE, then the call should be nonblocking.
1127 // When we are finished, we put the socket to blocking mode
1128 // again.
1129
1130 if (!wait)
1131 GSocket_SetNonBlocking(m_socket, TRUE);
1132
1133 child_socket = GSocket_WaitConnection(m_socket);
1134
1135 if (!wait)
1136 GSocket_SetNonBlocking(m_socket, FALSE);
1137
1138 // GRG: this was not being handled!
1139 if (child_socket == NULL)
1140 return FALSE;
1141
1142 sock.m_type = SOCK_INTERNAL;
1143 sock.m_socket = child_socket;
1144 sock.m_connected = TRUE;
1145
1146 GSocket_SetTimeout(sock.m_socket, sock.m_timeout);
1147 GSocket_SetCallback(sock.m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1148 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1149 wx_socket_callback, (char *)&sock);
1150
1151 return TRUE;
1152 }
1153
1154 wxSocketBase *wxSocketServer::Accept(bool wait)
1155 {
1156 wxSocketBase* sock = new wxSocketBase();
1157
1158 sock->SetFlags((wxSockFlags)m_flags);
1159
1160 if (!AcceptWith(*sock, wait))
1161 return NULL;
1162
1163 return sock;
1164 }
1165
1166 bool wxSocketServer::WaitForAccept(long seconds, long milliseconds)
1167 {
1168 return _Wait(seconds, milliseconds, GSOCK_CONNECTION_FLAG);
1169 }
1170
1171 // --------------------------------------------------------------
1172 // wxSocketClient
1173 // --------------------------------------------------------------
1174
1175 // --------------------------------------------------------------
1176 // wxSocketClient ctor and dtor
1177 // --------------------------------------------------------------
1178
1179 wxSocketClient::wxSocketClient(wxSockFlags _flags) :
1180 wxSocketBase(_flags, SOCK_CLIENT)
1181 {
1182 }
1183
1184 wxSocketClient::~wxSocketClient()
1185 {
1186 }
1187
1188 // --------------------------------------------------------------
1189 // wxSocketClient Connect functions
1190 // --------------------------------------------------------------
1191 bool wxSocketClient::Connect(wxSockAddress& addr_man, bool wait)
1192 {
1193 GSocketError err;
1194
1195 if (IsConnected())
1196 Close();
1197
1198 // This should never happen.
1199 if (m_socket)
1200 GSocket_destroy(m_socket);
1201
1202 // Initialize all socket stuff ...
1203 m_socket = GSocket_new();
1204 m_connected = FALSE;
1205 m_establishing = FALSE;
1206
1207 if (!m_socket)
1208 return FALSE;
1209
1210 GSocket_SetTimeout(m_socket, m_timeout);
1211 GSocket_SetCallback(m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1212 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1213 wx_socket_callback, (char *)this);
1214
1215 // GRG: If wait == FALSE, then the call should be nonblocking.
1216 // When we are finished, we put the socket to blocking mode
1217 // again.
1218
1219 if (!wait)
1220 GSocket_SetNonBlocking(m_socket, TRUE);
1221
1222 GSocket_SetPeer(m_socket, addr_man.GetAddress());
1223 err = GSocket_Connect(m_socket, GSOCK_STREAMED);
1224
1225 if (!wait)
1226 GSocket_SetNonBlocking(m_socket, FALSE);
1227
1228 if (err != GSOCK_NOERROR)
1229 {
1230 if (err == GSOCK_WOULDBLOCK)
1231 m_establishing = TRUE;
1232
1233 return FALSE;
1234 }
1235
1236 m_connected = TRUE;
1237 return TRUE;
1238 }
1239
1240 bool wxSocketClient::WaitOnConnect(long seconds, long milliseconds)
1241 {
1242 if (m_connected) // Already connected
1243 return TRUE;
1244
1245 if (!m_establishing || !m_socket) // No connection in progress
1246 return FALSE;
1247
1248 return _Wait(seconds, milliseconds, GSOCK_CONNECTION_FLAG);
1249 }
1250
1251 // --------------------------------------------------------------
1252 // wxSocketEvent
1253 // --------------------------------------------------------------
1254
1255 wxSocketEvent::wxSocketEvent(int id)
1256 : wxEvent(id)
1257 {
1258 wxEventType type = (wxEventType)wxEVT_SOCKET;
1259
1260 SetEventType(type);
1261 }
1262
1263 void wxSocketEvent::CopyObject(wxObject& obj_d) const
1264 {
1265 wxSocketEvent *event = (wxSocketEvent *)&obj_d;
1266
1267 wxEvent::CopyObject(obj_d);
1268
1269 event->m_skevt = m_skevt;
1270 event->m_socket = m_socket;
1271 }
1272
1273 // --------------------------------------------------------------------------
1274 // wxSocketModule
1275 // --------------------------------------------------------------------------
1276 class WXDLLEXPORT wxSocketModule: public wxModule {
1277 DECLARE_DYNAMIC_CLASS(wxSocketModule)
1278 public:
1279 bool OnInit() {
1280 return GSocket_Init();
1281 }
1282 void OnExit() {
1283 GSocket_Cleanup();
1284 }
1285 };
1286
1287 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule)
1288
1289 #endif
1290 // wxUSE_SOCKETS