This change prepares the way for using wxGTK under Windows as this would still define __WINDOWS__ but use __WXGTK__ instead of __WXMSW__. Closes #14064. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@70796 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			325 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			325 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
///////////////////////////////////////////////////////////////////////////////
 | 
						|
// Name:        wx/private/sckaddr.h
 | 
						|
// Purpose:     wxSockAddressImpl
 | 
						|
// Author:      Vadim Zeitlin
 | 
						|
// Created:     2008-12-28
 | 
						|
// RCS-ID:      $Id$
 | 
						|
// Copyright:   (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
 | 
						|
// Licence:     wxWindows licence
 | 
						|
///////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
#ifndef _WX_PRIVATE_SOCKADDR_H_
 | 
						|
#define _WX_PRIVATE_SOCKADDR_H_
 | 
						|
 | 
						|
#ifdef __WINDOWS__
 | 
						|
    #include "wx/msw/wrapwin.h"
 | 
						|
 | 
						|
    #if wxUSE_IPV6
 | 
						|
        #include <ws2tcpip.h>
 | 
						|
    #endif
 | 
						|
#elif defined(__VMS__)
 | 
						|
    #include <socket.h>
 | 
						|
 | 
						|
    struct sockaddr_un
 | 
						|
    {
 | 
						|
        u_char  sun_len;        /* sockaddr len including null */
 | 
						|
        u_char  sun_family;     /* AF_UNIX */
 | 
						|
        char    sun_path[108];  /* path name (gag) */
 | 
						|
    };
 | 
						|
    #include <in.h>
 | 
						|
#else // generic Unix
 | 
						|
    #include <sys/types.h>
 | 
						|
    #include <sys/socket.h>
 | 
						|
    #include <netinet/in.h>
 | 
						|
    #include <sys/un.h>
 | 
						|
#endif // platform
 | 
						|
 | 
						|
#include <stdlib.h> // for calloc()
 | 
						|
 | 
						|
// this is a wrapper for sockaddr_storage if it's available or just sockaddr
 | 
						|
// otherwise
 | 
						|
union wxSockAddressStorage
 | 
						|
{
 | 
						|
#if wxUSE_IPV6
 | 
						|
    sockaddr_storage addr_storage;
 | 
						|
#endif
 | 
						|
    sockaddr addr;
 | 
						|
};
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// helpers for wxSockAddressImpl
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
// helper class mapping sockaddr_xxx types to corresponding AF_XXX values
 | 
						|
//
 | 
						|
// FIXME-VC6: we could leave the template undefined if not for VC6 which
 | 
						|
//            absolutely does need to have a generic version defining the
 | 
						|
//            template "interface" to compile the code below
 | 
						|
template <class T> struct AddressFamily { enum { value = AF_UNSPEC }; };
 | 
						|
 | 
						|
template <> struct AddressFamily<sockaddr_in> { enum { value = AF_INET }; };
 | 
						|
 | 
						|
#if wxUSE_IPV6
 | 
						|
template <> struct AddressFamily<sockaddr_in6> { enum { value = AF_INET6 }; };
 | 
						|
#endif // wxUSE_IPV6
 | 
						|
 | 
						|
#ifdef wxHAS_UNIX_DOMAIN_SOCKETS
 | 
						|
template <> struct AddressFamily<sockaddr_un> { enum { value = AF_UNIX }; };
 | 
						|
#endif // wxHAS_UNIX_DOMAIN_SOCKETS
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// wxSockAddressImpl
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
// Represents a socket endpoint, e.g. an (address, port) pair for PF_INET
 | 
						|
// sockets. It can be initialized from an existing sockaddr struct and also
 | 
						|
// provides access to sockaddr stored internally so that it can be easily used
 | 
						|
// with e.g. connect(2).
 | 
						|
//
 | 
						|
// This class also performs (synchronous, hence potentially long) name lookups
 | 
						|
// if necessary, i.e. if the host name strings don't contain addresses in
 | 
						|
// numerical form (quad dotted for IPv4 or standard hexadecimal for IPv6).
 | 
						|
// Notice that internally the potentially Unicode host names are encoded as
 | 
						|
// UTF-8 before being passed to the lookup function but the host names should
 | 
						|
// really be ASCII anyhow.
 | 
						|
class wxSockAddressImpl
 | 
						|
{
 | 
						|
public:
 | 
						|
    // as this is passed to socket() it should be a PF_XXX and not AF_XXX (even
 | 
						|
    // though they're the same in practice)
 | 
						|
    enum Family
 | 
						|
    {
 | 
						|
        FAMILY_INET = PF_INET,
 | 
						|
#if wxUSE_IPV6
 | 
						|
        FAMILY_INET6 = PF_INET6,
 | 
						|
#endif
 | 
						|
#ifdef wxHAS_UNIX_DOMAIN_SOCKETS
 | 
						|
        FAMILY_UNIX = PF_UNIX,
 | 
						|
#endif
 | 
						|
        FAMILY_UNSPEC = PF_UNSPEC
 | 
						|
    };
 | 
						|
 | 
						|
    // default ctor creates uninitialized object, use one of CreateXXX() below
 | 
						|
    wxSockAddressImpl()
 | 
						|
    {
 | 
						|
        InitUnspec();
 | 
						|
    }
 | 
						|
 | 
						|
    // ctor from an existing sockaddr
 | 
						|
    wxSockAddressImpl(const sockaddr& addr, int len)
 | 
						|
    {
 | 
						|
        switch ( addr.sa_family )
 | 
						|
        {
 | 
						|
            case PF_INET:
 | 
						|
#if wxUSE_IPV6
 | 
						|
            case PF_INET6:
 | 
						|
#endif
 | 
						|
#ifdef wxHAS_UNIX_DOMAIN_SOCKETS
 | 
						|
            case PF_UNIX:
 | 
						|
#endif
 | 
						|
                m_family = static_cast<Family>(addr.sa_family);
 | 
						|
                break;
 | 
						|
 | 
						|
            default:
 | 
						|
                wxFAIL_MSG( "unsupported socket address family" );
 | 
						|
                InitUnspec();
 | 
						|
                return;
 | 
						|
        }
 | 
						|
 | 
						|
        InitFromSockaddr(addr, len);
 | 
						|
    }
 | 
						|
 | 
						|
    // copy ctor and assignment operators
 | 
						|
    wxSockAddressImpl(const wxSockAddressImpl& other)
 | 
						|
    {
 | 
						|
        InitFromOther(other);
 | 
						|
    }
 | 
						|
 | 
						|
    wxSockAddressImpl& operator=(const wxSockAddressImpl& other)
 | 
						|
    {
 | 
						|
        if (this != &other)
 | 
						|
        {
 | 
						|
            free(m_addr);
 | 
						|
            InitFromOther(other);
 | 
						|
        }
 | 
						|
        return *this;
 | 
						|
    }
 | 
						|
 | 
						|
    // dtor frees the memory used by m_addr
 | 
						|
    ~wxSockAddressImpl()
 | 
						|
    {
 | 
						|
        free(m_addr);
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    // reset the address to the initial uninitialized state
 | 
						|
    void Clear()
 | 
						|
    {
 | 
						|
        free(m_addr);
 | 
						|
 | 
						|
        InitUnspec();
 | 
						|
    }
 | 
						|
 | 
						|
    // initialize the address to be of specific address family, it must be
 | 
						|
    // currently uninitialized (you may call Clear() to achieve this)
 | 
						|
    void CreateINET();
 | 
						|
    void CreateINET6();
 | 
						|
#ifdef wxHAS_UNIX_DOMAIN_SOCKETS
 | 
						|
    void CreateUnix();
 | 
						|
#endif // wxHAS_UNIX_DOMAIN_SOCKETS
 | 
						|
    void Create(Family family)
 | 
						|
    {
 | 
						|
        switch ( family )
 | 
						|
        {
 | 
						|
            case FAMILY_INET:
 | 
						|
                CreateINET();
 | 
						|
                break;
 | 
						|
 | 
						|
#if wxUSE_IPV6
 | 
						|
            case FAMILY_INET6:
 | 
						|
                CreateINET6();
 | 
						|
                break;
 | 
						|
#endif // wxUSE_IPV6
 | 
						|
 | 
						|
#ifdef wxHAS_UNIX_DOMAIN_SOCKETS
 | 
						|
            case FAMILY_UNIX:
 | 
						|
                CreateUnix();
 | 
						|
                break;
 | 
						|
#endif // wxHAS_UNIX_DOMAIN_SOCKETS
 | 
						|
 | 
						|
            default:
 | 
						|
                wxFAIL_MSG( "unsupported socket address family" );
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    // simple accessors
 | 
						|
    Family GetFamily() const { return m_family; }
 | 
						|
    bool Is(Family family) const { return m_family == family; }
 | 
						|
    bool IsOk() const { return m_family != FAMILY_UNSPEC; }
 | 
						|
    const sockaddr *GetAddr() const { return m_addr; }
 | 
						|
    sockaddr *GetWritableAddr() { return m_addr; }
 | 
						|
    int GetLen() const { return m_len; }
 | 
						|
 | 
						|
    // accessors for INET or INET6 address families
 | 
						|
#if wxUSE_IPV6
 | 
						|
    #define CALL_IPV4_OR_6(func, args) \
 | 
						|
        Is(FAMILY_INET6) ? func##6(args) : func##4(args)
 | 
						|
    #define CALL_IPV4_OR_6_VOID(func) \
 | 
						|
        Is(FAMILY_INET6) ? func##6() : func##4()
 | 
						|
#else
 | 
						|
    #define CALL_IPV4_OR_6(func, args) func##4(args)
 | 
						|
    #define CALL_IPV4_OR_6_VOID(func) func##4()
 | 
						|
#endif // IPv6 support on/off
 | 
						|
 | 
						|
    wxString GetHostName() const;
 | 
						|
    bool SetHostName(const wxString& name)
 | 
						|
    {
 | 
						|
        return CALL_IPV4_OR_6(SetHostName, (name));
 | 
						|
    }
 | 
						|
 | 
						|
    wxUint16 GetPort() const { return CALL_IPV4_OR_6_VOID(GetPort); }
 | 
						|
    bool SetPort(wxUint16 port) { return CALL_IPV4_OR_6(SetPort, (port)); }
 | 
						|
    bool SetPortName(const wxString& name, const char *protocol);
 | 
						|
 | 
						|
    bool SetToAnyAddress() { return CALL_IPV4_OR_6_VOID(SetToAnyAddress); }
 | 
						|
 | 
						|
#undef CALL_IPV4_OR_6
 | 
						|
 | 
						|
    // accessors for INET addresses only
 | 
						|
    bool GetHostAddress(wxUint32 *address) const;
 | 
						|
    bool SetHostAddress(wxUint32 address);
 | 
						|
 | 
						|
    bool SetToBroadcastAddress() { return SetHostAddress(INADDR_BROADCAST); }
 | 
						|
 | 
						|
    // accessors for INET6 addresses only
 | 
						|
#if wxUSE_IPV6
 | 
						|
    bool GetHostAddress(in6_addr *address) const;
 | 
						|
    bool SetHostAddress(const in6_addr& address);
 | 
						|
#endif // wxUSE_IPV6
 | 
						|
 | 
						|
#ifdef wxHAS_UNIX_DOMAIN_SOCKETS
 | 
						|
    // methods valid for Unix address family addresses only
 | 
						|
    bool SetPath(const wxString& path);
 | 
						|
    wxString GetPath() const;
 | 
						|
#endif // wxHAS_UNIX_DOMAIN_SOCKETS
 | 
						|
 | 
						|
private:
 | 
						|
    void DoAlloc(int len)
 | 
						|
    {
 | 
						|
        m_addr = static_cast<sockaddr *>(calloc(1, len));
 | 
						|
        m_len = len;
 | 
						|
    }
 | 
						|
 | 
						|
    // FIXME-VC6: VC6 doesn't grok Foo<T>() call syntax so we need the extra
 | 
						|
    //            dummy parameter of type T, use the macros in sckaddr.cpp to
 | 
						|
    //            hide it
 | 
						|
    template <class T>
 | 
						|
    T *Alloc(T *)
 | 
						|
    {
 | 
						|
        DoAlloc(sizeof(T));
 | 
						|
 | 
						|
        return reinterpret_cast<T *>(m_addr);
 | 
						|
    }
 | 
						|
 | 
						|
    template <class T>
 | 
						|
    T *Get(T *) const
 | 
						|
    {
 | 
						|
        wxCHECK_MSG( static_cast<int>(m_family) == AddressFamily<T>::value,
 | 
						|
                     NULL,
 | 
						|
                     "socket address family mismatch" );
 | 
						|
 | 
						|
        return reinterpret_cast<T *>(m_addr);
 | 
						|
    }
 | 
						|
 | 
						|
    void InitUnspec()
 | 
						|
    {
 | 
						|
        m_family = FAMILY_UNSPEC;
 | 
						|
        m_addr = NULL;
 | 
						|
        m_len = 0;
 | 
						|
    }
 | 
						|
 | 
						|
    void InitFromSockaddr(const sockaddr& addr, int len)
 | 
						|
    {
 | 
						|
        DoAlloc(len);
 | 
						|
        memcpy(m_addr, &addr, len);
 | 
						|
    }
 | 
						|
 | 
						|
    void InitFromOther(const wxSockAddressImpl& other)
 | 
						|
    {
 | 
						|
        m_family = other.m_family;
 | 
						|
 | 
						|
        if ( other.m_addr )
 | 
						|
        {
 | 
						|
            InitFromSockaddr(*other.m_addr, other.m_len);
 | 
						|
        }
 | 
						|
        else // no address to copy
 | 
						|
        {
 | 
						|
            m_addr = NULL;
 | 
						|
            m_len = 0;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    // IPv4/6 implementations of public functions
 | 
						|
    bool SetHostName4(const wxString& name);
 | 
						|
 | 
						|
    bool SetPort4(wxUint16 port);
 | 
						|
    wxUint16 GetPort4() const;
 | 
						|
 | 
						|
    bool SetToAnyAddress4() { return SetHostAddress(INADDR_ANY); }
 | 
						|
 | 
						|
#if wxUSE_IPV6
 | 
						|
    bool SetHostName6(const wxString& name);
 | 
						|
 | 
						|
    bool SetPort6(wxUint16 port);
 | 
						|
    wxUint16 GetPort6() const;
 | 
						|
 | 
						|
    bool SetToAnyAddress6();
 | 
						|
#endif // wxUSE_IPV6
 | 
						|
 | 
						|
    Family m_family;
 | 
						|
    sockaddr *m_addr;
 | 
						|
    int m_len;
 | 
						|
};
 | 
						|
 | 
						|
#endif // _WX_PRIVATE_SOCKADDR_H_
 |