]> git.saurik.com Git - wxWidgets.git/blob - src/common/socket.cpp
Updated wxSocket documentation
[wxWidgets.git] / src / common / socket.cpp
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
49 IMPLEMENT_CLASS(wxSocketBase, wxObject)
50 IMPLEMENT_CLASS(wxSocketServer, wxSocketBase)
51 IMPLEMENT_CLASS(wxSocketClient, wxSocketBase)
52 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent)
53 #endif
54
55 class wxSocketState : public wxObject {
56 public:
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
63 public:
64 wxSocketState() : wxObject() {}
65 };
66
67 // --------------------------------------------------------------
68 // --------- wxSocketBase CONSTRUCTOR ---------------------------
69 // --------------------------------------------------------------
70 wxSocketBase::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
84 wxSocketBase::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
101 wxSocketBase::~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
113 bool 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 // --------------------------------------------------------------
131 class _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
142 int wxSocketBase::DeferRead(char *buffer, wxUint32 nbytes)
143 {
144 wxSocketEventFlags 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
190 wxSocketBase& wxSocketBase::Read(char* buffer, wxUint32 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
235 wxSocketBase& wxSocketBase::ReadMsg(char* buffer, wxUint32 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 wxUint32 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 |= (wxUint32)(msg.sig[1] & 0xff) << 8;
252 sig |= (wxUint32)(msg.sig[2] & 0xff) << 16;
253 sig |= (wxUint32)(msg.sig[3] & 0xff) << 24;
254
255 if (sig != 0xfeeddead)
256 return *this;
257 len = msg.len[0] & 0xff;
258 len |= (wxUint32)(msg.len[1] & 0xff) << 8;
259 len |= (wxUint32)(msg.len[2] & 0xff) << 16;
260 len |= (wxUint32)(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 |= (wxUint32)(msg.sig[1] & 0xff) << 8;
283 sig |= (wxUint32)(msg.sig[2] & 0xff) << 16;
284 sig |= (wxUint32)(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
293 wxSocketBase& wxSocketBase::Peek(char* buffer, wxUint32 nbytes)
294 {
295 Read(buffer, nbytes);
296 CreatePushbackAfter(buffer, nbytes);
297
298 return *this;
299 }
300
301 int wxSocketBase::DeferWrite(const char *buffer, wxUint32 nbytes)
302 {
303 wxSocketEventFlags 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
346 wxSocketBase& wxSocketBase::Write(const char *buffer, wxUint32 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
361 wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, wxUint32 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
402 wxSocketBase& wxSocketBase::Unread(const char *buffer, wxUint32 nbytes)
403 {
404 m_lcount = 0;
405 if (nbytes != 0) {
406 CreatePushbackAfter(buffer, nbytes);
407 m_lcount = nbytes;
408 }
409 return *this;
410 }
411
412 bool wxSocketBase::IsData() const
413 {
414 if (!m_socket)
415 return FALSE;
416
417 return (GSocket_DataAvailable(m_socket));
418 }
419
420 void wxSocketBase::DoDefer(wxSocketNotify req_evt)
421 {
422 int ret;
423
424 if (req_evt == wxSOCKET_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 // ---------------------------------------------------------------------
460 void wxSocketBase::Discard()
461 {
462 #define MAX_BUFSIZE (10*1024)
463 char *my_data = new char[MAX_BUFSIZE];
464 wxUint32 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
484 bool 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
498 bool 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
516 void 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
531 void 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
556 wxSocketBase::wxSockCbk wxSocketBase::Callback(wxSockCbk cbk_)
557 {
558 wxSockCbk old_cbk = cbk_;
559
560 m_cbk = cbk_;
561 return old_cbk;
562 }
563
564 char *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
576 static void wx_socket_wait(GSocket *socket, GSocketEvent event, char *cdata)
577 {
578 int *state = (int *)cdata;
579
580 *state = event;
581 }
582
583 bool 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
615 bool 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
621 bool wxSocketBase::WaitForRead(long seconds, long milliseconds)
622 {
623 return _Wait(seconds, milliseconds, GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG);
624 }
625
626 bool wxSocketBase::WaitForWrite(long seconds, long milliseconds)
627 {
628 return _Wait(seconds, milliseconds, GSOCK_OUTPUT_FLAG | GSOCK_LOST_FLAG);
629 }
630
631 bool wxSocketBase::WaitForLost(long seconds, long milliseconds)
632 {
633 return _Wait(seconds, milliseconds, GSOCK_LOST_FLAG);
634 }
635
636 // --------------------------------------------------------------
637 // --------- wxSocketBase callback management -------------------
638 // --------------------------------------------------------------
639
640 wxSocketEventFlags wxSocketBase::EventToNotify(wxSocketNotify 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
658 void wxSocketBase::SetFlags(wxSockFlags _flags)
659 {
660 m_flags = _flags;
661 }
662
663 wxSocketBase::wxSockFlags wxSocketBase::GetFlags() const
664 {
665 return m_flags;
666 }
667
668 void wxSocketBase::SetNotify(wxSocketEventFlags 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
685 static void wx_socket_fallback(GSocket *socket, GSocketEvent event, char *cdata)
686 {
687 wxSocketBase *sckobj = (wxSocketBase *)cdata;
688
689 sckobj->OnRequest((wxSocketNotify)event);
690 }
691
692 void 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
706 void wxSocketBase::OnRequest(wxSocketNotify req_evt)
707 {
708 wxSocketEvent event(m_id);
709 wxSocketEventFlags 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 == wxSOCKET_LOST)
724 Close();
725 }
726
727 void wxSocketBase::OldOnNotify(wxSocketNotify evt)
728 {
729 }
730
731 // --------------------------------------------------------------
732 // --------- wxSocketBase functions [Callback, CallbackData] ----
733 // --------------------------------------------------------------
734
735 void 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
745 void wxSocketBase::CreatePushbackAfter(const char *buffer, wxUint32 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
760 void wxSocketBase::CreatePushbackBefore(const char *buffer, wxUint32 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
779 wxUint32 wxSocketBase::GetPushback(char *buffer, wxUint32 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
805 wxSocketServer::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
828 bool 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
841 wxSocketBase *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 // --------------------------------------------------------------
859 wxSocketClient::wxSocketClient(wxSockFlags _flags) :
860 wxSocketBase(_flags, SOCK_CLIENT)
861 {
862 }
863
864 // --------------------------------------------------------------
865 // --------- wxSocketClient DESTRUCTOR --------------------------
866 // --------------------------------------------------------------
867 wxSocketClient::~wxSocketClient()
868 {
869 }
870
871 // --------------------------------------------------------------
872 // --------- wxSocketClient Connect functions -------------------
873 // --------------------------------------------------------------
874 bool 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
906 bool 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
916 void wxSocketClient::OnRequest(wxSocketNotify evt)
917 {
918 if ((GSocketEvent)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
935 wxSocketEvent::wxSocketEvent(int id)
936 : wxEvent(id)
937 {
938 wxEventType type = (wxEventType)wxEVT_SOCKET;
939
940 SetEventType(type);
941 }
942
943 void 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 // --------------------------------------------------------------------------
956 class 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
967 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule)
968
969 #endif
970 // wxUSE_SOCKETS