]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/private/socket.h
add wxVector(size_t size[, const value_type& value]) ctors
[wxWidgets.git] / include / wx / private / socket.h
index 9b20bf60ccc3563e2f75bc22f3fa981ecb46bcf8..e1c2f6ad254dce0867056b77e6d656222a0ced18 100644 (file)
@@ -1,16 +1,71 @@
-///////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
 // Name:        wx/private/socket.h
-// Purpose:     various wxSocket-related private declarations
-// Author:      Vadim Zeitlin
-// Created:     2008-11-23
-// RCS-ID:      $Id$
-// Copyright:   (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
+// Purpose:     wxSocketImpl nd related declarations
+// Authors:     Guilhem Lavaux, Vadim Zeitlin
+// Created:     April 1997
+// RCS-ID:      $Id: socket.h 56994 2008-11-28 12:47:07Z VZ $
+// Copyright:   (c) 1997 Guilhem Lavaux
+//              (c) 2008 Vadim Zeitlin
 // Licence:     wxWindows licence
-///////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+/*
+    Brief overview of different socket classes:
+
+    - wxSocketBase is the public class representing a socket ("Base" here
+      refers to the fact that wxSocketClient and wxSocketServer are derived
+      from it and predates the convention of using "Base" for common base
+      classes for platform-specific classes in wxWidgets) with implementation
+      common to all platforms and forwarding methods whose implementation
+      differs between platforms to wxSocketImpl which it contains.
+
+    - wxSocketImpl is actually just an abstract base class having only code
+      common to all platforms, the concrete implementation classes derive from
+      it and are created by wxSocketImpl::Create().
+
+    - Some socket operations have different implementations in console-mode and
+      GUI applications. wxSocketManager class exists to abstract this in such
+      way that console applications (using wxBase) don't depend on wxNet. An
+      object of this class is made available via wxApp and GUI applications set
+      up a different kind of global socket manager from console ones.
+
+      TODO: it looks like wxSocketManager could be eliminated by providing
+            methods for registering/unregistering sockets directly in
+            wxEventLoop.
+ */
 
 #ifndef _WX_PRIVATE_SOCKET_H_
 #define _WX_PRIVATE_SOCKET_H_
 
+#include "wx/defs.h"
+
+#if wxUSE_SOCKETS
+
+#include "wx/socket.h"
+
+#include <stddef.h>
+
+/*
+   Including sys/types.h under Cygwin results in the warnings about "fd_set
+   having been defined in sys/types.h" when winsock.h is included later and
+   doesn't seem to be necessary anyhow. It's not needed under Mac neither.
+ */
+#if !defined(__WXMAC__) && !defined(__CYGWIN__) && !defined(__WXWINCE__)
+#include <sys/types.h>
+#endif
+
+#ifdef __WXWINCE__
+#include <stdlib.h>
+#endif
+
+// include the header defining timeval: under Windows this struct is used only
+// with sockets so we need to include winsock.h which we do via windows.h
+#ifdef __WXMSW__
+    #include "wx/msw/wrapwin.h"
+#else
+    #include <sys/time.h>   // for timeval
+#endif
+
 // these definitions are for MSW when we don't use configure, otherwise these
 // symbols are defined by configure
 #ifndef WX_SOCKLEN_T
 
 // define some symbols which winsock.h defines but traditional BSD headers
 // don't
+#ifndef SOCKET
+    #define SOCKET int
+#endif
+
 #ifndef INVALID_SOCKET
     #define INVALID_SOCKET (-1)
 #endif
     typedef struct sockaddr wxSockAddr;
 #endif
 
-#endif // _WX_PRIVATE_SOCKET_H_
+enum GAddressType
+{
+    wxSOCKET_NOFAMILY = 0,
+    wxSOCKET_INET,
+    wxSOCKET_INET6,
+    wxSOCKET_UNIX
+};
+
+typedef int wxSocketEventFlags;
+
+struct GAddress;
+class wxSocketImpl;
+
+/*
+   Class providing hooks abstracting the differences between console and GUI
+   applications for socket code.
+
+   We also have different implementations of this class for different platforms
+   allowing us to keep more things in the common code but the main reason for
+   its existence is that we want the same socket code work differently
+   depending on whether it's used from a console or a GUI program. This is
+   achieved by implementing the virtual methods of this class differently in
+   the objects returned by wxConsoleAppTraits::GetSocketManager() and the same
+   method in wxGUIAppTraits.
+ */
+class wxSocketManager
+{
+public:
+    // set the manager to use, we don't take ownership of it
+    //
+    // this should be called before creating the first wxSocket object,
+    // otherwise the manager returned by wxAppTraits::GetSocketManager() will
+    // be used
+    static void Set(wxSocketManager *manager);
+
+    // return the manager to use
+    //
+    // this initializes the manager at first use
+    static wxSocketManager *Get()
+    {
+        if ( !ms_manager )
+            Init();
+
+        return ms_manager;
+    }
+
+    // called before the first wxSocket is created and should do the
+    // initializations needed in order to use the network
+    //
+    // return true if initialized successfully; if this returns false sockets
+    // can't be used at all
+    virtual bool OnInit() = 0;
+
+    // undo the initializations of OnInit()
+    virtual void OnExit() = 0;
+
+
+    // these functions enable or disable monitoring of the given socket for the
+    // specified events inside the currently running event loop (but notice
+    // that both BSD and Winsock implementations actually use socket->m_server
+    // value to determine what exactly should be monitored so it needs to be
+    // set before calling these functions)
+    virtual void Install_Callback(wxSocketImpl *socket,
+                                  wxSocketNotify event = wxSOCKET_MAX_EVENT) = 0;
+    virtual void Uninstall_Callback(wxSocketImpl *socket,
+                                    wxSocketNotify event = wxSOCKET_MAX_EVENT) = 0;
+
+    virtual ~wxSocketManager() { }
+
+private:
+    // get the manager to use if we don't have it yet
+    static void Init();
+
+    static wxSocketManager *ms_manager;
+};
+
+/*
+    Base class for all socket implementations providing functionality common to
+    BSD and Winsock sockets.
+
+    Objects of this class are not created directly but only via its static
+    Create() method which is implemented in port-specific code.
+ */
+class wxSocketImpl
+{
+public:
+    // static factory function: creates the low-level socket associated with
+    // the given wxSocket (and inherits its attributes such as timeout)
+    static wxSocketImpl *Create(wxSocketBase& wxsocket);
+
+    virtual ~wxSocketImpl();
+
+    // set various socket properties: all of those can only be called before
+    // creating the socket
+    void SetTimeout(unsigned long millisec);
+    void SetNonBlocking(bool non_blocking) { m_non_blocking = non_blocking; }
+    void SetReusable() { m_reusable = true; }
+    void SetBroadcast() { m_broadcast = true; }
+    void DontDoBind() { m_dobind = false; }
+    void SetInitialSocketBuffers(int recv, int send)
+    {
+        m_initialRecvBufferSize = recv;
+        m_initialSendBufferSize = send;
+    }
+
+    wxSocketError SetLocal(GAddress *address);
+    wxSocketError SetPeer(GAddress *address);
+
+    // accessors
+    // ---------
+
+    GAddress *GetLocal();
+    GAddress *GetPeer();
+
+    wxSocketError GetError() const { return m_error; }
+    bool IsOk() const { return m_error == wxSOCKET_NOERROR; }
+
+
+    // creating/closing the socket
+    // --------------------------
+
+    // notice that SetLocal() must be called before creating the socket using
+    // any of the functions below
+    //
+    // all of Create() functions return wxSOCKET_NOERROR if the operation
+    // completed successfully or one of:
+    //  wxSOCKET_INVSOCK - the socket is in use.
+    //  wxSOCKET_INVADDR - the local (server) or peer (client) address has not
+    //                     been set.
+    //  wxSOCKET_IOERR   - any other error.
+
+    // create a socket listening on the local address specified by SetLocal()
+    // (notice that DontDoBind() is ignored by this function)
+    wxSocketError CreateServer();
+
+    // create a socket connected to the peer address specified by SetPeer()
+    // (notice that DontDoBind() is ignored by this function)
+    //
+    // this function may return wxSOCKET_WOULDBLOCK in addition to the return
+    // values listed above
+    wxSocketError CreateClient();
+
+    // create (and bind unless DontDoBind() had been called) an UDP socket
+    // associated with the given local address
+    wxSocketError CreateUDP();
+
+    // may be called whether the socket was created or not, calls DoClose() if
+    // it was indeed created
+    void Close();
+
+    virtual void Shutdown();
+
+
+    // IO operations
+    // -------------
+
+    virtual int Read(char *buffer, int size) = 0;
+    virtual int Write(const char *buffer, int size) = 0;
+
+    wxSocketEventFlags Select(wxSocketEventFlags flags);
+
+    virtual wxSocketImpl *WaitConnection(wxSocketBase& wxsocket) = 0;
+
+
+    // notifications
+    // -------------
+
+    // notify m_wxsocket about the given socket event by calling its (inaptly
+    // named) OnRequest() method
+    void NotifyOnStateChange(wxSocketNotify event);
+
+    // FIXME: this one probably isn't needed here at all
+    virtual void Notify(bool WXUNUSED(notify)) { }
+
+    // TODO: make these fields protected and provide accessors for those of
+    //       them that wxSocketBase really needs
+//protected:
+    SOCKET m_fd;
+
+    int m_initialRecvBufferSize;
+    int m_initialSendBufferSize;
+
+    GAddress *m_local;
+    GAddress *m_peer;
+    wxSocketError m_error;
+
+    bool m_non_blocking;
+    bool m_server;
+    bool m_stream;
+    bool m_establishing;
+    bool m_reusable;
+    bool m_broadcast;
+    bool m_dobind;
+
+    struct timeval m_timeout;
+
+    wxSocketEventFlags m_detected;
+
+protected:
+    wxSocketImpl(wxSocketBase& wxsocket);
+
+private:
+    // handle the given connect() return value (which may be 0 or EWOULDBLOCK
+    // or something else)
+    virtual wxSocketError DoHandleConnect(int ret) = 0;
+
+    // called by Close() if we have a valid m_fd
+    virtual void DoClose() = 0;
+
+    // put this socket into non-blocking mode and enable monitoring this socket
+    // as part of the event loop
+    virtual void UnblockAndRegisterWithEventLoop() = 0;
+
+    // check that the socket wasn't created yet and that the given address
+    // (either m_local or m_peer depending on the socket kind) is valid and
+    // set m_error and return false if this is not the case
+    bool PreCreateCheck(GAddress *addr);
+
+    // set the given socket option: this just wraps setsockopt(SOL_SOCKET)
+    int SetSocketOption(int optname, int optval)
+    {
+        // although modern Unix systems use "const void *" for the 4th
+        // parameter here, old systems and Winsock still use "const char *"
+        return setsockopt(m_fd, SOL_SOCKET, optname,
+                          reinterpret_cast<const char *>(&optval),
+                          sizeof(optval));
+    }
+
+    // set the given socket option to true value: this is an even simpler
+    // wrapper for setsockopt(SOL_SOCKET) for boolean options
+    int EnableSocketOption(int optname)
+    {
+        return SetSocketOption(optname, 1);
+    }
+
+    // apply the options to the (just created) socket and register it with the
+    // event loop by calling UnblockAndRegisterWithEventLoop()
+    void PostCreation();
+
+    // update local address after binding/connecting
+    wxSocketError UpdateLocalAddress();
+
+
+    // set in ctor and never changed except that it's reset to NULL when the
+    // socket is shut down
+    wxSocketBase *m_wxsocket;
+
+    DECLARE_NO_COPY_CLASS(wxSocketImpl)
+};
+
+#if defined(__WXMSW__)
+    #include "wx/msw/gsockmsw.h"
+#else
+    #include "wx/unix/private/sockunix.h"
+#endif
+
+
+/* GAddress */
+
+// TODO: make GAddress a real class instead of this mix of C and C++
+
+// Represents a socket endpoint, i.e. -- in spite of its name -- not an address
+// but an (address, port) pair
+struct GAddress
+{
+    struct sockaddr *m_addr;
+    size_t m_len;
+
+    GAddressType m_family;
+    int m_realfamily;
+
+    wxSocketError m_error;
+};
+
+GAddress *GAddress_new();
+GAddress *GAddress_copy(GAddress *address);
+void GAddress_destroy(GAddress *address);
+
+void GAddress_SetFamily(GAddress *address, GAddressType type);
+GAddressType GAddress_GetFamily(GAddress *address);
+
+/* The use of any of the next functions will set the address family to
+ * the specific one. For example if you use GAddress_INET_SetHostName,
+ * address family will be implicitly set to AF_INET.
+ */
+
+wxSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname);
+wxSocketError GAddress_INET_SetBroadcastAddress(GAddress *address);
+wxSocketError GAddress_INET_SetAnyAddress(GAddress *address);
+wxSocketError GAddress_INET_SetHostAddress(GAddress *address,
+                                          unsigned long hostaddr);
+wxSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
+                                       const char *protocol);
+wxSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port);
+
+wxSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname,
+                                       size_t sbuf);
+unsigned long GAddress_INET_GetHostAddress(GAddress *address);
+unsigned short GAddress_INET_GetPort(GAddress *address);
+
+wxSocketError _GAddress_translate_from(GAddress *address,
+                                      struct sockaddr *addr, int len);
+wxSocketError _GAddress_translate_to  (GAddress *address,
+                                      struct sockaddr **addr, int *len);
+wxSocketError _GAddress_Init_INET(GAddress *address);
+
+#if wxUSE_IPV6
+
+wxSocketError GAddress_INET6_SetHostName(GAddress *address, const char *hostname);
+wxSocketError GAddress_INET6_SetAnyAddress(GAddress *address);
+wxSocketError GAddress_INET6_SetHostAddress(GAddress *address,
+                                          struct in6_addr hostaddr);
+wxSocketError GAddress_INET6_SetPortName(GAddress *address, const char *port,
+                                       const char *protocol);
+wxSocketError GAddress_INET6_SetPort(GAddress *address, unsigned short port);
+
+wxSocketError GAddress_INET6_GetHostName(GAddress *address, char *hostname,
+                                       size_t sbuf);
+wxSocketError GAddress_INET6_GetHostAddress(GAddress *address,struct in6_addr *hostaddr);
+unsigned short GAddress_INET6_GetPort(GAddress *address);
+
+#endif // wxUSE_IPV6
+
+// these functions are available under all platforms but only implemented under
+// Unix ones, elsewhere they just return wxSOCKET_INVADDR
+wxSocketError _GAddress_Init_UNIX(GAddress *address);
+wxSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path);
+wxSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf);
+
+#endif /* wxUSE_SOCKETS */
 
+#endif /* _WX_PRIVATE_SOCKET_H_ */