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