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