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