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