home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / common / socket.cpp < prev    next >
C/C++ Source or Header  |  2002-07-29  |  34KB  |  1,327 lines

  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: socket.cpp,v 1.105 2002/07/29 04:13:24 RL Exp $
  9. // License:    see wxWindows license
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. // ==========================================================================
  13. // Declarations
  14. // ==========================================================================
  15.  
  16. #ifdef __GNUG__
  17. #pragma implementation "socket.h"
  18. #endif
  19.  
  20. // For compilers that support precompilation, includes "wx.h".
  21. #include "wx/wxprec.h"
  22.  
  23. #ifdef __BORLANDC__
  24. #pragma hdrstop
  25. #endif
  26.  
  27. #if wxUSE_SOCKETS
  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. #include "wx/event.h"
  39.  
  40. #if wxUSE_GUI
  41.   #include "wx/gdicmn.h"      // for wxPendingDelete
  42. #endif // wxUSE_GUI
  43.  
  44. #include "wx/sckaddr.h"
  45. #include "wx/socket.h"
  46.  
  47. // --------------------------------------------------------------------------
  48. // macros and constants
  49. // --------------------------------------------------------------------------
  50.  
  51. // discard buffer
  52. #define MAX_DISCARD_SIZE (10 * 1024)
  53.  
  54. // what to do within waits: in wxBase we don't do anything as we don't have
  55. // the event loop anyhow (for now). In GUI apps we have 2 cases: from the main
  56. // thread itself we have to call wxYield() to let the events (including the
  57. // GUI events and the low-level (not wxWindows) events from GSocket) be
  58. // processed. From another thread it is enough to just call wxThread::Yield()
  59. // which will give away the rest of our time slice: the explanation is that
  60. // the events will be processed by the main thread anyhow, without calling
  61. // wxYield(), but we don't want to eat the CPU time uselessly while sitting
  62. // in the loop waiting for the data
  63. #if wxUSE_GUI
  64.     #if wxUSE_THREADS
  65.         #define PROCESS_EVENTS()        \
  66.         {                               \
  67.             if ( wxThread::IsMain() )   \
  68.                 wxYield();              \
  69.             else                        \
  70.                 wxThread::Yield();      \
  71.         }
  72.     #else // !wxUSE_THREADS
  73.         #define PROCESS_EVENTS() wxYield()
  74.     #endif // wxUSE_THREADS/!wxUSE_THREADS
  75. #else // !wxUSE_GUI
  76.     #define PROCESS_EVENTS()
  77. #endif // wxUSE_GUI/!wxUSE_GUI
  78.  
  79. #define wxTRACE_Socket _T("wxSocket")
  80.  
  81. // --------------------------------------------------------------------------
  82. // wxWin macros
  83. // --------------------------------------------------------------------------
  84.  
  85. IMPLEMENT_CLASS(wxSocketBase, wxObject)
  86. IMPLEMENT_CLASS(wxSocketServer, wxSocketBase)
  87. IMPLEMENT_CLASS(wxSocketClient, wxSocketBase)
  88. IMPLEMENT_CLASS(wxDatagramSocket, wxSocketBase)
  89. IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent)
  90.  
  91. // --------------------------------------------------------------------------
  92. // private classes
  93. // --------------------------------------------------------------------------
  94.  
  95. class wxSocketState : public wxObject
  96. {
  97. public:
  98.   wxSocketFlags            m_flags;
  99.   wxSocketEventFlags       m_eventmask;
  100.   bool                     m_notify;
  101.   void                    *m_clientData;
  102. #if WXWIN_COMPATIBILITY
  103.   wxSocketBase::wxSockCbk  m_cbk;
  104.   char                    *m_cdata;
  105. #endif // WXWIN_COMPATIBILITY
  106.  
  107. public:
  108.   wxSocketState() : wxObject() {}
  109. };
  110.  
  111. // ==========================================================================
  112. // wxSocketBase
  113. // ==========================================================================
  114.  
  115. // --------------------------------------------------------------------------
  116. // Initialization and shutdown
  117. // --------------------------------------------------------------------------
  118.  
  119. // FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses
  120. //           to m_countInit with a crit section
  121. size_t wxSocketBase::m_countInit = 0;
  122.  
  123. bool wxSocketBase::IsInitialized()
  124. {
  125.     return m_countInit > 0;
  126. }
  127.  
  128. bool wxSocketBase::Initialize()
  129. {
  130.     if ( !m_countInit++ )
  131.     {
  132.         if ( !GSocket_Init() )
  133.         {
  134.             m_countInit--;
  135.  
  136.             return FALSE;
  137.         }
  138.     }
  139.  
  140.     return TRUE;
  141. }
  142.  
  143. void wxSocketBase::Shutdown()
  144. {
  145.     // we should be initialized
  146.     wxASSERT_MSG( m_countInit, _T("extra call to Shutdown()") );
  147.     if ( !--m_countInit )
  148.     {
  149.         GSocket_Cleanup();
  150.     }
  151. }
  152.  
  153. // --------------------------------------------------------------------------
  154. // Ctor and dtor
  155. // --------------------------------------------------------------------------
  156.  
  157. void wxSocketBase::Init()
  158. {
  159.   m_socket       = NULL;
  160.   m_type         = wxSOCKET_UNINIT;
  161.  
  162.   // state
  163.   m_flags        = 0;
  164.   m_connected    =
  165.   m_establishing =
  166.   m_reading      =
  167.   m_writing      =
  168.   m_error        = FALSE;
  169.   m_lcount       = 0;
  170.   m_timeout      = 600;
  171.   m_beingDeleted = FALSE;
  172.  
  173.   // pushback buffer
  174.   m_unread       = NULL;
  175.   m_unrd_size    = 0;
  176.   m_unrd_cur     = 0;
  177.  
  178.   // events
  179.   m_id           = -1;
  180.   m_handler      = NULL;
  181.   m_clientData   = NULL;
  182.   m_notify       = FALSE;
  183.   m_eventmask    = 0;
  184. #if WXWIN_COMPATIBILITY
  185.   m_cbk          = NULL;
  186.   m_cdata        = NULL;
  187. #endif // WXWIN_COMPATIBILITY
  188.  
  189.   if ( !IsInitialized() )
  190.   {
  191.       // this Initialize() will be undone by wxSocketModule::OnExit(), all the
  192.       // other calls to it should be matched by a call to Shutdown()
  193.       Initialize();
  194.   }
  195. }
  196.  
  197. wxSocketBase::wxSocketBase()
  198. {
  199.   Init();
  200. }
  201.  
  202. wxSocketBase::wxSocketBase(wxSocketFlags flags, wxSocketType type)
  203. {
  204.   Init();
  205.  
  206.   m_flags = flags;
  207.   m_type  = type;
  208. }
  209.  
  210. wxSocketBase::~wxSocketBase()
  211. {
  212.   // Just in case the app called Destroy() *and* then deleted
  213.   // the socket immediately: don't leave dangling pointers.
  214. #if wxUSE_GUI
  215.   wxPendingDelete.DeleteObject(this);
  216. #endif
  217.  
  218.   // Shutdown and close the socket
  219.   if (!m_beingDeleted)
  220.     Close();
  221.  
  222.   // Destroy the GSocket object
  223.   if (m_socket)
  224.     GSocket_destroy(m_socket);
  225.  
  226.   // Free the pushback buffer
  227.   if (m_unread)
  228.     free(m_unread);
  229. }
  230.  
  231. bool wxSocketBase::Destroy()
  232. {
  233.   // Delayed destruction: the socket will be deleted during the next
  234.   // idle loop iteration. This ensures that all pending events have
  235.   // been processed.
  236.   m_beingDeleted = TRUE;
  237.  
  238.   // Shutdown and close the socket
  239.   Close();
  240.  
  241.   // Supress events from now on
  242.   Notify(FALSE);
  243.  
  244. #if wxUSE_GUI
  245.   if ( !wxPendingDelete.Member(this) )
  246.     wxPendingDelete.Append(this);
  247. #else
  248.   delete this;
  249. #endif
  250.  
  251.   return TRUE;
  252. }
  253.  
  254. // --------------------------------------------------------------------------
  255. // Basic IO calls
  256. // --------------------------------------------------------------------------
  257.  
  258. // The following IO operations update m_error and m_lcount:
  259. // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
  260. //
  261. // TODO: Should Connect, Accept and AcceptWith update m_error?
  262.  
  263. bool wxSocketBase::Close()
  264. {
  265.   // Interrupt pending waits
  266.   InterruptWait();
  267.  
  268.   if (m_socket)
  269.   {
  270.     // Disable callbacks
  271.     GSocket_UnsetCallback(m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
  272.                                     GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG);
  273.  
  274.     // Shutdown the connection
  275.     GSocket_Shutdown(m_socket);
  276.   }
  277.  
  278.   m_connected = FALSE;
  279.   m_establishing = FALSE;
  280.   return TRUE;
  281. }
  282.  
  283. wxSocketBase& wxSocketBase::Read(void* buffer, wxUint32 nbytes)
  284. {
  285.   // Mask read events
  286.   m_reading = TRUE;
  287.  
  288.   m_lcount = _Read(buffer, nbytes);
  289.  
  290.   // If in wxSOCKET_WAITALL mode, all bytes should have been read.
  291.   if (m_flags & wxSOCKET_WAITALL)
  292.     m_error = (m_lcount != nbytes);
  293.   else
  294.     m_error = (m_lcount == 0);
  295.  
  296.   // Allow read events from now on
  297.   m_reading = FALSE;
  298.  
  299.   return *this;
  300. }
  301.  
  302. wxUint32 wxSocketBase::_Read(void* buffer, wxUint32 nbytes)
  303. {
  304.   int total;
  305.   int ret = 1;
  306.  
  307.   // Try the pushback buffer first
  308.   total = GetPushback(buffer, nbytes, FALSE);
  309.   nbytes -= total;
  310.   buffer  = (char *)buffer + total;
  311.  
  312.   // Return now in one of the following cases:
  313.   // - the socket is invalid,
  314.   // - we got all the data,
  315.   // - we got *some* data and we are not using wxSOCKET_WAITALL.
  316.   if ( !m_socket ||
  317.        !nbytes ||
  318.        ((total != 0) && !(m_flags & wxSOCKET_WAITALL)) )
  319.     return total;
  320.  
  321.   // Possible combinations (they are checked in this order)
  322.   // wxSOCKET_NOWAIT
  323.   // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
  324.   // wxSOCKET_BLOCK
  325.   // wxSOCKET_NONE
  326.   //
  327.   if (m_flags & wxSOCKET_NOWAIT)
  328.   {
  329.     GSocket_SetNonBlocking(m_socket, 1);
  330.     ret = GSocket_Read(m_socket, (char *)buffer, nbytes);
  331.     GSocket_SetNonBlocking(m_socket, 0);
  332.  
  333.     if (ret > 0)
  334.       total += ret;
  335.   }
  336.   else
  337.   {
  338.     bool more = TRUE;
  339.  
  340.     while (more)
  341.     {
  342.       if ( !(m_flags & wxSOCKET_BLOCK) && !WaitForRead() )
  343.         break;
  344.  
  345.       ret = GSocket_Read(m_socket, (char *)buffer, nbytes);
  346.  
  347.       if (ret > 0)
  348.       {
  349.         total  += ret;
  350.         nbytes -= ret;
  351.         buffer  = (char *)buffer + ret;
  352.       }
  353.  
  354.       // If we got here and wxSOCKET_WAITALL is not set, we can leave
  355.       // now. Otherwise, wait until we recv all the data or until there
  356.       // is an error.
  357.       //
  358.       more = (ret > 0 && nbytes > 0 && (m_flags & wxSOCKET_WAITALL));
  359.     }
  360.   }
  361.  
  362.   return total;
  363. }
  364.  
  365. wxSocketBase& wxSocketBase::ReadMsg(void* buffer, wxUint32 nbytes)
  366. {
  367.   wxUint32 len, len2, sig, total;
  368.   bool error;
  369.   int old_flags;
  370.   struct
  371.   {
  372.     unsigned char sig[4];
  373.     unsigned char len[4];
  374.   } msg;
  375.  
  376.   // Mask read events
  377.   m_reading = TRUE;
  378.  
  379.   total = 0;
  380.   error = TRUE;
  381.   old_flags = m_flags;
  382.   SetFlags((m_flags & wxSOCKET_BLOCK) | wxSOCKET_WAITALL);
  383.  
  384.   if (_Read(&msg, sizeof(msg)) != sizeof(msg))
  385.     goto exit;
  386.  
  387.   sig = (wxUint32)msg.sig[0];
  388.   sig |= (wxUint32)(msg.sig[1] << 8);
  389.   sig |= (wxUint32)(msg.sig[2] << 16);
  390.   sig |= (wxUint32)(msg.sig[3] << 24);
  391.  
  392.   if (sig != 0xfeeddead)
  393.   {
  394.     wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
  395.     goto exit;
  396.   }
  397.  
  398.   len = (wxUint32)msg.len[0];
  399.   len |= (wxUint32)(msg.len[1] << 8);
  400.   len |= (wxUint32)(msg.len[2] << 16);
  401.   len |= (wxUint32)(msg.len[3] << 24);
  402.  
  403.   if (len > nbytes)
  404.   {
  405.     len2 = len - nbytes;
  406.     len = nbytes;
  407.   }
  408.   else
  409.     len2 = 0;
  410.  
  411.   // Don't attemp to read if the msg was zero bytes long.
  412.   if (len)
  413.   {
  414.     total = _Read(buffer, len);
  415.  
  416.     if (total != len)
  417.       goto exit;
  418.   }
  419.   if (len2)
  420.   {
  421.     char *discard_buffer = new char[MAX_DISCARD_SIZE];
  422.     long discard_len;
  423.  
  424.     // NOTE: discarded bytes don't add to m_lcount.
  425.     do
  426.     {
  427.       discard_len = ((len2 > MAX_DISCARD_SIZE)? MAX_DISCARD_SIZE : len2);
  428.       discard_len = _Read(discard_buffer, (wxUint32)discard_len);
  429.       len2 -= (wxUint32)discard_len;
  430.     }
  431.     while ((discard_len > 0) && len2);
  432.  
  433.     delete [] discard_buffer;
  434.  
  435.     if (len2 != 0)
  436.       goto exit;
  437.   }
  438.   if (_Read(&msg, sizeof(msg)) != sizeof(msg))
  439.     goto exit;
  440.  
  441.   sig = (wxUint32)msg.sig[0];
  442.   sig |= (wxUint32)(msg.sig[1] << 8);
  443.   sig |= (wxUint32)(msg.sig[2] << 16);
  444.   sig |= (wxUint32)(msg.sig[3] << 24);
  445.  
  446.   if (sig != 0xdeadfeed)
  447.   {
  448.     wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
  449.     goto exit;
  450.   }
  451.  
  452.   // everything was OK
  453.   error = FALSE;
  454.  
  455. exit:
  456.   m_error = error;
  457.   m_lcount = total;
  458.   m_reading = FALSE;
  459.   SetFlags(old_flags);
  460.  
  461.   return *this;
  462. }
  463.  
  464. wxSocketBase& wxSocketBase::Peek(void* buffer, wxUint32 nbytes)
  465. {
  466.   // Mask read events
  467.   m_reading = TRUE;
  468.  
  469.   m_lcount = _Read(buffer, nbytes);
  470.   Pushback(buffer, m_lcount);
  471.  
  472.   // If in wxSOCKET_WAITALL mode, all bytes should have been read.
  473.   if (m_flags & wxSOCKET_WAITALL)
  474.     m_error = (m_lcount != nbytes);
  475.   else
  476.     m_error = (m_lcount == 0);
  477.  
  478.   // Allow read events again
  479.   m_reading = FALSE;
  480.  
  481.   return *this;
  482. }
  483.  
  484. wxSocketBase& wxSocketBase::Write(const void *buffer, wxUint32 nbytes)
  485. {
  486.   // Mask write events
  487.   m_writing = TRUE;
  488.  
  489.   m_lcount = _Write(buffer, nbytes);
  490.  
  491.   // If in wxSOCKET_WAITALL mode, all bytes should have been written.
  492.   if (m_flags & wxSOCKET_WAITALL)
  493.     m_error = (m_lcount != nbytes);
  494.   else
  495.     m_error = (m_lcount == 0);
  496.  
  497.   // Allow write events again
  498.   m_writing = FALSE;
  499.  
  500.   return *this;
  501. }
  502.  
  503. wxUint32 wxSocketBase::_Write(const void *buffer, wxUint32 nbytes)
  504. {
  505.   wxUint32 total = 0;
  506.   int ret = 1;
  507.  
  508.   // If the socket is invalid or parameters are ill, return immediately
  509.   if (!m_socket || !buffer || !nbytes)
  510.     return 0;
  511.  
  512.   // Possible combinations (they are checked in this order)
  513.   // wxSOCKET_NOWAIT
  514.   // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
  515.   // wxSOCKET_BLOCK
  516.   // wxSOCKET_NONE
  517.   //
  518.   if (m_flags & wxSOCKET_NOWAIT)
  519.   {
  520.     GSocket_SetNonBlocking(m_socket, 1);
  521.     ret = GSocket_Write(m_socket, (const char *)buffer, nbytes);
  522.     GSocket_SetNonBlocking(m_socket, 0);
  523.  
  524.     if (ret > 0)
  525.       total = ret;
  526.   }
  527.   else
  528.   {
  529.     bool more = TRUE;
  530.  
  531.     while (more)
  532.     {
  533.       if ( !(m_flags & wxSOCKET_BLOCK) && !WaitForWrite() )
  534.         break;
  535.  
  536.       ret = GSocket_Write(m_socket, (const char *)buffer, nbytes);
  537.  
  538.       if (ret > 0)
  539.       {
  540.         total  += ret;
  541.         nbytes -= ret;
  542.         buffer  = (const char *)buffer + ret;
  543.       }
  544.  
  545.       // If we got here and wxSOCKET_WAITALL is not set, we can leave
  546.       // now. Otherwise, wait until we send all the data or until there
  547.       // is an error.
  548.       //
  549.       more = (ret > 0 && nbytes > 0 && (m_flags & wxSOCKET_WAITALL));
  550.     }
  551.   }
  552.  
  553.   return total;
  554. }
  555.  
  556. wxSocketBase& wxSocketBase::WriteMsg(const void *buffer, wxUint32 nbytes)
  557. {
  558.   wxUint32 total;
  559.   bool error;
  560.   int old_flags;
  561.   struct
  562.   {
  563.     unsigned char sig[4];
  564.     unsigned char len[4];
  565.   } msg;
  566.  
  567.   // Mask write events
  568.   m_writing = TRUE;
  569.  
  570.   error = TRUE;
  571.   total = 0;
  572.   old_flags = m_flags;
  573.   SetFlags((m_flags & wxSOCKET_BLOCK) | wxSOCKET_WAITALL);
  574.  
  575.   msg.sig[0] = (unsigned char) 0xad;
  576.   msg.sig[1] = (unsigned char) 0xde;
  577.   msg.sig[2] = (unsigned char) 0xed;
  578.   msg.sig[3] = (unsigned char) 0xfe;
  579.  
  580.   msg.len[0] = (unsigned char) (nbytes & 0xff);
  581.   msg.len[1] = (unsigned char) ((nbytes >> 8) & 0xff);
  582.   msg.len[2] = (unsigned char) ((nbytes >> 16) & 0xff);
  583.   msg.len[3] = (unsigned char) ((nbytes >> 24) & 0xff);
  584.  
  585.   if (_Write(&msg, sizeof(msg)) < sizeof(msg))
  586.     goto exit;
  587.  
  588.   total = _Write(buffer, nbytes);
  589.  
  590.   if (total < nbytes)
  591.     goto exit;
  592.  
  593.   msg.sig[0] = (unsigned char) 0xed;
  594.   msg.sig[1] = (unsigned char) 0xfe;
  595.   msg.sig[2] = (unsigned char) 0xad;
  596.   msg.sig[3] = (unsigned char) 0xde;
  597.   msg.len[0] = msg.len[1] = msg.len[2] = msg.len[3] = (char) 0;
  598.  
  599.   if ((_Write(&msg, sizeof(msg))) < sizeof(msg))
  600.     goto exit;
  601.  
  602.   // everything was OK
  603.   error = FALSE;
  604.  
  605. exit:
  606.   m_error = error;
  607.   m_lcount = total;
  608.   m_writing = FALSE;
  609.  
  610.   return *this;
  611. }
  612.  
  613. wxSocketBase& wxSocketBase::Unread(const void *buffer, wxUint32 nbytes)
  614. {
  615.   if (nbytes != 0)
  616.     Pushback(buffer, nbytes);
  617.  
  618.   m_error = FALSE;
  619.   m_lcount = nbytes;
  620.  
  621.   return *this;
  622. }
  623.  
  624. wxSocketBase& wxSocketBase::Discard()
  625. {
  626.   int old_flags;
  627.   char *buffer = new char[MAX_DISCARD_SIZE];
  628.   wxUint32 ret;
  629.   wxUint32 total = 0;
  630.  
  631.   // Mask read events
  632.   m_reading = TRUE;
  633.  
  634.   old_flags = m_flags;
  635.   SetFlags(wxSOCKET_NOWAIT);
  636.  
  637.   do
  638.   {
  639.     ret = _Read(buffer, MAX_DISCARD_SIZE);
  640.     total += ret;
  641.   }
  642.   while (ret == MAX_DISCARD_SIZE);
  643.  
  644.   delete[] buffer;
  645.   m_lcount = total;
  646.   m_error  = FALSE;
  647.  
  648.   // Allow read events again
  649.   m_reading = FALSE;
  650.  
  651.   return *this;
  652. }
  653.  
  654. // --------------------------------------------------------------------------
  655. // Wait functions
  656. // --------------------------------------------------------------------------
  657.  
  658. // All Wait functions poll the socket using GSocket_Select() to
  659. // check for the specified combination of conditions, until one
  660. // of these conditions become true, an error occurs, or the
  661. // timeout elapses. The polling loop calls PROCESS_EVENTS(), so
  662. // this won't block the GUI.
  663.  
  664. bool wxSocketBase::_Wait(long seconds,
  665.                          long milliseconds,
  666.                          wxSocketEventFlags flags)
  667. {
  668.   GSocketEventFlags result;
  669.   long timeout;
  670.  
  671.   // Set this to TRUE to interrupt ongoing waits
  672.   m_interrupt = FALSE;
  673.  
  674.   // Check for valid socket
  675.   if (!m_socket)
  676.     return FALSE;
  677.  
  678.   // Check for valid timeout value.
  679.   if (seconds != -1)
  680.     timeout = seconds * 1000 + milliseconds;
  681.   else
  682.     timeout = m_timeout * 1000;
  683.  
  684.   // Wait in an active polling loop.
  685.   //
  686.   // NOTE: We duplicate some of the code in OnRequest, but this doesn't
  687.   //   hurt. It has to be here because the (GSocket) event might arrive
  688.   //   a bit delayed, and it has to be in OnRequest as well because we
  689.   //   don't know whether the Wait functions are being used.
  690.   //
  691.   // Do this at least once (important if timeout == 0, when
  692.   // we are just polling). Also, if just polling, do not yield.
  693.  
  694.   wxStopWatch chrono;
  695.   bool done = FALSE;
  696.  
  697.   while (!done)
  698.   {
  699.     result = GSocket_Select(m_socket, flags | GSOCK_LOST_FLAG);
  700.  
  701.     // Incoming connection (server) or connection established (client)
  702.     if (result & GSOCK_CONNECTION_FLAG)
  703.     {
  704.       m_connected = TRUE;
  705.       m_establishing = FALSE;
  706.       return TRUE;
  707.     }
  708.  
  709.     // Data available or output buffer ready
  710.     if ((result & GSOCK_INPUT_FLAG) || (result & GSOCK_OUTPUT_FLAG))
  711.     {
  712.       return TRUE;
  713.     }
  714.  
  715.     // Connection lost
  716.     if (result & GSOCK_LOST_FLAG)
  717.     {
  718.       m_connected = FALSE;
  719.       m_establishing = FALSE;
  720.       return (flags & GSOCK_LOST_FLAG) != 0;
  721.     }
  722.  
  723.     // Wait more?
  724.     if ((!timeout) || (chrono.Time() > timeout) || (m_interrupt))
  725.       done = TRUE;
  726.     else
  727.       PROCESS_EVENTS();
  728.   }
  729.  
  730.   return FALSE;
  731. }
  732.  
  733. bool wxSocketBase::Wait(long seconds, long milliseconds)
  734. {
  735.   return _Wait(seconds, milliseconds, GSOCK_INPUT_FLAG |
  736.                                       GSOCK_OUTPUT_FLAG |
  737.                                       GSOCK_CONNECTION_FLAG |
  738.                                       GSOCK_LOST_FLAG);
  739. }
  740.  
  741. bool wxSocketBase::WaitForRead(long seconds, long milliseconds)
  742. {
  743.   // Check pushback buffer before entering _Wait
  744.   if (m_unread)
  745.     return TRUE;
  746.  
  747.   // Note that GSOCK_INPUT_LOST has to be explicitly passed to
  748.   // _Wait becuase of the semantics of WaitForRead: a return
  749.   // value of TRUE means that a GSocket_Read call will return
  750.   // immediately, not that there is actually data to read.
  751.  
  752.   return _Wait(seconds, milliseconds, GSOCK_INPUT_FLAG |
  753.                                       GSOCK_LOST_FLAG);
  754. }
  755.  
  756. bool wxSocketBase::WaitForWrite(long seconds, long milliseconds)
  757. {
  758.   return _Wait(seconds, milliseconds, GSOCK_OUTPUT_FLAG);
  759. }
  760.  
  761. bool wxSocketBase::WaitForLost(long seconds, long milliseconds)
  762. {
  763.   return _Wait(seconds, milliseconds, GSOCK_LOST_FLAG);
  764. }
  765.  
  766. // --------------------------------------------------------------------------
  767. // Miscellaneous
  768. // --------------------------------------------------------------------------
  769.  
  770. //
  771. // Get local or peer address
  772. //
  773.  
  774. bool wxSocketBase::GetPeer(wxSockAddress& addr_man) const
  775. {
  776.   GAddress *peer;
  777.  
  778.   if (!m_socket)
  779.     return FALSE;
  780.  
  781.   peer = GSocket_GetPeer(m_socket);
  782.  
  783.     // copying a null address would just trigger an assert anyway
  784.  
  785.   if (!peer)
  786.     return FALSE;
  787.  
  788.   addr_man.SetAddress(peer);
  789.   GAddress_destroy(peer);
  790.  
  791.   return TRUE;
  792. }
  793.  
  794. bool wxSocketBase::GetLocal(wxSockAddress& addr_man) const
  795. {
  796.   GAddress *local;
  797.  
  798.   if (!m_socket)
  799.     return FALSE;
  800.  
  801.   local = GSocket_GetLocal(m_socket);
  802.   addr_man.SetAddress(local);
  803.   GAddress_destroy(local);
  804.  
  805.   return TRUE;
  806. }
  807.  
  808. //
  809. // Save and restore socket state
  810. //
  811.  
  812. void wxSocketBase::SaveState()
  813. {
  814.   wxSocketState *state;
  815.  
  816.   state = new wxSocketState();
  817.  
  818.   state->m_flags      = m_flags;
  819.   state->m_notify     = m_notify;
  820.   state->m_eventmask  = m_eventmask;
  821.   state->m_clientData = m_clientData;
  822. #if WXWIN_COMPATIBILITY
  823.   state->m_cbk        = m_cbk;
  824.   state->m_cdata      = m_cdata;
  825. #endif // WXWIN_COMPATIBILITY
  826.  
  827.   m_states.Append(state);
  828. }
  829.  
  830. void wxSocketBase::RestoreState()
  831. {
  832.   wxNode *node;
  833.   wxSocketState *state;
  834.  
  835.   node = m_states.Last();
  836.   if (!node)
  837.     return;
  838.  
  839.   state = (wxSocketState *)node->Data();
  840.  
  841.   m_flags      = state->m_flags;
  842.   m_notify     = state->m_notify;
  843.   m_eventmask  = state->m_eventmask;
  844.   m_clientData = state->m_clientData;
  845. #if WXWIN_COMPATIBILITY
  846.   m_cbk        = state->m_cbk;
  847.   m_cdata      = state->m_cdata;
  848. #endif // WXWIN_COMPATIBILITY
  849.  
  850.   delete node;
  851.   delete state;
  852. }
  853.  
  854. //
  855. // Timeout and flags
  856. //
  857.  
  858. void wxSocketBase::SetTimeout(long seconds)
  859. {
  860.   m_timeout = seconds;
  861.  
  862.   if (m_socket)
  863.     GSocket_SetTimeout(m_socket, m_timeout * 1000);
  864. }
  865.  
  866. void wxSocketBase::SetFlags(wxSocketFlags flags)
  867. {
  868.   m_flags = flags;
  869. }
  870.  
  871.  
  872. // --------------------------------------------------------------------------
  873. // Callbacks (now obsolete - use events instead)
  874. // --------------------------------------------------------------------------
  875.  
  876. #if WXWIN_COMPATIBILITY
  877.  
  878. wxSocketBase::wxSockCbk wxSocketBase::Callback(wxSockCbk cbk_)
  879. {
  880.   wxSockCbk old_cbk = cbk_;
  881.  
  882.   m_cbk = cbk_;
  883.   return old_cbk;
  884. }
  885.  
  886. char *wxSocketBase::CallbackData(char *data)
  887. {
  888.   char *old_data = m_cdata;
  889.  
  890.   m_cdata = data;
  891.   return old_data;
  892. }
  893.  
  894. #endif // WXWIN_COMPATIBILITY
  895.  
  896. // --------------------------------------------------------------------------
  897. // Event handling
  898. // --------------------------------------------------------------------------
  899.  
  900. // A note on how events are processed, which is probably the most
  901. // difficult thing to get working right while keeping the same API
  902. // and functionality for all platforms.
  903. //
  904. // When GSocket detects an event, it calls wx_socket_callback, which in
  905. // turn just calls wxSocketBase::OnRequest in the corresponding wxSocket
  906. // object. OnRequest does some housekeeping, and if the event is to be
  907. // propagated to the user, it creates a new wxSocketEvent object and
  908. // posts it. The event is not processed immediately, but delayed with
  909. // AddPendingEvent instead. This is necessary in order to decouple the
  910. // event processing from wx_socket_callback; otherwise, subsequent IO
  911. // calls made from the user event handler would fail, as gtk callbacks
  912. // are not reentrant.
  913. //
  914. // Note that, unlike events, user callbacks (now deprecated) are _not_
  915. // decoupled from wx_socket_callback and thus they suffer from a variety
  916. // of problems. Avoid them where possible and use events instead.
  917.  
  918. extern "C"
  919. void LINKAGEMODE wx_socket_callback(GSocket * WXUNUSED(socket),
  920.                                     GSocketEvent notification,
  921.                                     char *cdata)
  922. {
  923.   wxSocketBase *sckobj = (wxSocketBase *)cdata;
  924.  
  925.   sckobj->OnRequest((wxSocketNotify) notification);
  926. }
  927.  
  928. void wxSocketBase::OnRequest(wxSocketNotify notification)
  929. {
  930.   // NOTE: We duplicate some of the code in _Wait, but this doesn't
  931.   //   hurt. It has to be here because the (GSocket) event might arrive
  932.   //   a bit delayed, and it has to be in _Wait as well because we don't
  933.   //   know whether the Wait functions are being used.
  934.  
  935.   switch(notification)
  936.   {
  937.     case wxSOCKET_CONNECTION:
  938.       m_establishing = FALSE;
  939.       m_connected = TRUE;
  940.       break;
  941.  
  942.     // If we are in the middle of a R/W operation, do not
  943.     // propagate events to users. Also, filter 'late' events
  944.     // which are no longer valid.
  945.  
  946.     case wxSOCKET_INPUT:
  947.       if (m_reading || !GSocket_Select(m_socket, GSOCK_INPUT_FLAG))
  948.         return;
  949.       break;
  950.  
  951.     case wxSOCKET_OUTPUT:
  952.       if (m_writing || !GSocket_Select(m_socket, GSOCK_OUTPUT_FLAG))
  953.         return;
  954.       break;
  955.  
  956.     case wxSOCKET_LOST:
  957.       m_connected = FALSE;
  958.       m_establishing = FALSE;
  959.       break;
  960.  
  961.     default:
  962.       break;
  963.   }
  964.  
  965.   // Schedule the event
  966.  
  967.   wxSocketEventFlags flag = 0;
  968.   switch (notification)
  969.   {
  970.     case GSOCK_INPUT:      flag = GSOCK_INPUT_FLAG; break;
  971.     case GSOCK_OUTPUT:     flag = GSOCK_OUTPUT_FLAG; break;
  972.     case GSOCK_CONNECTION: flag = GSOCK_CONNECTION_FLAG; break;
  973.     case GSOCK_LOST:       flag = GSOCK_LOST_FLAG; break;
  974.     default:
  975.       wxLogWarning(_("wxSocket: unknown event!."));
  976.       return;
  977.   }
  978.  
  979.   if (((m_eventmask & flag) == flag) && m_notify)
  980.   {
  981.     if (m_handler)
  982.     {
  983.       wxSocketEvent event(m_id);
  984.       event.m_event      = notification;
  985.       event.m_clientData = m_clientData;
  986.       event.SetEventObject(this);
  987.  
  988.       m_handler->AddPendingEvent(event);
  989.     }
  990.  
  991. #if WXWIN_COMPATIBILITY
  992.     if (m_cbk)
  993.       m_cbk(*this, notification, m_cdata);
  994. #endif // WXWIN_COMPATIBILITY
  995.   }
  996. }
  997.  
  998. void wxSocketBase::Notify(bool notify)
  999. {
  1000.   m_notify = notify;
  1001. }
  1002.  
  1003. void wxSocketBase::SetNotify(wxSocketEventFlags flags)
  1004. {
  1005.   m_eventmask = flags;
  1006. }
  1007.  
  1008. void wxSocketBase::SetEventHandler(wxEvtHandler& handler, int id)
  1009. {
  1010.   m_handler = &handler;
  1011.   m_id      = id;
  1012. }
  1013.  
  1014. // --------------------------------------------------------------------------
  1015. // Pushback buffer
  1016. // --------------------------------------------------------------------------
  1017.  
  1018. void wxSocketBase::Pushback(const void *buffer, wxUint32 size)
  1019. {
  1020.   if (!size) return;
  1021.  
  1022.   if (m_unread == NULL)
  1023.     m_unread = malloc(size);
  1024.   else
  1025.   {
  1026.     void *tmp;
  1027.  
  1028.     tmp = malloc(m_unrd_size + size);
  1029.     memcpy((char *)tmp + size, m_unread, m_unrd_size);
  1030.     free(m_unread);
  1031.  
  1032.     m_unread = tmp;
  1033.   }
  1034.  
  1035.   m_unrd_size += size;
  1036.  
  1037.   memcpy(m_unread, buffer, size);
  1038. }
  1039.  
  1040. wxUint32 wxSocketBase::GetPushback(void *buffer, wxUint32 size, bool peek)
  1041. {
  1042.   if (!m_unrd_size)
  1043.     return 0;
  1044.  
  1045.   if (size > (m_unrd_size-m_unrd_cur))
  1046.     size = m_unrd_size-m_unrd_cur;
  1047.  
  1048.   memcpy(buffer, (char *)m_unread + m_unrd_cur, size);
  1049.  
  1050.   if (!peek)
  1051.   {
  1052.     m_unrd_cur += size;
  1053.     if (m_unrd_size == m_unrd_cur)
  1054.     {
  1055.       free(m_unread);
  1056.       m_unread = NULL;
  1057.       m_unrd_size = 0;
  1058.       m_unrd_cur  = 0;
  1059.     }
  1060.   }
  1061.  
  1062.   return size;
  1063. }
  1064.  
  1065.  
  1066. // ==========================================================================
  1067. // wxSocketServer
  1068. // ==========================================================================
  1069.  
  1070. // --------------------------------------------------------------------------
  1071. // Ctor
  1072. // --------------------------------------------------------------------------
  1073.  
  1074. wxSocketServer::wxSocketServer(wxSockAddress& addr_man,
  1075.                                wxSocketFlags flags)
  1076.               : wxSocketBase(flags, wxSOCKET_SERVER)
  1077. {
  1078.     wxLogTrace( wxTRACE_Socket, _T("Opening wxSocketServer") );
  1079.  
  1080.     m_socket = GSocket_new();
  1081.  
  1082.     if (!m_socket)
  1083.     {
  1084.         wxLogTrace( wxTRACE_Socket, _T("*** GSocket_new failed") );
  1085.         return;
  1086.     }
  1087.  
  1088.         // Setup the socket as server
  1089.  
  1090.     GSocket_SetLocal(m_socket, addr_man.GetAddress());
  1091.     if (GSocket_SetServer(m_socket) != GSOCK_NOERROR)
  1092.     {
  1093.         GSocket_destroy(m_socket);
  1094.         m_socket = NULL;
  1095.  
  1096.         wxLogTrace( wxTRACE_Socket, _T("*** GSocket_SetServer failed") );
  1097.         return;
  1098.     }
  1099.  
  1100.     GSocket_SetTimeout(m_socket, m_timeout * 1000);
  1101.     GSocket_SetCallback(m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
  1102.                                   GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
  1103.                                   wx_socket_callback, (char *)this);
  1104. }
  1105.  
  1106. // --------------------------------------------------------------------------
  1107. // Accept
  1108. // --------------------------------------------------------------------------
  1109.  
  1110. bool wxSocketServer::AcceptWith(wxSocketBase& sock, bool wait)
  1111. {
  1112.   GSocket *child_socket;
  1113.  
  1114.   if (!m_socket)
  1115.     return FALSE;
  1116.  
  1117.   // If wait == FALSE, then the call should be nonblocking.
  1118.   // When we are finished, we put the socket to blocking mode
  1119.   // again.
  1120.  
  1121.   if (!wait)
  1122.     GSocket_SetNonBlocking(m_socket, 1);
  1123.  
  1124.   child_socket = GSocket_WaitConnection(m_socket);
  1125.  
  1126.   if (!wait)
  1127.     GSocket_SetNonBlocking(m_socket, 0);
  1128.  
  1129.   if (!child_socket)
  1130.     return FALSE;
  1131.  
  1132.   sock.m_type = wxSOCKET_BASE;
  1133.   sock.m_socket = child_socket;
  1134.   sock.m_connected = TRUE;
  1135.  
  1136.   GSocket_SetTimeout(sock.m_socket, sock.m_timeout * 1000);
  1137.   GSocket_SetCallback(sock.m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
  1138.                                      GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
  1139.                                      wx_socket_callback, (char *)&sock);
  1140.  
  1141.   return TRUE;
  1142. }
  1143.  
  1144. wxSocketBase *wxSocketServer::Accept(bool wait)
  1145. {
  1146.   wxSocketBase* sock = new wxSocketBase();
  1147.  
  1148.   sock->SetFlags(m_flags);
  1149.  
  1150.   if (!AcceptWith(*sock, wait))
  1151.   {
  1152.     sock->Destroy();
  1153.     sock = NULL;
  1154.   }
  1155.  
  1156.   return sock;
  1157. }
  1158.  
  1159. bool wxSocketServer::WaitForAccept(long seconds, long milliseconds)
  1160. {
  1161.   return _Wait(seconds, milliseconds, GSOCK_CONNECTION_FLAG);
  1162. }
  1163.  
  1164. // ==========================================================================
  1165. // wxSocketClient
  1166. // ==========================================================================
  1167.  
  1168. // --------------------------------------------------------------------------
  1169. // Ctor and dtor
  1170. // --------------------------------------------------------------------------
  1171.  
  1172. wxSocketClient::wxSocketClient(wxSocketFlags flags)
  1173.               : wxSocketBase(flags, wxSOCKET_CLIENT)
  1174. {
  1175. }
  1176.  
  1177. wxSocketClient::~wxSocketClient()
  1178. {
  1179. }
  1180.  
  1181. // --------------------------------------------------------------------------
  1182. // Connect
  1183. // --------------------------------------------------------------------------
  1184.  
  1185. bool wxSocketClient::Connect(wxSockAddress& addr_man, bool wait)
  1186. {
  1187.   GSocketError err;
  1188.  
  1189.   if (m_socket)
  1190.   {
  1191.     // Shutdown and destroy the socket
  1192.     Close();
  1193.     GSocket_destroy(m_socket);
  1194.   }
  1195.  
  1196.   m_socket = GSocket_new();
  1197.   m_connected = FALSE;
  1198.   m_establishing = FALSE;
  1199.  
  1200.   if (!m_socket)
  1201.     return FALSE;
  1202.  
  1203.   GSocket_SetTimeout(m_socket, m_timeout * 1000);
  1204.   GSocket_SetCallback(m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
  1205.                                 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
  1206.                                 wx_socket_callback, (char *)this);
  1207.  
  1208.   // If wait == FALSE, then the call should be nonblocking.
  1209.   // When we are finished, we put the socket to blocking mode
  1210.   // again.
  1211.  
  1212.   if (!wait)
  1213.     GSocket_SetNonBlocking(m_socket, 1);
  1214.  
  1215.   GSocket_SetPeer(m_socket, addr_man.GetAddress());
  1216.   err = GSocket_Connect(m_socket, GSOCK_STREAMED);
  1217.  
  1218.   if (!wait)
  1219.     GSocket_SetNonBlocking(m_socket, 0);
  1220.  
  1221.   if (err != GSOCK_NOERROR)
  1222.   {
  1223.     if (err == GSOCK_WOULDBLOCK)
  1224.       m_establishing = TRUE;
  1225.  
  1226.     return FALSE;
  1227.   }
  1228.  
  1229.   m_connected = TRUE;
  1230.   return TRUE;
  1231. }
  1232.  
  1233. bool wxSocketClient::WaitOnConnect(long seconds, long milliseconds)
  1234. {
  1235.   if (m_connected)                      // Already connected
  1236.     return TRUE;
  1237.  
  1238.   if (!m_establishing || !m_socket)     // No connection in progress
  1239.     return FALSE;
  1240.  
  1241.   return _Wait(seconds, milliseconds, GSOCK_CONNECTION_FLAG |
  1242.                                       GSOCK_LOST_FLAG);
  1243. }
  1244.  
  1245. // ==========================================================================
  1246. // wxDatagramSocket
  1247. // ==========================================================================
  1248.  
  1249. /* NOTE: experimental stuff - might change */
  1250.  
  1251. wxDatagramSocket::wxDatagramSocket( wxSockAddress& addr,
  1252.                                     wxSocketFlags flags )
  1253.                 : wxSocketBase( flags, wxSOCKET_DATAGRAM )
  1254. {
  1255.   // Create the socket
  1256.   m_socket = GSocket_new();
  1257.  
  1258.   if(!m_socket)
  1259.     return;
  1260.  
  1261.   // Setup the socket as non connection oriented
  1262.   GSocket_SetLocal(m_socket, addr.GetAddress());
  1263.   if( GSocket_SetNonOriented(m_socket) != GSOCK_NOERROR )
  1264.   {
  1265.     GSocket_destroy(m_socket);
  1266.     m_socket = NULL;
  1267.     return;
  1268.   }
  1269.  
  1270.   // Initialize all stuff
  1271.   m_connected = FALSE;
  1272.   m_establishing = FALSE;
  1273.   GSocket_SetTimeout( m_socket, m_timeout );
  1274.   GSocket_SetCallback( m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
  1275.                                  GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
  1276.                                  wx_socket_callback, (char*)this );
  1277.  
  1278. }
  1279.  
  1280. wxDatagramSocket& wxDatagramSocket::RecvFrom( wxSockAddress& addr,
  1281.                                               void* buf,
  1282.                                               wxUint32 nBytes )
  1283. {
  1284.     Read(buf, nBytes);
  1285.     GetPeer(addr);
  1286.     return (*this);
  1287. }
  1288.  
  1289. wxDatagramSocket& wxDatagramSocket::SendTo( wxSockAddress& addr,
  1290.                                             const void* buf,
  1291.                                             wxUint32 nBytes )
  1292. {
  1293.     GSocket_SetPeer(m_socket, addr.GetAddress());
  1294.     Write(buf, nBytes);
  1295.     return (*this);
  1296. }
  1297.  
  1298. // ==========================================================================
  1299. // wxSocketModule
  1300. // ==========================================================================
  1301.  
  1302. class WXDLLEXPORT wxSocketModule : public wxModule
  1303. {
  1304. public:
  1305.     virtual bool OnInit()
  1306.     {
  1307.         // wxSocketBase will call GSocket_Init() itself when/if needed
  1308.         return TRUE;
  1309.     }
  1310.  
  1311.     virtual void OnExit()
  1312.     {
  1313.         if ( wxSocketBase::IsInitialized() )
  1314.             wxSocketBase::Shutdown();
  1315.     }
  1316.  
  1317. private:
  1318.     DECLARE_DYNAMIC_CLASS(wxSocketModule)
  1319. };
  1320.  
  1321. IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule)
  1322.  
  1323. #endif
  1324.   // wxUSE_SOCKETS
  1325.  
  1326. // vi:sts=4:sw=4:et
  1327.