]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/sockmsw.cpp
Don't try to pop from an empty stack in wxGDIPlusContext::PopState().
[wxWidgets.git] / src / msw / sockmsw.cpp
index 75b56980d46a3ad7957e795f037f2e9f9c5fc024..d531813ca68a8c940e147c1485246a67b9b416b3 100644 (file)
@@ -7,7 +7,7 @@
 //             (C) 1999-2000, Guillermo Rodriguez Garcia
 //             (C) 2008 Vadim Zeitlin
 // RCS_ID:     $Id$
-// License:    wxWindows licence
+// Licence:    wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 
 #endif
 
 #include "wx/private/socket.h"
+#include "wx/msw/private.h"     // for wxGetInstance()
+#include "wx/private/fd.h"
 #include "wx/apptrait.h"
 #include "wx/thread.h"
-
-extern "C" WXDLLIMPEXP_BASE HINSTANCE wxGetInstance();
-#define INSTANCE wxGetInstance()
-
-#include <winsock.h>
-
-#if defined(__CYGWIN__)
-    //CYGWIN gives annoying warning about runtime stuff if we don't do this
-#   define USE_SYS_TYPES_FD_SET
-#   include <sys/types.h>
-#endif
+#include "wx/dynlib.h"
+#include "wx/link.h"
 
 #ifdef __WXWINCE__
 /*
@@ -83,7 +76,7 @@ wxCreateHiddenWindow(LPCTSTR *pclassname, LPCTSTR classname, WNDPROC wndproc);
 #endif
 
 #ifndef __WXWINCE__
-typedef int (PASCAL *WSAAsyncSelectFunc)(SOCKET,HWND,u_int,long);
+typedef int (PASCAL *WSAAsyncSelect_t)(SOCKET,HWND,u_int,long);
 #else
 /* Typedef the needed function prototypes and the WSANETWORKEVENTS structure
 */
@@ -91,10 +84,10 @@ typedef struct _WSANETWORKEVENTS {
        long lNetworkEvents;
        int iErrorCode[10];
 } WSANETWORKEVENTS, FAR * LPWSANETWORKEVENTS;
-typedef HANDLE (PASCAL *WSACreateEventFunc)();
-typedef int (PASCAL *WSAEventSelectFunc)(SOCKET,HANDLE,long);
-typedef int (PASCAL *WSAWaitForMultipleEventsFunc)(long,HANDLE,BOOL,long,BOOL);
-typedef int (PASCAL *WSAEnumNetworkEventsFunc)(SOCKET,HANDLE,LPWSANETWORKEVENTS);
+typedef HANDLE (PASCAL *WSACreateEvent_t)();
+typedef int (PASCAL *WSAEventSelect_t)(SOCKET,HANDLE,long);
+typedef int (PASCAL *WSAWaitForMultipleEvents_t)(long,HANDLE,BOOL,long,BOOL);
+typedef int (PASCAL *WSAEnumNetworkEvents_t)(SOCKET,HANDLE,LPWSANETWORKEVENTS);
 #endif //__WXWINCE__
 
 LRESULT CALLBACK wxSocket_Internal_WinProc(HWND, UINT, WPARAM, LPARAM);
@@ -107,15 +100,15 @@ static wxSocketImplMSW *socketList[MAXSOCKETS];
 static int firstAvailable;
 
 #ifndef __WXWINCE__
-static WSAAsyncSelectFunc gs_WSAAsyncSelect = NULL;
+static WSAAsyncSelect_t gs_WSAAsyncSelect = NULL;
 #else
 static SocketHash socketHash;
 static unsigned int currSocket;
 HANDLE hThread[MAXSOCKETS];
-static WSACreateEventFunc gs_WSACreateEvent = NULL;
-static WSAEventSelectFunc gs_WSAEventSelect = NULL;
-static WSAWaitForMultipleEventsFunc gs_WSAWaitForMultipleEvents = NULL;
-static WSAEnumNetworkEventsFunc gs_WSAEnumNetworkEvents = NULL;
+static WSACreateEvent_t gs_WSACreateEvent = NULL;
+static WSAEventSelect_t gs_WSAEventSelect = NULL;
+static WSAWaitForMultipleEvents_t gs_WSAWaitForMultipleEvents = NULL;
+static WSAEnumNetworkEvents_t gs_WSAEnumNetworkEvents = NULL;
 /* This structure will be used to pass data on to the thread that handles socket events.
 */
 typedef struct thread_data{
@@ -126,13 +119,11 @@ typedef struct thread_data{
 }thread_data;
 #endif
 
-static HMODULE gs_wsock32dll = 0;
-
-
 #ifdef __WXWINCE__
-/* This thread handles socket events on WinCE using WSAEventSelect() as WSAAsyncSelect is not supported.
-*  When an event occures for the socket, it is checked what kind of event happend and the correct message gets posted
-*  so that the hidden window can handle it as it would in other MSW builds.
+/* This thread handles socket events on WinCE using WSAEventSelect() as
+ * WSAAsyncSelect is not supported. When an event occurs for the socket, it is
+ * checked what kind of event happend and the correct message gets posted so
+ * that the hidden window can handle it as it would in other MSW builds.
 */
 DWORD WINAPI SocketThread(LPVOID data)
 {
@@ -190,10 +181,17 @@ public:
     {
         return new wxSocketImplMSW(wxsocket);
     }
-    virtual void Install_Callback(wxSocketImpl *socket, wxSocketNotify event);
-    virtual void Uninstall_Callback(wxSocketImpl *socket, wxSocketNotify event);
+    virtual void Install_Callback(wxSocketImpl *socket,
+                                  wxSocketNotify event = wxSOCKET_LOST);
+    virtual void Uninstall_Callback(wxSocketImpl *socket,
+                                    wxSocketNotify event = wxSOCKET_LOST);
+
+private:
+    static wxDynamicLibrary gs_wsock32dll;
 };
 
+wxDynamicLibrary wxSocketMSWManager::gs_wsock32dll;
+
 bool wxSocketMSWManager::OnInit()
 {
   static LPCTSTR pclassname = NULL;
@@ -211,45 +209,42 @@ bool wxSocketMSWManager::OnInit()
   }
   firstAvailable = 0;
 
-  /* Load WSAAsyncSelect from wsock32.dll (we don't link against it
-     statically to avoid dependency on wsock32.dll for apps that don't use
-     sockets): */
+  // we don't link with wsock32.dll (or ws2 in CE case) statically to avoid
+  // dependencies on it for all the application using wx even if they don't use
+  // sockets
+#ifdef __WXWINCE__
+    #define WINSOCK_DLL_NAME wxT("ws2.dll")
+#else
+    #define WINSOCK_DLL_NAME wxT("wsock32.dll")
+#endif
+
+    gs_wsock32dll.Load(WINSOCK_DLL_NAME, wxDL_VERBATIM | wxDL_QUIET);
+    if ( !gs_wsock32dll.IsLoaded() )
+        return false;
+
 #ifndef __WXWINCE__
-  gs_wsock32dll = LoadLibrary(wxT("wsock32.dll"));
-  if (!gs_wsock32dll)
-      return false;
-  gs_WSAAsyncSelect =(WSAAsyncSelectFunc)GetProcAddress(gs_wsock32dll,
-                                                        "WSAAsyncSelect");
-  if (!gs_WSAAsyncSelect)
-      return false;
+    wxDL_INIT_FUNC(gs_, WSAAsyncSelect, gs_wsock32dll);
+    if ( !gs_WSAAsyncSelect )
+        return false;
 #else
-/*  On WinCE we load ws2.dll which will provide the needed functions.
-*/
-  gs_wsock32dll = LoadLibrary(wxT("ws2.dll"));
-  if (!gs_wsock32dll)
-      return false;
-  gs_WSAEventSelect =(WSAEventSelectFunc)GetProcAddress(gs_wsock32dll,
-                                                        wxT("WSAEventSelect"));
-  if (!gs_WSAEventSelect)
-      return false;
+    wxDL_INIT_FUNC(gs_, WSAEventSelect, gs_wsock32dll);
+    if ( !gs_WSAEventSelect )
+        return false;
 
-  gs_WSACreateEvent =(WSACreateEventFunc)GetProcAddress(gs_wsock32dll,
-                                                        wxT("WSACreateEvent"));
-  if (!gs_WSACreateEvent)
-      return false;
+    wxDL_INIT_FUNC(gs_, WSACreateEvent, gs_wsock32dll);
+    if ( !gs_WSACreateEvent )
+        return false;
 
-  gs_WSAWaitForMultipleEvents =(WSAWaitForMultipleEventsFunc)GetProcAddress(gs_wsock32dll,
-                                                                            wxT("WSAWaitForMultipleEvents"));
-  if (!gs_WSAWaitForMultipleEvents)
-      return false;
+    wxDL_INIT_FUNC(gs_, WSAWaitForMultipleEvents, gs_wsock32dll);
+    if ( !gs_WSAWaitForMultipleEvents )
+        return false;
 
-  gs_WSAEnumNetworkEvents =(WSAEnumNetworkEventsFunc)GetProcAddress(gs_wsock32dll,
-                                                                    wxT("WSAEnumNetworkEvents"));
-  if (!gs_WSAEnumNetworkEvents)
-      return false;
+    wxDL_INIT_FUNC(gs_, WSAEnumNetworkEvents, gs_wsock32dll);
+    if ( !gs_WSAEnumNetworkEvents )
+        return false;
 
-  currSocket = 0;
-#endif
+    currSocket = 0;
+#endif // !__WXWINCE__/__WXWINCE__
 
   // finally initialize WinSock
   WSADATA wsaData;
@@ -265,16 +260,11 @@ void wxSocketMSWManager::OnExit()
 #endif
   /* Destroy internal window */
   DestroyWindow(hWin);
-  UnregisterClass(CLASSNAME, INSTANCE);
-
-  /* Unlock wsock32.dll */
-  if (gs_wsock32dll)
-  {
-      FreeLibrary(gs_wsock32dll);
-      gs_wsock32dll = 0;
-  }
+  UnregisterClass(CLASSNAME, wxGetInstance());
 
   WSACleanup();
+
+  gs_wsock32dll.Unload();
 }
 
 /* Per-socket GUI initialization / cleanup */
@@ -331,49 +321,70 @@ LRESULT CALLBACK wxSocket_Internal_WinProc(HWND hWnd,
         return DefWindowProc(hWnd, uMsg, wParam, lParam);
 
     wxSocketImplMSW *socket;
-    wxSocketNotify event;
+    wxSocketNotify event = (wxSocketNotify)-1;
     {
         wxCRIT_SECT_LOCKER(lock, gs_critical);
 
         socket = socketList[(uMsg - WM_USER)];
-        event = (wxSocketNotify) -1;
+        if ( !socket )
+            return 0;
+
+        // the socket may be already closed but we could still receive
+        // notifications for it sent (asynchronously) before it got closed
+        if ( socket->m_fd == INVALID_SOCKET )
+            return 0;
+
+        wxASSERT_MSG( socket->m_fd == (SOCKET)wParam,
+                      "mismatch between message and socket?" );
 
-        /* Check that the socket still exists (it has not been
-         * destroyed) and for safety, check that the m_fd field
-         * is what we expect it to be.
-         */
-        if ((socket != NULL) && ((WPARAM)socket->m_fd == wParam))
+        switch ( WSAGETSELECTEVENT(lParam) )
         {
-            switch WSAGETSELECTEVENT(lParam)
-            {
-                case FD_READ:    event = wxSOCKET_INPUT; break;
-                case FD_WRITE:   event = wxSOCKET_OUTPUT; break;
-                case FD_ACCEPT:  event = wxSOCKET_CONNECTION; break;
-                case FD_CONNECT:
-                                 {
-                                     if (WSAGETSELECTERROR(lParam) != 0)
-                                         event = wxSOCKET_LOST;
-                                     else
-                                         event = wxSOCKET_CONNECTION;
-                                     break;
-                                 }
-                case FD_CLOSE:   event = wxSOCKET_LOST; break;
-            }
-
-            if (event != -1)
-            {
-                if (event == wxSOCKET_LOST)
-                    socket->m_detected = wxSOCKET_LOST_FLAG;
-                else
-                    socket->m_detected |= (1 << event);
-            }
+            case FD_READ:
+                // We may get a FD_READ notification even when there is no data
+                // to read on the socket, in particular this happens on socket
+                // creation when we seem to always get FD_CONNECT, FD_WRITE and
+                // FD_READ notifications all at once (but it doesn't happen
+                // only then). Ignore such dummy notifications.
+                {
+                    fd_set fds;
+                    timeval tv = { 0, 0 };
+
+                    wxFD_ZERO(&fds);
+                    wxFD_SET(socket->m_fd, &fds);
+
+                    if ( select(socket->m_fd + 1, &fds, NULL, NULL, &tv) != 1 )
+                        return 0;
+                }
+
+                event = wxSOCKET_INPUT;
+                break;
+
+            case FD_WRITE:
+                event = wxSOCKET_OUTPUT;
+                break;
+
+            case FD_ACCEPT:
+                event = wxSOCKET_CONNECTION;
+                break;
+
+            case FD_CONNECT:
+                event = WSAGETSELECTERROR(lParam) ? wxSOCKET_LOST
+                                                  : wxSOCKET_CONNECTION;
+                break;
+
+            case FD_CLOSE:
+                event = wxSOCKET_LOST;
+                break;
+
+            default:
+                wxFAIL_MSG( "unexpected socket notification" );
+                return 0;
         }
     } // unlock gs_critical
 
-    if ( socket )
-        socket->NotifyOnStateChange(event);
+    socket->NotifyOnStateChange(event);
 
-    return (LRESULT) 0;
+    return 0;
 }
 
 /*
@@ -416,7 +427,7 @@ void wxSocketMSWManager::Install_Callback(wxSocketImpl *socket_,
  *  Disable event notifications (used when shutting down the socket)
  */
 void wxSocketMSWManager::Uninstall_Callback(wxSocketImpl *socket_,
-                                           wxSocketNotify WXUNUSED(event))
+                                            wxSocketNotify WXUNUSED(event))
 {
     wxSocketImplMSW * const socket = static_cast<wxSocketImplMSW *>(socket_);
 
@@ -444,886 +455,36 @@ static struct ManagerSetter
     }
 } gs_managerSetter;
 
+// see the relative linker macro in socket.cpp
+wxFORCE_LINK_THIS_MODULE( mswsocket );
+
 // ============================================================================
 // wxSocketImpl implementation
 // ============================================================================
 
-/* static */
-wxSocketImpl *wxSocketImpl::Create(wxSocketBase& wxsocket)
-{
-    return new wxSocketImplMSW(wxsocket);
-}
-
 void wxSocketImplMSW::DoClose()
 {
-    wxSocketManager::Get()->
-        Uninstall_Callback(this, wxSOCKET_MAX_EVENT /* unused anyhow */);
+    wxSocketManager::Get()->Uninstall_Callback(this);
 
     closesocket(m_fd);
 }
 
-/*
- *  Waits for an incoming client connection. Returns a pointer to
- *  a wxSocketImpl object, or NULL if there was an error, in which case
- *  the last error field will be updated for the calling wxSocketImpl.
- *
- *  Error codes (set in the calling wxSocketImpl)
- *    wxSOCKET_INVSOCK    - the socket is not valid or not a server.
- *    wxSOCKET_TIMEDOUT   - timeout, no incoming connections.
- *    wxSOCKET_WOULDBLOCK - the call would block and the socket is nonblocking.
- *    wxSOCKET_MEMERR     - couldn't allocate memory.
- *    wxSOCKET_IOERR      - low-level error.
- */
-wxSocketImpl *wxSocketImplMSW::WaitConnection(wxSocketBase& wxsocket)
-{
-  wxSocketImpl *connection;
-  wxSockAddr from;
-  WX_SOCKLEN_T fromlen = sizeof(from);
-  wxSocketError err;
-  u_long arg = 1;
-
-  /* Reenable CONNECTION events */
-  m_detected &= ~wxSOCKET_CONNECTION_FLAG;
-
-  /* If the socket has already been created, we exit immediately */
-  if (m_fd == INVALID_SOCKET || !m_server)
-  {
-    m_error = wxSOCKET_INVSOCK;
-    return NULL;
-  }
-
-  /* Create a wxSocketImpl object for the new connection */
-  connection = wxSocketImplMSW::Create(wxsocket);
-
-  if (!connection)
-  {
-    m_error = wxSOCKET_MEMERR;
-    return NULL;
-  }
-
-  /* Wait for a connection (with timeout) */
-  if (Input_Timeout() == wxSOCKET_TIMEDOUT)
-  {
-    delete connection;
-    /* m_error set by Input_Timeout */
-    return NULL;
-  }
-
-  connection->m_fd = accept(m_fd, (sockaddr*)&from, &fromlen);
-
-  if (connection->m_fd == INVALID_SOCKET)
-  {
-    if (WSAGetLastError() == WSAEWOULDBLOCK)
-      m_error = wxSOCKET_WOULDBLOCK;
-    else
-      m_error = wxSOCKET_IOERR;
-
-    delete connection;
-    return NULL;
-  }
-
-  /* Initialize all fields */
-  connection->m_server   = false;
-  connection->m_stream   = true;
-
-  /* Setup the peer address field */
-  connection->m_peer = GAddress_new();
-  if (!connection->m_peer)
-  {
-    delete connection;
-    m_error = wxSOCKET_MEMERR;
-    return NULL;
-  }
-  err = _GAddress_translate_from(connection->m_peer, (sockaddr*)&from, fromlen);
-  if (err != wxSOCKET_NOERROR)
-  {
-    GAddress_destroy(connection->m_peer);
-    delete connection;
-    m_error = err;
-    return NULL;
-  }
-
-  ioctlsocket(connection->m_fd, FIONBIO, (u_long FAR *) &arg);
-  wxSocketManager::Get()->Install_Callback(connection);
-
-  return connection;
-}
-
-wxSocketError wxSocketImplMSW::DoHandleConnect(int ret)
+wxSocketError wxSocketImplMSW::GetLastError() const
 {
-    // TODO: review this
-    if (ret == SOCKET_ERROR)
+    switch ( WSAGetLastError() )
     {
-        int err = WSAGetLastError();
-
-        /* If connect failed with EWOULDBLOCK and the wxSocketImpl object
-         * is in blocking mode, we select() for the specified timeout
-         * checking for writability to see if the connection request
-         * completes.
-         */
-        if ((err == WSAEWOULDBLOCK) && (!m_non_blocking))
-        {
-            err = Connect_Timeout();
+        case 0:
+            return wxSOCKET_NOERROR;
 
-            if (err != wxSOCKET_NOERROR)
-            {
-                Close();
-                /* m_error is set in Connect_Timeout */
-            }
+        case WSAENOTSOCK:
+            return wxSOCKET_INVSOCK;
 
-            return (wxSocketError) err;
-        }
-
-        /* If connect failed with EWOULDBLOCK and the wxSocketImpl object
-         * is set to nonblocking, we set m_error to wxSOCKET_WOULDBLOCK
-         * (and return wxSOCKET_WOULDBLOCK) but we don't close the socket;
-         * this way if the connection completes, a wxSOCKET_CONNECTION
-         * event will be generated, if enabled.
-         */
-        if ((err == WSAEWOULDBLOCK) && (m_non_blocking))
-        {
-            m_establishing = true;
-            m_error = wxSOCKET_WOULDBLOCK;
+        case WSAEWOULDBLOCK:
             return wxSOCKET_WOULDBLOCK;
-        }
-
-        /* If connect failed with an error other than EWOULDBLOCK,
-         * then the call to Connect() has failed.
-         */
-        Close();
-        m_error = wxSOCKET_IOERR;
-        return wxSOCKET_IOERR;
-    }
-
-    return wxSOCKET_NOERROR;
-}
-
-/* Generic IO */
-
-/* Like recv(), send(), ... */
-int wxSocketImplMSW::Read(void *buffer, int size)
-{
-  int ret;
-
-  /* Reenable INPUT events */
-  m_detected &= ~wxSOCKET_INPUT_FLAG;
-
-  if (m_fd == INVALID_SOCKET || m_server)
-  {
-    m_error = wxSOCKET_INVSOCK;
-    return -1;
-  }
-
-  /* If the socket is blocking, wait for data (with a timeout) */
-  if (Input_Timeout() == wxSOCKET_TIMEDOUT)
-  {
-    m_error = wxSOCKET_TIMEDOUT;
-    return -1;
-  }
-
-  /* Read the data */
-  if (m_stream)
-    ret = Recv_Stream(buffer, size);
-  else
-    ret = Recv_Dgram(buffer, size);
-
-  if (ret == SOCKET_ERROR)
-  {
-    if (WSAGetLastError() != WSAEWOULDBLOCK)
-      m_error = wxSOCKET_IOERR;
-    else
-      m_error = wxSOCKET_WOULDBLOCK;
-    return -1;
-  }
-
-  return ret;
-}
-
-int wxSocketImplMSW::Write(const void *buffer, int size)
-{
-  int ret;
-
-  if (m_fd == INVALID_SOCKET || m_server)
-  {
-    m_error = wxSOCKET_INVSOCK;
-    return -1;
-  }
-
-  /* If the socket is blocking, wait for writability (with a timeout) */
-  if (Output_Timeout() == wxSOCKET_TIMEDOUT)
-    return -1;
-
-  /* Write the data */
-  if (m_stream)
-    ret = Send_Stream(buffer, size);
-  else
-    ret = Send_Dgram(buffer, size);
-
-  if (ret == SOCKET_ERROR)
-  {
-    if (WSAGetLastError() != WSAEWOULDBLOCK)
-      m_error = wxSOCKET_IOERR;
-    else
-      m_error = wxSOCKET_WOULDBLOCK;
-
-    /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
-     * does). Once the first OUTPUT event is received, users can assume
-     * that the socket is writable until a read operation fails. Only then
-     * will further OUTPUT events be posted.
-     */
-    m_detected &= ~wxSOCKET_OUTPUT_FLAG;
-    return -1;
-  }
-
-  return ret;
-}
-
-/* Internals (IO) */
-
-/*
- *  For blocking sockets, wait until data is available or
- *  until timeout ellapses.
- */
-wxSocketError wxSocketImplMSW::Input_Timeout()
-{
-  fd_set readfds;
-
-  if (!m_non_blocking)
-  {
-    FD_ZERO(&readfds);
-    FD_SET(m_fd, &readfds);
-    if (select(0, &readfds, NULL, NULL, &m_timeout) == 0)
-    {
-      m_error = wxSOCKET_TIMEDOUT;
-      return wxSOCKET_TIMEDOUT;
-    }
-  }
-  return wxSOCKET_NOERROR;
-}
-
-/*
- *  For blocking sockets, wait until data can be sent without
- *  blocking or until timeout ellapses.
- */
-wxSocketError wxSocketImplMSW::Output_Timeout()
-{
-  fd_set writefds;
-
-  if (!m_non_blocking)
-  {
-    FD_ZERO(&writefds);
-    FD_SET(m_fd, &writefds);
-    if (select(0, NULL, &writefds, NULL, &m_timeout) == 0)
-    {
-      m_error = wxSOCKET_TIMEDOUT;
-      return wxSOCKET_TIMEDOUT;
-    }
-  }
-  return wxSOCKET_NOERROR;
-}
-
-/*
- *  For blocking sockets, wait until the connection is
- *  established or fails, or until timeout ellapses.
- */
-wxSocketError wxSocketImplMSW::Connect_Timeout()
-{
-  fd_set writefds;
-  fd_set exceptfds;
-
-  FD_ZERO(&writefds);
-  FD_ZERO(&exceptfds);
-  FD_SET(m_fd, &writefds);
-  FD_SET(m_fd, &exceptfds);
-  if (select(0, NULL, &writefds, &exceptfds, &m_timeout) == 0)
-  {
-    m_error = wxSOCKET_TIMEDOUT;
-    return wxSOCKET_TIMEDOUT;
-  }
-  if (!FD_ISSET(m_fd, &writefds))
-  {
-    m_error = wxSOCKET_IOERR;
-    return wxSOCKET_IOERR;
-  }
-
-  return wxSOCKET_NOERROR;
-}
-
-int wxSocketImplMSW::Recv_Stream(void *buffer, int size)
-{
-    return recv(m_fd, static_cast<char *>(buffer), size, 0);
-}
-
-int wxSocketImplMSW::Recv_Dgram(void *buffer, int size)
-{
-  wxSockAddr from;
-  WX_SOCKLEN_T fromlen = sizeof(from);
-  int ret;
-  wxSocketError err;
-
-  ret = recvfrom(m_fd, static_cast<char *>(buffer),
-                 size, 0, &from, &fromlen);
-
-  if (ret == SOCKET_ERROR)
-    return SOCKET_ERROR;
-
-  /* Translate a system address into a wxSocketImpl address */
-  if (!m_peer)
-  {
-    m_peer = GAddress_new();
-    if (!m_peer)
-    {
-      m_error = wxSOCKET_MEMERR;
-      return -1;
-    }
-  }
-  err = _GAddress_translate_from(m_peer, (sockaddr*)&from, fromlen);
-  if (err != wxSOCKET_NOERROR)
-  {
-    GAddress_destroy(m_peer);
-    m_peer  = NULL;
-    m_error = err;
-    return -1;
-  }
-
-  return ret;
-}
-
-int wxSocketImplMSW::Send_Stream(const void *buffer, int size)
-{
-  return send(m_fd, static_cast<const char *>(buffer), size, 0);
-}
-
-int wxSocketImplMSW::Send_Dgram(const void *buffer, int size)
-{
-  struct sockaddr *addr;
-  int len, ret;
-  wxSocketError err;
-
-  if (!m_peer)
-  {
-    m_error = wxSOCKET_INVADDR;
-    return -1;
-  }
-
-  err = _GAddress_translate_to(m_peer, &addr, &len);
-  if (err != wxSOCKET_NOERROR)
-  {
-    m_error = err;
-    return -1;
-  }
-
-  ret = sendto(m_fd, static_cast<const char *>(buffer), size, 0, addr, len);
-
-  /* Frees memory allocated by _GAddress_translate_to */
-  free(addr);
-
-  return ret;
-}
-
-/*
- * -------------------------------------------------------------------------
- * GAddress
- * -------------------------------------------------------------------------
- */
-
-/* CHECK_ADDRESS verifies that the current address family is either
- * wxSOCKET_NOFAMILY or wxSOCKET_*family*, and if it is wxSOCKET_NOFAMILY, it
- * initalizes it to be a wxSOCKET_*family*. In other cases, it returns
- * an appropiate error code.
- *
- * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error.
- */
-#define CHECK_ADDRESS(address, family)                              \
-{                                                                   \
-  if (address->m_family == wxSOCKET_NOFAMILY)                          \
-    if (_GAddress_Init_##family(address) != wxSOCKET_NOERROR)          \
-      return address->m_error;                                      \
-  if (address->m_family != wxSOCKET_##family)                          \
-  {                                                                 \
-    address->m_error = wxSOCKET_INVADDR;                               \
-    return wxSOCKET_INVADDR;                                           \
-  }                                                                 \
-}
-
-#define CHECK_ADDRESS_RETVAL(address, family, retval)               \
-{                                                                   \
-  if (address->m_family == wxSOCKET_NOFAMILY)                          \
-    if (_GAddress_Init_##family(address) != wxSOCKET_NOERROR)          \
-      return retval;                                                \
-  if (address->m_family != wxSOCKET_##family)                          \
-  {                                                                 \
-    address->m_error = wxSOCKET_INVADDR;                               \
-    return retval;                                                  \
-  }                                                                 \
-}
-
-
-GAddress *GAddress_new()
-{
-  GAddress *address;
-
-  if ((address = (GAddress *) malloc(sizeof(GAddress))) == NULL)
-    return NULL;
-
-  address->m_family = wxSOCKET_NOFAMILY;
-  address->m_addr   = NULL;
-  address->m_len    = 0;
-
-  return address;
-}
-
-GAddress *GAddress_copy(GAddress *address)
-{
-  GAddress *addr2;
-
-  if ((addr2 = (GAddress *) malloc(sizeof(GAddress))) == NULL)
-    return NULL;
-
-  memcpy(addr2, address, sizeof(GAddress));
-
-  if (address->m_addr)
-  {
-    addr2->m_addr = (struct sockaddr *) malloc(addr2->m_len);
-    if (addr2->m_addr == NULL)
-    {
-      free(addr2);
-      return NULL;
-    }
-    memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
-  }
 
-  return addr2;
-}
-
-void GAddress_destroy(GAddress *address)
-{
-  if (address->m_addr)
-    free(address->m_addr);
-
-  free(address);
-}
-
-void GAddress_SetFamily(GAddress *address, GAddressType type)
-{
-  address->m_family = type;
-}
-
-GAddressType GAddress_GetFamily(GAddress *address)
-{
-  return address->m_family;
-}
-
-wxSocketError _GAddress_translate_from(GAddress *address,
-                                      struct sockaddr *addr, int len)
-{
-  address->m_realfamily = addr->sa_family;
-  switch (addr->sa_family)
-  {
-    case AF_INET:
-      address->m_family = wxSOCKET_INET;
-      break;
-    case AF_UNIX:
-      address->m_family = wxSOCKET_UNIX;
-      break;
-#if wxUSE_IPV6
-    case AF_INET6:
-      address->m_family = wxSOCKET_INET6;
-      break;
-#endif
-    default:
-    {
-      address->m_error = wxSOCKET_INVOP;
-      return wxSOCKET_INVOP;
-    }
-  }
-
-  if (address->m_addr)
-    free(address->m_addr);
-
-  address->m_len = len;
-  address->m_addr = (struct sockaddr *) malloc(len);
-
-  if (address->m_addr == NULL)
-  {
-    address->m_error = wxSOCKET_MEMERR;
-    return wxSOCKET_MEMERR;
-  }
-  memcpy(address->m_addr, addr, len);
-
-  return wxSOCKET_NOERROR;
-}
-
-wxSocketError _GAddress_translate_to(GAddress *address,
-                                    struct sockaddr **addr, int *len)
-{
-  if (!address->m_addr)
-  {
-    address->m_error = wxSOCKET_INVADDR;
-    return wxSOCKET_INVADDR;
-  }
-
-  *len = address->m_len;
-  *addr = (struct sockaddr *) malloc(address->m_len);
-  if (*addr == NULL)
-  {
-    address->m_error = wxSOCKET_MEMERR;
-    return wxSOCKET_MEMERR;
-  }
-
-  memcpy(*addr, address->m_addr, address->m_len);
-  return wxSOCKET_NOERROR;
-}
-
-/*
- * -------------------------------------------------------------------------
- * Internet address family
- * -------------------------------------------------------------------------
- */
-
-wxSocketError _GAddress_Init_INET(GAddress *address)
-{
-  address->m_len  = sizeof(struct sockaddr_in);
-  address->m_addr = (struct sockaddr *) malloc(address->m_len);
-  if (address->m_addr == NULL)
-  {
-    address->m_error = wxSOCKET_MEMERR;
-    return wxSOCKET_MEMERR;
-  }
-
-  address->m_family = wxSOCKET_INET;
-  address->m_realfamily = AF_INET;
-  ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
-  ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
-
-  return wxSOCKET_NOERROR;
-}
-
-wxSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
-{
-  struct hostent *he;
-  struct in_addr *addr;
-
-  CHECK_ADDRESS(address, INET);
-
-  addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
-
-  addr->s_addr = inet_addr(hostname);
-
-  /* If it is a numeric host name, convert it now */
-  if (addr->s_addr == INADDR_NONE)
-  {
-    struct in_addr *array_addr;
-
-    /* It is a real name, we solve it */
-    if ((he = gethostbyname(hostname)) == NULL)
-    {
-      /* addr->s_addr = INADDR_NONE just done by inet_addr() above */
-      address->m_error = wxSOCKET_NOHOST;
-      return wxSOCKET_NOHOST;
-    }
-    array_addr = (struct in_addr *) *(he->h_addr_list);
-    addr->s_addr = array_addr[0].s_addr;
-  }
-  return wxSOCKET_NOERROR;
-}
-
-wxSocketError GAddress_INET_SetBroadcastAddress(GAddress *address)
-{
-  return GAddress_INET_SetHostAddress(address, INADDR_BROADCAST);
-}
-
-wxSocketError GAddress_INET_SetAnyAddress(GAddress *address)
-{
-  return GAddress_INET_SetHostAddress(address, INADDR_ANY);
-}
-
-wxSocketError GAddress_INET_SetHostAddress(GAddress *address,
-                                          unsigned long hostaddr)
-{
-  struct in_addr *addr;
-
-  CHECK_ADDRESS(address, INET);
-
-  addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
-  addr->s_addr = htonl(hostaddr);
-
-  return wxSOCKET_NOERROR;
-}
-
-wxSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
-                                       const char *protocol)
-{
-  struct servent *se;
-  struct sockaddr_in *addr;
-
-  CHECK_ADDRESS(address, INET);
-
-  if (!port)
-  {
-    address->m_error = wxSOCKET_INVPORT;
-    return wxSOCKET_INVPORT;
-  }
-
-  se = getservbyname(port, protocol);
-  if (!se)
-  {
-    if (isdigit(port[0]))
-    {
-      int port_int;
-
-      port_int = atoi(port);
-      addr = (struct sockaddr_in *)address->m_addr;
-      addr->sin_port = htons((u_short) port_int);
-      return wxSOCKET_NOERROR;
-    }
-
-    address->m_error = wxSOCKET_INVPORT;
-    return wxSOCKET_INVPORT;
-  }
-
-  addr = (struct sockaddr_in *)address->m_addr;
-  addr->sin_port = se->s_port;
-
-  return wxSOCKET_NOERROR;
-}
-
-wxSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
-{
-  struct sockaddr_in *addr;
-
-  CHECK_ADDRESS(address, INET);
-
-  addr = (struct sockaddr_in *)address->m_addr;
-  addr->sin_port = htons(port);
-
-  return wxSOCKET_NOERROR;
-}
-
-wxSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
-{
-  struct hostent *he;
-  char *addr_buf;
-  struct sockaddr_in *addr;
-
-  CHECK_ADDRESS(address, INET);
-
-  addr = (struct sockaddr_in *)address->m_addr;
-  addr_buf = (char *)&(addr->sin_addr);
-
-  he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
-  if (he == NULL)
-  {
-    address->m_error = wxSOCKET_NOHOST;
-    return wxSOCKET_NOHOST;
-  }
-
-  strncpy(hostname, he->h_name, sbuf);
-
-  return wxSOCKET_NOERROR;
-}
-
-unsigned long GAddress_INET_GetHostAddress(GAddress *address)
-{
-  struct sockaddr_in *addr;
-
-  CHECK_ADDRESS_RETVAL(address, INET, 0);
-
-  addr = (struct sockaddr_in *)address->m_addr;
-
-  return ntohl(addr->sin_addr.s_addr);
-}
-
-unsigned short GAddress_INET_GetPort(GAddress *address)
-{
-  struct sockaddr_in *addr;
-
-  CHECK_ADDRESS_RETVAL(address, INET, 0);
-
-  addr = (struct sockaddr_in *)address->m_addr;
-  return ntohs(addr->sin_port);
-}
-
-
-#if wxUSE_IPV6
-/*
- * -------------------------------------------------------------------------
- * Internet IPv6 address family
- * -------------------------------------------------------------------------
- */
-#include "ws2tcpip.h"
-
-#ifdef __VISUALC__
-    #pragma comment(lib,"ws2_32")
-#endif // __VISUALC__
-
-wxSocketError _GAddress_Init_INET6(GAddress *address)
-{
-  struct in6_addr any_address = IN6ADDR_ANY_INIT;
-  address->m_len  = sizeof(struct sockaddr_in6);
-  address->m_addr = (struct sockaddr *) malloc(address->m_len);
-  if (address->m_addr == NULL)
-  {
-    address->m_error = wxSOCKET_MEMERR;
-    return wxSOCKET_MEMERR;
-  }
-  memset(address->m_addr,0,address->m_len);
-
-  address->m_family = wxSOCKET_INET6;
-  address->m_realfamily = AF_INET6;
-  ((struct sockaddr_in6 *)address->m_addr)->sin6_family = AF_INET6;
-  ((struct sockaddr_in6 *)address->m_addr)->sin6_addr = any_address;
-
-  return wxSOCKET_NOERROR;
-}
-
-wxSocketError GAddress_INET6_SetHostName(GAddress *address, const char *hostname)
-{
-  CHECK_ADDRESS(address, INET6);
-
-  addrinfo hints;
-  memset( & hints, 0, sizeof( hints ) );
-  hints.ai_family = AF_INET6;
-  addrinfo * info = 0;
-  if ( getaddrinfo( hostname, "0", & hints, & info ) || ! info )
-  {
-    address->m_error = wxSOCKET_NOHOST;
-    return wxSOCKET_NOHOST;
-  }
-
-  memcpy( address->m_addr, info->ai_addr, info->ai_addrlen );
-  freeaddrinfo( info );
-  return wxSOCKET_NOERROR;
-}
-
-wxSocketError GAddress_INET6_SetAnyAddress(GAddress *address)
-{
-  CHECK_ADDRESS(address, INET6);
-
-  struct in6_addr addr;
-  memset( & addr, 0, sizeof( addr ) );
-  return GAddress_INET6_SetHostAddress(address, addr);
-}
-wxSocketError GAddress_INET6_SetHostAddress(GAddress *address,
-                                          struct in6_addr hostaddr)
-{
-  CHECK_ADDRESS(address, INET6);
-
-  ((struct sockaddr_in6 *)address->m_addr)->sin6_addr = hostaddr;
-
-  return wxSOCKET_NOERROR;
-}
-
-wxSocketError GAddress_INET6_SetPortName(GAddress *address, const char *port,
-                                       const char *protocol)
-{
-  struct servent *se;
-  struct sockaddr_in6 *addr;
-
-  CHECK_ADDRESS(address, INET6);
-
-  if (!port)
-  {
-    address->m_error = wxSOCKET_INVPORT;
-    return wxSOCKET_INVPORT;
-  }
-
-  se = getservbyname(port, protocol);
-  if (!se)
-  {
-    if (isdigit((unsigned char) port[0]))
-    {
-      int port_int;
-
-      port_int = atoi(port);
-      addr = (struct sockaddr_in6 *)address->m_addr;
-      addr->sin6_port = htons((u_short) port_int);
-      return wxSOCKET_NOERROR;
+        default:
+            return wxSOCKET_IOERR;
     }
-
-    address->m_error = wxSOCKET_INVPORT;
-    return wxSOCKET_INVPORT;
-  }
-
-  addr = (struct sockaddr_in6 *)address->m_addr;
-  addr->sin6_port = se->s_port;
-
-  return wxSOCKET_NOERROR;
-}
-
-wxSocketError GAddress_INET6_SetPort(GAddress *address, unsigned short port)
-{
-  struct sockaddr_in6 *addr;
-
-  CHECK_ADDRESS(address, INET6);
-
-  addr = (struct sockaddr_in6 *)address->m_addr;
-  addr->sin6_port = htons(port);
-
-  return wxSOCKET_NOERROR;
-}
-
-wxSocketError GAddress_INET6_GetHostName(GAddress *address, char *hostname, size_t sbuf)
-{
-  struct hostent *he;
-  char *addr_buf;
-  struct sockaddr_in6 *addr;
-
-  CHECK_ADDRESS(address, INET6);
-
-  addr = (struct sockaddr_in6 *)address->m_addr;
-  addr_buf = (char *)&(addr->sin6_addr);
-
-  he = gethostbyaddr(addr_buf, sizeof(addr->sin6_addr), AF_INET6);
-  if (he == NULL)
-  {
-    address->m_error = wxSOCKET_NOHOST;
-    return wxSOCKET_NOHOST;
-  }
-
-  strncpy(hostname, he->h_name, sbuf);
-
-  return wxSOCKET_NOERROR;
-}
-
-wxSocketError GAddress_INET6_GetHostAddress(GAddress *address,struct in6_addr *hostaddr)
-{
-  CHECK_ADDRESS_RETVAL(address, INET6, wxSOCKET_INVADDR);
-  *hostaddr = ( (struct sockaddr_in6 *)address->m_addr )->sin6_addr;
-  return wxSOCKET_NOERROR;
-}
-
-unsigned short GAddress_INET6_GetPort(GAddress *address)
-{
-  CHECK_ADDRESS_RETVAL(address, INET6, 0);
-
-  return ntohs( ((struct sockaddr_in6 *)address->m_addr)->sin6_port );
-}
-
-#endif // wxUSE_IPV6
-
-/*
- * -------------------------------------------------------------------------
- * Unix address family
- * -------------------------------------------------------------------------
- */
-
-wxSocketError _GAddress_Init_UNIX(GAddress *address)
-{
-  address->m_error = wxSOCKET_INVADDR;
-  return wxSOCKET_INVADDR;
-}
-
-wxSocketError GAddress_UNIX_SetPath(GAddress *address, const char *WXUNUSED(path))
-{
-  address->m_error = wxSOCKET_INVADDR;
-  return wxSOCKET_INVADDR;
-}
-
-wxSocketError GAddress_UNIX_GetPath(GAddress *address, char *WXUNUSED(path), size_t WXUNUSED(sbuf))
-{
-  address->m_error = wxSOCKET_INVADDR;
-  return wxSOCKET_INVADDR;
 }
 
 #endif  // wxUSE_SOCKETS