]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/socket.cpp
Whole lot of stuff for new wxFileDialog
[wxWidgets.git] / src / common / socket.cpp
... / ...
CommitLineData
1////////////////////////////////////////////////////////////////////////////////
2// Name: socket.cpp
3// Purpose: Socket handler classes
4// Authors: Guilhem Lavaux
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#ifdef __GNUG__
12#pragma implementation "socket.h"
13#endif
14
15// For compilers that support precompilation, includes "wx.h".
16#include "wx/wxprec.h"
17
18#ifdef __BORLANDC__
19#pragma hdrstop
20#endif
21
22#if wxUSE_SOCKETS
23
24/////////////////////////////////////////////////////////////////////////////
25// wxWindows headers
26/////////////////////////////////////////////////////////////////////////////
27#include <wx/defs.h>
28#include <wx/object.h>
29#include <wx/string.h>
30#include <wx/timer.h>
31#include <wx/utils.h>
32#include <wx/log.h>
33
34#include <stdlib.h>
35#include <string.h>
36#include <ctype.h>
37
38/////////////////////////////////////////////////////////////////////////////
39// wxSocket headers
40/////////////////////////////////////////////////////////////////////////////
41#include <wx/module.h>
42#include <wx/sckaddr.h>
43#include <wx/socket.h>
44
45// --------------------------------------------------------------
46// ClassInfos
47// --------------------------------------------------------------
48#if !USE_SHARED_LIBRARY
49IMPLEMENT_CLASS(wxSocketBase, wxObject)
50IMPLEMENT_CLASS(wxSocketServer, wxSocketBase)
51IMPLEMENT_CLASS(wxSocketClient, wxSocketBase)
52IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent)
53#endif
54
55class wxSocketState : public wxObject {
56public:
57 bool notify_state;
58 GSocketEventFlags evt_notify_state;
59 wxSocketBase::wxSockFlags socket_flags;
60 wxSocketBase::wxSockCbk c_callback;
61 char *c_callback_data;
62
63public:
64 wxSocketState() : wxObject() {}
65};
66
67// --------------------------------------------------------------
68// --------- wxSocketBase CONSTRUCTOR ---------------------------
69// --------------------------------------------------------------
70wxSocketBase::wxSocketBase(wxSocketBase::wxSockFlags _flags,
71 wxSocketBase::wxSockType _type) :
72 wxEvtHandler(),
73 m_socket(NULL), m_flags(_flags), m_type(_type),
74 m_neededreq(GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG),
75 m_lcount(0), m_timeout(600),
76 m_unread(NULL), m_unrd_size(0), m_unrd_cur(0),
77 m_cbk(NULL), m_cdata(NULL),
78 m_connected(FALSE), m_notify_state(FALSE), m_id(-1),
79 m_defering(NO_DEFER),
80 m_states()
81{
82}
83
84wxSocketBase::wxSocketBase() :
85 wxEvtHandler(),
86 m_socket(NULL), m_flags(SPEED | WAITALL), m_type(SOCK_UNINIT),
87 m_neededreq(GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG),
88 m_lcount(0), m_timeout(600),
89 m_unread(NULL), m_unrd_size(0), m_unrd_cur(0),
90 m_cbk(NULL), m_cdata(NULL),
91 m_connected(FALSE), m_notify_state(FALSE), m_id(-1),
92 m_defering(NO_DEFER),
93 m_states()
94{
95}
96
97// --------------------------------------------------------------
98// wxSocketBase destructor
99// --------------------------------------------------------------
100
101wxSocketBase::~wxSocketBase()
102{
103 if (m_unread)
104 free(m_unread);
105
106 // At last, close the file descriptor.
107 Close();
108
109 if (m_socket)
110 GSocket_destroy(m_socket);
111}
112
113bool wxSocketBase::Close()
114{
115 if (m_socket)
116 {
117 if (m_notify_state == TRUE)
118 Notify(FALSE);
119
120 // Shutdown the connection.
121 GSocket_Shutdown(m_socket);
122 m_connected = FALSE;
123 }
124
125 return TRUE;
126}
127
128// --------------------------------------------------------------
129// wxSocketBase base IO function
130// --------------------------------------------------------------
131class _wxSocketInternalTimer: public wxTimer {
132 public:
133 int *m_state;
134 unsigned long m_new_val;
135
136 void Notify()
137 {
138 *m_state = m_new_val; // Change the value
139 }
140};
141
142int wxSocketBase::DeferRead(char *buffer, size_t nbytes)
143{
144 GSocketEventFlags old_event_flags;
145 bool old_notify_state;
146 // Timer for timeout
147 _wxSocketInternalTimer timer;
148
149 wxASSERT(m_defering == NO_DEFER);
150
151 // Set the defering mode to READ.
152 m_defering = DEFER_READ;
153
154 // Save the old state.
155 old_event_flags = NeededReq();
156 old_notify_state = m_notify_state;
157
158 // Set the new async flag.
159 SetNotify(GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG);
160 Notify(TRUE);
161
162 // Set the current buffer.
163 m_defer_buffer = buffer;
164 m_defer_nbytes = nbytes;
165 m_defer_timer = &timer;
166
167 timer.m_state = (int *)&m_defer_buffer;
168 timer.m_new_val = 0;
169
170 timer.Start(m_timeout * 1000, FALSE);
171
172 // Wait for buffer completion.
173 while (m_defer_buffer != NULL)
174 wxYield();
175
176 timer.Stop();
177
178 // Restore the old state.
179 Notify(old_notify_state);
180 SetNotify(old_event_flags);
181
182 // Disable defering mode.
183 m_defering = NO_DEFER;
184 m_defer_timer = NULL;
185
186 // Return the number of bytes read from the socket.
187 return nbytes-m_defer_nbytes;
188}
189
190wxSocketBase& wxSocketBase::Read(char* buffer, size_t nbytes)
191{
192 int ret = 1;
193
194 m_lcount = GetPushback(buffer, nbytes, FALSE);
195 nbytes -= m_lcount;
196 buffer += m_lcount;
197
198 if (!m_connected)
199 return *this;
200
201 // If we have got the whole needed buffer or if we don't want to
202 // wait then it returns immediately.
203 if (!nbytes || (m_lcount && !(m_flags & WAITALL)) ) {
204 return *this;
205 }
206
207 if ((m_flags & SPEED) != 0) {
208
209 if ((m_flags & WAITALL) != 0) {
210 while (ret > 0 && nbytes > 0) {
211 ret = GSocket_Read(m_socket, buffer, nbytes);
212 m_lcount += ret;
213 buffer += ret;
214 nbytes -= ret;
215 }
216 // In case the last call was an error ...
217 if (ret < 0)
218 m_lcount ++;
219 } else {
220 ret = GSocket_Read(m_socket, buffer, nbytes);
221 if (ret > 0)
222 m_lcount += ret;
223 }
224
225 } else {
226 ret = DeferRead(buffer, nbytes);
227
228 if (ret > 0)
229 m_lcount += ret;
230 }
231
232 return *this;
233}
234
235wxSocketBase& wxSocketBase::ReadMsg(char* buffer, size_t nbytes)
236{
237 unsigned long len, len2, sig;
238 struct {
239 char sig[4];
240 char len[4];
241 } msg;
242
243 // sig should be an explicit 32-bit unsigned integer; I've seen
244 // compilers in which size_t was actually a 16-bit unsigned integer
245
246 Read((char *)&msg, sizeof(msg));
247 if (m_lcount != sizeof(msg))
248 return *this;
249
250 sig = msg.sig[0] & 0xff;
251 sig |= (size_t)(msg.sig[1] & 0xff) << 8;
252 sig |= (size_t)(msg.sig[2] & 0xff) << 16;
253 sig |= (size_t)(msg.sig[3] & 0xff) << 24;
254
255 if (sig != 0xfeeddead)
256 return *this;
257 len = msg.len[0] & 0xff;
258 len |= (size_t)(msg.len[1] & 0xff) << 8;
259 len |= (size_t)(msg.len[2] & 0xff) << 16;
260 len |= (size_t)(msg.len[3] & 0xff) << 24;
261
262 // len2 is incorrectly computed in the original; this sequence is
263 // the fix
264 if (len > nbytes) {
265 len2 = len - nbytes;
266 len = nbytes;
267 }
268 else
269 len2 = 0;
270
271 // the "len &&" in the following statement is necessary so that
272 // we don't attempt to read (and possibly hang the system)
273 // if the message was zero bytes long
274 if (len && Read(buffer, len).LastCount() != len)
275 return *this;
276 if (len2 && (Read(NULL, len2).LastCount() != len2))
277 return *this;
278 if (Read((char *)&msg, sizeof(msg)).LastCount() != sizeof(msg))
279 return *this;
280
281 sig = msg.sig[0] & 0xff;
282 sig |= (size_t)(msg.sig[1] & 0xff) << 8;
283 sig |= (size_t)(msg.sig[2] & 0xff) << 16;
284 sig |= (size_t)(msg.sig[3] & 0xff) << 24;
285
286// ERROR
287 if (sig != 0xdeadfeed)
288 wxLogDebug(_T("Warning: invalid signature returned to ReadMsg\n"));
289
290 return *this;
291}
292
293wxSocketBase& wxSocketBase::Peek(char* buffer, size_t nbytes)
294{
295 Read(buffer, nbytes);
296 CreatePushbackAfter(buffer, nbytes);
297
298 return *this;
299}
300
301int wxSocketBase::DeferWrite(const char *buffer, size_t nbytes)
302{
303 GSocketEventFlags old_event_flags;
304 bool old_notify_state;
305 // Timer for timeout
306 _wxSocketInternalTimer timer;
307
308 wxASSERT(m_defering == NO_DEFER);
309
310 m_defering = DEFER_WRITE;
311
312 // Save the old state
313 old_event_flags = NeededReq();
314 old_notify_state = m_notify_state;
315
316 SetNotify(GSOCK_OUTPUT_FLAG | GSOCK_LOST_FLAG);
317 Notify(TRUE);
318
319 // Set the current buffer
320 m_defer_buffer = (char *)buffer;
321 m_defer_nbytes = nbytes;
322
323 // Start timer
324 timer.m_state = (int *)&m_defer_buffer;
325 timer.m_new_val = 0;
326
327 m_defer_timer = &timer;
328 timer.Start(m_timeout * 1000, FALSE);
329
330 while (m_defer_buffer != NULL)
331 wxYield();
332
333 // Stop timer
334 m_defer_timer = NULL;
335 timer.Stop();
336
337 // Restore the old state
338 Notify(old_notify_state);
339 SetNotify(old_event_flags);
340
341 m_defering = NO_DEFER;
342
343 return nbytes-m_defer_nbytes;
344}
345
346wxSocketBase& wxSocketBase::Write(const char *buffer, size_t nbytes)
347{
348 int ret;
349
350 if ((m_flags & SPEED) != 0)
351 ret = GSocket_Write(m_socket, buffer, nbytes);
352 else
353 ret = DeferWrite(buffer, nbytes);
354
355 if (ret != -1)
356 m_lcount += ret;
357
358 return *this;
359}
360
361wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, size_t nbytes)
362{
363 struct {
364 char sig[4];
365 char len[4];
366 } msg;
367
368 // warning about 'cast truncates constant value'
369#ifdef __VISUALC__
370 #pragma warning(disable: 4310)
371#endif // __VISUALC__
372
373 msg.sig[0] = (char) 0xad;
374 msg.sig[1] = (char) 0xde;
375 msg.sig[2] = (char) 0xed;
376 msg.sig[3] = (char) 0xfe;
377
378 msg.len[0] = (char) nbytes & 0xff;
379 msg.len[1] = (char) (nbytes >> 8) & 0xff;
380 msg.len[2] = (char) (nbytes >> 16) & 0xff;
381 msg.len[3] = (char) (nbytes >> 24) & 0xff;
382
383 if (Write((char *)&msg, sizeof(msg)).LastCount() < sizeof(msg))
384 return *this;
385 if (Write(buffer, nbytes).LastCount() < nbytes)
386 return *this;
387
388 msg.sig[0] = (char) 0xed;
389 msg.sig[1] = (char) 0xfe;
390 msg.sig[2] = (char) 0xad;
391 msg.sig[3] = (char) 0xde;
392 msg.len[0] = msg.len[1] = msg.len[2] = msg.len[3] = (char) 0;
393 Write((char *)&msg, sizeof(msg));
394
395 return *this;
396
397#ifdef __VISUALC__
398 #pragma warning(default: 4310)
399#endif // __VISUALC__
400}
401
402wxSocketBase& wxSocketBase::Unread(const char *buffer, size_t nbytes)
403{
404 m_lcount = 0;
405 if (nbytes != 0) {
406 CreatePushbackAfter(buffer, nbytes);
407 m_lcount = nbytes;
408 }
409 return *this;
410}
411
412bool wxSocketBase::IsData() const
413{
414 if (!m_socket)
415 return FALSE;
416
417 return (GSocket_DataAvailable(m_socket));
418}
419
420void wxSocketBase::DoDefer(GSocketEvent req_evt)
421{
422 int ret;
423
424 if (req_evt == GSOCK_LOST) {
425 Close();
426 m_defer_buffer = NULL;
427 return;
428 }
429 switch (m_defering) {
430 case DEFER_READ:
431 ret = GSocket_Read(m_socket, m_defer_buffer, m_defer_nbytes);
432 break;
433 case DEFER_WRITE:
434 ret = GSocket_Write(m_socket, m_defer_buffer, m_defer_nbytes);
435 break;
436 default:
437 ret = -1;
438 break;
439 }
440
441 m_defer_nbytes -= ret;
442
443 if (ret < 0)
444 m_defer_nbytes++;
445
446 // If we are waiting for all bytes to be acquired, keep the defering modei
447 // enabled.
448 if ((m_flags & WAITALL) == 0 || m_defer_nbytes == 0 || ret < 0) {
449 m_defer_buffer = NULL;
450 Notify(FALSE);
451 } else {
452 m_defer_buffer += ret;
453 m_defer_timer->Start(m_timeout * 1000, FALSE);
454 }
455}
456
457// ---------------------------------------------------------------------
458// --------- wxSocketBase Discard(): deletes all byte in the input queue
459// ---------------------------------------------------------------------
460void wxSocketBase::Discard()
461{
462#define MAX_BUFSIZE (10*1024)
463 char *my_data = new char[MAX_BUFSIZE];
464 size_t recv_size = MAX_BUFSIZE;
465
466 SaveState();
467 SetFlags(NOWAIT | SPEED);
468
469 while (recv_size == MAX_BUFSIZE)
470 {
471 recv_size = Read(my_data, MAX_BUFSIZE).LastCount();
472 }
473
474 RestoreState();
475 delete [] my_data;
476
477#undef MAX_BUFSIZE
478}
479
480// --------------------------------------------------------------
481// wxSocketBase socket info functions
482// --------------------------------------------------------------
483
484bool wxSocketBase::GetPeer(wxSockAddress& addr_man) const
485{
486 GAddress *peer;
487
488 if (!m_socket)
489 return FALSE;
490
491 peer = GSocket_GetPeer(m_socket);
492 addr_man.SetAddress(peer);
493 GAddress_destroy(peer);
494
495 return TRUE;
496}
497
498bool wxSocketBase::GetLocal(wxSockAddress& addr_man) const
499{
500 GAddress *local;
501
502 if (!m_socket)
503 return FALSE;
504
505 local = GSocket_GetLocal(m_socket);
506 addr_man.SetAddress(local);
507 GAddress_destroy(local);
508
509 return TRUE;
510}
511
512// --------------------------------------------------------------
513// wxSocketBase wait functions
514// --------------------------------------------------------------
515
516void wxSocketBase::SaveState()
517{
518 wxSocketState *state;
519
520 state = new wxSocketState();
521
522 state->notify_state = m_notify_state;
523 state->evt_notify_state = m_neededreq;
524 state->socket_flags = m_flags;
525 state->c_callback = m_cbk;
526 state->c_callback_data = m_cdata;
527
528 m_states.Append(state);
529}
530
531void wxSocketBase::RestoreState()
532{
533 wxNode *node;
534 wxSocketState *state;
535
536 node = m_states.Last();
537 if (!node)
538 return;
539
540 state = (wxSocketState *)node->Data();
541
542 SetFlags(state->socket_flags);
543 m_neededreq = state->evt_notify_state;
544 m_cbk = state->c_callback;
545 m_cdata = state->c_callback_data;
546 Notify(state->notify_state);
547
548 delete node;
549 delete state;
550}
551
552// --------------------------------------------------------------
553// --------- wxSocketBase callback functions --------------------
554// --------------------------------------------------------------
555
556wxSocketBase::wxSockCbk wxSocketBase::Callback(wxSockCbk cbk_)
557{
558 wxSockCbk old_cbk = cbk_;
559
560 m_cbk = cbk_;
561 return old_cbk;
562}
563
564char *wxSocketBase::CallbackData(char *data)
565{
566 char *old_data = m_cdata;
567
568 m_cdata = data;
569 return old_data;
570}
571
572// --------------------------------------------------------------
573// --------- wxSocketBase wait functions ------------------------
574// --------------------------------------------------------------
575
576static void wx_socket_wait(GSocket *socket, GSocketEvent event, char *cdata)
577{
578 int *state = (int *)cdata;
579
580 *state = event;
581}
582
583bool wxSocketBase::_Wait(long seconds, long milliseconds, int type)
584{
585 bool old_notify_state = m_notify_state;
586 int state = -1;
587 _wxSocketInternalTimer timer;
588
589 if (!m_connected || !m_socket)
590 return FALSE;
591
592 // Set the variable to change
593 timer.m_state = &state;
594 timer.m_new_val = GSOCK_MAX_EVENT;
595
596 // Disable the previous handler
597 Notify(FALSE);
598
599 // Set the timeout
600 timer.Start(seconds * 1000 + milliseconds, TRUE);
601 GSocket_SetCallback(m_socket, type, wx_socket_wait, (char *)&state);
602
603 while (state == -1)
604 wxYield();
605
606 GSocket_UnsetCallback(m_socket, type);
607 timer.Stop();
608
609 // Notify will restore automatically the old GSocket flags
610 Notify(old_notify_state);
611
612 return (state != GSOCK_MAX_EVENT);
613}
614
615bool wxSocketBase::Wait(long seconds, long milliseconds)
616{
617 return _Wait(seconds, milliseconds, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
618 GSOCK_CONNECTION_FLAG | GSOCK_LOST_FLAG);
619}
620
621bool wxSocketBase::WaitForRead(long seconds, long milliseconds)
622{
623 return _Wait(seconds, milliseconds, GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG);
624}
625
626bool wxSocketBase::WaitForWrite(long seconds, long milliseconds)
627{
628 return _Wait(seconds, milliseconds, GSOCK_OUTPUT_FLAG | GSOCK_LOST_FLAG);
629}
630
631bool wxSocketBase::WaitForLost(long seconds, long milliseconds)
632{
633 return _Wait(seconds, milliseconds, GSOCK_LOST_FLAG);
634}
635
636// --------------------------------------------------------------
637// --------- wxSocketBase callback management -------------------
638// --------------------------------------------------------------
639
640GSocketEventFlags wxSocketBase::EventToNotify(GSocketEvent evt)
641{
642 switch (evt)
643 {
644 case GSOCK_INPUT:
645 return GSOCK_INPUT_FLAG;
646 case GSOCK_OUTPUT:
647 return GSOCK_OUTPUT_FLAG;
648 case GSOCK_CONNECTION:
649 return GSOCK_CONNECTION_FLAG;
650 case GSOCK_LOST:
651 return GSOCK_LOST_FLAG;
652 default:
653 return 0;
654 }
655 return 0;
656}
657
658void wxSocketBase::SetFlags(wxSockFlags _flags)
659{
660 m_flags = _flags;
661}
662
663wxSocketBase::wxSockFlags wxSocketBase::GetFlags() const
664{
665 return m_flags;
666}
667
668void wxSocketBase::SetNotify(GSocketEventFlags flags)
669{
670 /* Check if server */
671 if (m_type != SOCK_SERVER)
672 flags &= ~GSOCK_CONNECTION_FLAG;
673
674 m_neededreq = flags;
675 if (m_neededreq == 0)
676 Notify(FALSE);
677 else
678 Notify(m_notify_state);
679}
680
681// --------------------------------------------------------------
682// Automatic notifier
683// --------------------------------------------------------------
684
685static void wx_socket_fallback(GSocket *socket, GSocketEvent event, char *cdata)
686{
687 wxSocketBase *sckobj = (wxSocketBase *)cdata;
688
689 sckobj->OnRequest(event);
690}
691
692void wxSocketBase::Notify(bool notify)
693{
694 m_notify_state = notify;
695 if (!m_socket)
696 return;
697
698 GSocket_UnsetCallback(m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
699 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG);
700 if (!notify)
701 return;
702
703 GSocket_SetCallback(m_socket, m_neededreq, wx_socket_fallback, (char *)this);
704}
705
706void wxSocketBase::OnRequest(GSocketEvent req_evt)
707{
708 wxSocketEvent event(m_id);
709 GSocketEventFlags notify = EventToNotify(req_evt);
710
711 if (m_defering != NO_DEFER) {
712 DoDefer(req_evt);
713 return;
714 }
715
716 if ((m_neededreq & notify) == notify) {
717 event.m_socket = this;
718 event.m_skevt = req_evt;
719 ProcessEvent(event);
720 OldOnNotify(req_evt);
721 }
722
723 if (req_evt == GSOCK_LOST)
724 Close();
725}
726
727void wxSocketBase::OldOnNotify(GSocketEvent evt)
728{
729}
730
731// --------------------------------------------------------------
732// --------- wxSocketBase functions [Callback, CallbackData] ----
733// --------------------------------------------------------------
734
735void wxSocketBase::SetEventHandler(wxEvtHandler& h_evt, int id)
736{
737 SetNextHandler(&h_evt);
738 m_id = id;
739}
740
741// --------------------------------------------------------------
742// --------- wxSocketBase pushback library ----------------------
743// --------------------------------------------------------------
744
745void wxSocketBase::CreatePushbackAfter(const char *buffer, size_t size)
746{
747 char *curr_pos;
748
749 if (m_unread != NULL)
750 m_unread = (char *) realloc(m_unread, m_unrd_size+size);
751 else
752 m_unread = (char *) malloc(size);
753
754 curr_pos = m_unread + m_unrd_size;
755
756 memcpy(curr_pos, buffer, size);
757 m_unrd_size += size;
758}
759
760void wxSocketBase::CreatePushbackBefore(const char *buffer, size_t size)
761{
762 if (m_unread == NULL)
763 m_unread = (char *)malloc(size);
764 else {
765 char *tmp;
766
767 tmp = (char *)malloc(m_unrd_size + size);
768 memcpy(tmp+size, m_unread, m_unrd_size);
769 free(m_unread);
770
771 m_unread = tmp;
772 }
773
774 m_unrd_size += size;
775
776 memcpy(m_unread, buffer, size);
777}
778
779size_t wxSocketBase::GetPushback(char *buffer, size_t size, bool peek)
780{
781 if (!m_unrd_size)
782 return 0;
783
784 if (size > (m_unrd_size-m_unrd_cur))
785 size = m_unrd_size-m_unrd_cur;
786 memcpy(buffer, (m_unread+m_unrd_cur), size);
787
788 if (!peek) {
789 m_unrd_cur += size;
790 if (m_unrd_size == m_unrd_cur) {
791 free(m_unread);
792 m_unread = NULL;
793 m_unrd_size = 0;
794 m_unrd_cur = 0;
795 }
796 }
797
798 return size;
799}
800
801// --------------------------------------------------------------
802// wxSocketServer
803// --------------------------------------------------------------
804
805wxSocketServer::wxSocketServer(wxSockAddress& addr_man,
806 wxSockFlags flags) :
807 wxSocketBase(flags, SOCK_SERVER)
808{
809 m_socket = GSocket_new();
810
811 if (!m_socket)
812 return;
813
814 GSocket_SetLocal(m_socket, addr_man.GetAddress());
815 if (GSocket_SetServer(m_socket) != GSOCK_NOERROR) {
816 GSocket_destroy(m_socket);
817 m_socket = NULL;
818 return;
819 }
820
821 Notify(TRUE);
822}
823
824// --------------------------------------------------------------
825// wxSocketServer Accept
826// --------------------------------------------------------------
827
828bool wxSocketServer::AcceptWith(wxSocketBase& sock)
829{
830 GSocket *child_socket;
831
832 child_socket = GSocket_WaitConnection(m_socket);
833
834 sock.m_type = SOCK_INTERNAL;
835 sock.m_socket = child_socket;
836 sock.m_connected = TRUE;
837
838 return TRUE;
839}
840
841wxSocketBase *wxSocketServer::Accept()
842{
843 wxSocketBase* sock = new wxSocketBase();
844
845 sock->SetFlags((wxSockFlags)m_flags);
846
847 if (!AcceptWith(*sock))
848 return NULL;
849
850 return sock;
851}
852
853// --------------------------------------------------------------
854// wxSocketClient
855// --------------------------------------------------------------
856
857// --------- wxSocketClient CONSTRUCTOR -------------------------
858// --------------------------------------------------------------
859wxSocketClient::wxSocketClient(wxSockFlags _flags) :
860 wxSocketBase(_flags, SOCK_CLIENT)
861{
862}
863
864// --------------------------------------------------------------
865// --------- wxSocketClient DESTRUCTOR --------------------------
866// --------------------------------------------------------------
867wxSocketClient::~wxSocketClient()
868{
869}
870
871// --------------------------------------------------------------
872// --------- wxSocketClient Connect functions -------------------
873// --------------------------------------------------------------
874bool wxSocketClient::Connect(wxSockAddress& addr_man, bool WXUNUSED(wait) )
875{
876 if (IsConnected())
877 Close();
878
879 // This should never happen.
880 if (m_socket)
881 GSocket_destroy(m_socket);
882
883 // Initializes all socket stuff ...
884 // --------------------------------
885 m_socket = GSocket_new();
886
887 if (!m_socket)
888 return FALSE;
889
890 m_connected = FALSE;
891
892 // Update the flags of m_socket.
893 SetFlags(m_flags);
894 GSocket_SetPeer(m_socket, addr_man.GetAddress());
895 if (GSocket_Connect(m_socket, GSOCK_STREAMED) != GSOCK_NOERROR)
896 return FALSE;
897
898 // Enables bg events.
899 // ------------------
900 Notify(TRUE);
901
902 m_connected = TRUE;
903 return TRUE;
904}
905
906bool wxSocketClient::WaitOnConnect(long seconds, long microseconds)
907{
908 int ret = _Wait(seconds, microseconds, GSOCK_CONNECTION_FLAG | GSOCK_LOST_FLAG);
909
910 if (ret)
911 m_connected = TRUE;
912
913 return m_connected;
914}
915
916void wxSocketClient::OnRequest(GSocketEvent evt)
917{
918 if (evt == GSOCK_CONNECTION)
919 {
920 if (m_connected)
921 {
922 m_neededreq &= ~GSOCK_CONNECTION_FLAG;
923 return;
924 }
925 m_connected = TRUE;
926 return;
927 }
928 wxSocketBase::OnRequest(evt);
929}
930
931// --------------------------------------------------------------
932// wxSocketEvent
933// --------------------------------------------------------------
934
935wxSocketEvent::wxSocketEvent(int id)
936 : wxEvent(id)
937{
938 wxEventType type = (wxEventType)wxEVT_SOCKET;
939
940 SetEventType(type);
941}
942
943void wxSocketEvent::CopyObject(wxObject& obj_d) const
944{
945 wxSocketEvent *event = (wxSocketEvent *)&obj_d;
946
947 wxEvent::CopyObject(obj_d);
948
949 event->m_skevt = m_skevt;
950 event->m_socket = m_socket;
951}
952
953// --------------------------------------------------------------------------
954// wxSocketModule
955// --------------------------------------------------------------------------
956class WXDLLEXPORT wxSocketModule: public wxModule {
957 DECLARE_DYNAMIC_CLASS(wxSocketModule)
958 public:
959 bool OnInit() {
960 return GSocket_Init();
961 }
962 void OnExit() {
963 GSocket_Cleanup();
964 }
965};
966
967IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule)
968
969#endif
970 // wxUSE_SOCKETS