]> git.saurik.com Git - wxWidgets.git/blob - src/common/socket.cpp
8e8f73c94511e0cb9db17fd7ed00e9c8b52c03a7
[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 * WXUNUSED(socket),
867 GSocketEvent event, char *cdata)
868 {
869 wxSocketBase *sckobj = (wxSocketBase *)cdata;
870
871 sckobj->OnRequest((wxSocketNotify)event);
872 }
873
874 wxSocketEventFlags wxSocketBase::EventToNotify(wxSocketNotify evt)
875 {
876 switch (evt)
877 {
878 case GSOCK_INPUT: return GSOCK_INPUT_FLAG;
879 case GSOCK_OUTPUT: return GSOCK_OUTPUT_FLAG;
880 case GSOCK_CONNECTION: return GSOCK_CONNECTION_FLAG;
881 case GSOCK_LOST: return GSOCK_LOST_FLAG;
882 }
883 return 0;
884 }
885
886 void wxSocketBase::SetNotify(wxSocketEventFlags flags)
887 {
888 m_neededreq = flags;
889 }
890
891 void wxSocketBase::Notify(bool notify)
892 {
893 m_notify_state = notify;
894 }
895
896 void wxSocketBase::OnRequest(wxSocketNotify req_evt)
897 {
898 wxSocketEvent event(m_id);
899 wxSocketEventFlags flag = EventToNotify(req_evt);
900
901 // NOTE: this duplicates some of the code in _Wait (lost
902 // connection and connection establishment handling) but
903 // this doesn't hurt. It has to be here because maybe the
904 // WaitXXX are not being used, and it has to be in _Wait
905 // as well because the event might be a bit delayed.
906 //
907 switch(req_evt)
908 {
909 case wxSOCKET_CONNECTION:
910 m_establishing = FALSE;
911 m_connected = TRUE;
912 break;
913 case wxSOCKET_LOST:
914 m_defer_buffer = NULL;
915 Close();
916 break;
917 case wxSOCKET_INPUT:
918 case wxSOCKET_OUTPUT:
919 if (m_defer_buffer)
920 {
921 // GRG: DoDefer() no longer needs to know which
922 // event occured, because this was only used to
923 // catch LOST events and set m_defer_buffer to
924 // NULL, and this is done in OnRequest() now.
925 DoDefer();
926 // Do not notify to user
927 return;
928 }
929 break;
930 }
931
932 if (((m_neededreq & flag) == flag) && m_notify_state)
933 {
934 event.m_socket = this;
935 event.m_skevt = req_evt;
936 ProcessEvent(event);
937 OldOnNotify(req_evt);
938
939 if (m_cbk)
940 m_cbk(*this, req_evt, m_cdata);
941 }
942 }
943
944 void wxSocketBase::OldOnNotify(wxSocketNotify WXUNUSED(evt))
945 {
946 }
947
948 // --------------------------------------------------------------
949 // wxSocketBase set event handler
950 // --------------------------------------------------------------
951
952 void wxSocketBase::SetEventHandler(wxEvtHandler& h_evt, int id)
953 {
954 SetNextHandler(&h_evt);
955 m_id = id;
956 }
957
958 // --------------------------------------------------------------
959 // wxSocketBase pushback library
960 // --------------------------------------------------------------
961
962 void wxSocketBase::CreatePushbackAfter(const char *buffer, wxUint32 size)
963 {
964 char *curr_pos;
965
966 if (m_unread != NULL)
967 m_unread = (char *) realloc(m_unread, m_unrd_size+size);
968 else
969 m_unread = (char *) malloc(size);
970
971 curr_pos = m_unread + m_unrd_size;
972
973 memcpy(curr_pos, buffer, size);
974 m_unrd_size += size;
975 }
976
977 void wxSocketBase::CreatePushbackBefore(const char *buffer, wxUint32 size)
978 {
979 if (m_unread == NULL)
980 m_unread = (char *)malloc(size);
981 else {
982 char *tmp;
983
984 tmp = (char *)malloc(m_unrd_size + size);
985 memcpy(tmp+size, m_unread, m_unrd_size);
986 free(m_unread);
987
988 m_unread = tmp;
989 }
990
991 m_unrd_size += size;
992
993 memcpy(m_unread, buffer, size);
994 }
995
996 wxUint32 wxSocketBase::GetPushback(char *buffer, wxUint32 size, bool peek)
997 {
998 if (!m_unrd_size)
999 return 0;
1000
1001 if (size > (m_unrd_size-m_unrd_cur))
1002 size = m_unrd_size-m_unrd_cur;
1003 memcpy(buffer, (m_unread+m_unrd_cur), size);
1004
1005 if (!peek) {
1006 m_unrd_cur += size;
1007 if (m_unrd_size == m_unrd_cur) {
1008 free(m_unread);
1009 m_unread = NULL;
1010 m_unrd_size = 0;
1011 m_unrd_cur = 0;
1012 }
1013 }
1014
1015 return size;
1016 }
1017
1018 // --------------------------------------------------------------
1019 // wxSocketServer
1020 // --------------------------------------------------------------
1021
1022 // --------------------------------------------------------------
1023 // wxSocketServer ctor and dtor
1024 // --------------------------------------------------------------
1025
1026 wxSocketServer::wxSocketServer(wxSockAddress& addr_man,
1027 wxSockFlags flags) :
1028 wxSocketBase(flags, SOCK_SERVER)
1029 {
1030 // Create the socket
1031 m_socket = GSocket_new();
1032
1033 if (!m_socket)
1034 return;
1035
1036 // Setup the socket as server
1037 GSocket_SetLocal(m_socket, addr_man.GetAddress());
1038 if (GSocket_SetServer(m_socket) != GSOCK_NOERROR)
1039 {
1040 GSocket_destroy(m_socket);
1041 m_socket = NULL;
1042 return;
1043 }
1044
1045 GSocket_SetTimeout(m_socket, m_timeout);
1046 GSocket_SetCallback(m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1047 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1048 wx_socket_callback, (char *)this);
1049
1050 }
1051
1052 // --------------------------------------------------------------
1053 // wxSocketServer Accept
1054 // --------------------------------------------------------------
1055
1056 bool wxSocketServer::AcceptWith(wxSocketBase& sock, bool wait)
1057 {
1058 GSocket *child_socket;
1059
1060 if (!m_socket)
1061 return FALSE;
1062
1063 // GRG: If wait == FALSE, then the call should be nonblocking.
1064 // When we are finished, we put the socket to blocking mode
1065 // again.
1066
1067 if (!wait)
1068 GSocket_SetNonBlocking(m_socket, TRUE);
1069
1070 child_socket = GSocket_WaitConnection(m_socket);
1071
1072 if (!wait)
1073 GSocket_SetNonBlocking(m_socket, FALSE);
1074
1075 // GRG: this was not being handled!
1076 if (child_socket == NULL)
1077 return FALSE;
1078
1079 sock.m_type = SOCK_INTERNAL;
1080 sock.m_socket = child_socket;
1081 sock.m_connected = TRUE;
1082
1083 GSocket_SetTimeout(sock.m_socket, sock.m_timeout);
1084 GSocket_SetCallback(sock.m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1085 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1086 wx_socket_callback, (char *)&sock);
1087
1088 return TRUE;
1089 }
1090
1091 wxSocketBase *wxSocketServer::Accept(bool wait)
1092 {
1093 wxSocketBase* sock = new wxSocketBase();
1094
1095 sock->SetFlags((wxSockFlags)m_flags);
1096
1097 if (!AcceptWith(*sock, wait))
1098 return NULL;
1099
1100 return sock;
1101 }
1102
1103 bool wxSocketServer::WaitForAccept(long seconds, long milliseconds)
1104 {
1105 return _Wait(seconds, milliseconds, GSOCK_CONNECTION_FLAG);
1106 }
1107
1108 // --------------------------------------------------------------
1109 // wxSocketClient
1110 // --------------------------------------------------------------
1111
1112 // --------------------------------------------------------------
1113 // wxSocketClient ctor and dtor
1114 // --------------------------------------------------------------
1115
1116 wxSocketClient::wxSocketClient(wxSockFlags _flags) :
1117 wxSocketBase(_flags, SOCK_CLIENT)
1118 {
1119 }
1120
1121 wxSocketClient::~wxSocketClient()
1122 {
1123 }
1124
1125 // --------------------------------------------------------------
1126 // wxSocketClient Connect functions
1127 // --------------------------------------------------------------
1128 bool wxSocketClient::Connect(wxSockAddress& addr_man, bool wait)
1129 {
1130 GSocketError err;
1131
1132 if (IsConnected())
1133 Close();
1134
1135 // This should never happen.
1136 if (m_socket)
1137 GSocket_destroy(m_socket);
1138
1139 // Initialize all socket stuff ...
1140 m_socket = GSocket_new();
1141 m_connected = FALSE;
1142 m_establishing = FALSE;
1143
1144 if (!m_socket)
1145 return FALSE;
1146
1147 GSocket_SetTimeout(m_socket, m_timeout);
1148
1149 // GRG: If wait == FALSE, then the call should be nonblocking.
1150 // When we are finished, we put the socket to blocking mode
1151 // again.
1152
1153 if (!wait)
1154 GSocket_SetNonBlocking(m_socket, TRUE);
1155
1156 GSocket_SetPeer(m_socket, addr_man.GetAddress());
1157 err = GSocket_Connect(m_socket, GSOCK_STREAMED);
1158 GSocket_SetCallback(m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1159 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1160 wx_socket_callback, (char *)this);
1161
1162 if (!wait)
1163 GSocket_SetNonBlocking(m_socket, FALSE);
1164
1165 if (err != GSOCK_NOERROR)
1166 {
1167 if (err == GSOCK_WOULDBLOCK)
1168 m_establishing = TRUE;
1169
1170 return FALSE;
1171 }
1172
1173 m_connected = TRUE;
1174 return TRUE;
1175 }
1176
1177 bool wxSocketClient::WaitOnConnect(long seconds, long milliseconds)
1178 {
1179 if (m_connected) // Already connected
1180 return TRUE;
1181
1182 if (!m_establishing || !m_socket) // No connection in progress
1183 return FALSE;
1184
1185 return _Wait(seconds, milliseconds, GSOCK_CONNECTION_FLAG);
1186 }
1187
1188 // --------------------------------------------------------------
1189 // wxSocketEvent
1190 // --------------------------------------------------------------
1191
1192 wxSocketEvent::wxSocketEvent(int id)
1193 : wxEvent(id)
1194 {
1195 wxEventType type = (wxEventType)wxEVT_SOCKET;
1196
1197 SetEventType(type);
1198 }
1199
1200 void wxSocketEvent::CopyObject(wxObject& obj_d) const
1201 {
1202 wxSocketEvent *event = (wxSocketEvent *)&obj_d;
1203
1204 wxEvent::CopyObject(obj_d);
1205
1206 event->m_skevt = m_skevt;
1207 event->m_socket = m_socket;
1208 }
1209
1210 // --------------------------------------------------------------------------
1211 // wxSocketModule
1212 // --------------------------------------------------------------------------
1213 class WXDLLEXPORT wxSocketModule: public wxModule {
1214 DECLARE_DYNAMIC_CLASS(wxSocketModule)
1215 public:
1216 bool OnInit() {
1217 return GSocket_Init();
1218 }
1219 void OnExit() {
1220 GSocket_Cleanup();
1221 }
1222 };
1223
1224 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule)
1225
1226 #endif
1227 // wxUSE_SOCKETS