/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



#ifndef _VOS_SOCKET_HXX_
#define _VOS_SOCKET_HXX_

#   include <vos/types.hxx>
#   include <vos/object.hxx>
#   include <vos/istream.hxx>
#ifndef _VOS_REFERMCE_HXX_
#   include <vos/refernce.hxx>
#endif
#   include <vos/refobj.hxx>
#   include <rtl/ustring.hxx>
#   include <osl/socket.h>

#include <osl/time.h>

namespace vos
{

/** Base data types
*/
class ISocketTypes
{
public:

    ISocketTypes() { }
    virtual ~ISocketTypes() { }

    /*
        Represents the address-family of a socket
    */
    enum TAddrFamily {
        TFamily_Inet = osl_Socket_FamilyInet,       /* IP */
        TFamily_Ipx  = osl_Socket_FamilyIpx,        /* Novell IPX/SPX */
        TFamily_Invalid = osl_Socket_FamilyInvalid
    };

    /*
        represent a specific protocol within a address-family
    */
    enum TProtocol {
        TProtocol_Ip    = osl_Socket_ProtocolIp,        /* for all af_inet */
        TProtocol_Ipx   = osl_Socket_ProtocolIpx,       /* af_ipx datagram sockets (IPX) */
        TProtocol_Spx   = osl_Socket_ProtocolSpx,       /* af_ipx seqpacket or stream for SPX */
        TProtocol_SpxII = osl_Socket_ProtocolSpxII,     /* af_ipx seqpacket or stream for SPX II */
        TProtocol_Invalid = osl_Socket_ProtocolInvalid
    };

    /*
        Represents the type of a socket
    */
    enum TSocketType {
        TType_Stream    = osl_Socket_TypeStream,
        TType_Dgram     = osl_Socket_TypeDgram,
        TType_Raw       = osl_Socket_TypeRaw,
        TType_Rdm       = osl_Socket_TypeRdm,
        TType_SeqPacket = osl_Socket_TypeSeqPacket,
        TType_Invalid = osl_Socket_TypeInvalid
    };

    /*
        Represents socket-options
    */
    enum TSocketOption {
        TOption_Debug       = osl_Socket_OptionDebug,
        TOption_AcceptConn  = osl_Socket_OptionAcceptConn,
        TOption_ReuseAddr   = osl_Socket_OptionReuseAddr,
        TOption_KeepAlive   = osl_Socket_OptionKeepAlive,
        TOption_DontRoute   = osl_Socket_OptionDontRoute,
        TOption_Broadcast   = osl_Socket_OptionBroadcast,
        TOption_UseLoopback = osl_Socket_OptionUseLoopback,
        TOption_Linger      = osl_Socket_OptionLinger,
        TOption_OOBinLine   = osl_Socket_OptionOOBinLine,
        TOption_SndBuf      = osl_Socket_OptionSndBuf,
        TOption_RcvBuf      = osl_Socket_OptionRcvBuf,
        TOption_SndLowat    = osl_Socket_OptionSndLowat,
        TOption_RcvLowat    = osl_Socket_OptionRcvLowat,
        TOption_SndTimeo    = osl_Socket_OptionSndTimeo,
        TOption_RcvTimeo    = osl_Socket_OptionRcvTimeo,
        TOption_Error       = osl_Socket_OptionError,
        TOption_Type        = osl_Socket_OptionType,
        TOption_TcpNoDelay  = osl_Socket_OptionTcpNoDelay,
        TOption_Invalid     = osl_Socket_OptionInvalid
    };

    /*
        Represents the different socket-option levels
    */
    enum TSocketOptionLevel {
        TLevel_Socket = osl_Socket_LevelSocket,
        TLevel_Tcp    = osl_Socket_LevelTcp,
        TLevel_Invalid = osl_Socket_LevelInvalid
    };

    /*
        Represents flags to be used with send/recv-calls.
    */
    enum TSocketMsgFlag {
        TMsg_Normal    = osl_Socket_MsgNormal,
        TMsg_OOB       = osl_Socket_MsgOOB,
        TMsg_Peek      = osl_Socket_MsgPeek,
        TMsg_DontRoute = osl_Socket_MsgDontRoute,
        TMsg_MaxIOVLen = osl_Socket_MsgMaxIOVLen,
        TMsg_Invalid   = osl_Socket_MsgInvalid
    };

    /*
        Used by shutdown to denote which end of the socket to "close".
    */
    enum TSocketDirection {
        TDirection_Read      = osl_Socket_DirRead,
        TDirection_Write     = osl_Socket_DirWrite,
        TDirection_ReadWrite = osl_Socket_DirReadWrite,
        TDirection_Invalid   = osl_Socket_DirInvalid
    };

    enum TSocketError {
        E_None              = osl_Socket_E_None,              /* no error */
        E_NotSocket         = osl_Socket_E_NotSocket,         /* Socket operation on non-socket */
        E_DestAddrReq       = osl_Socket_E_DestAddrReq,       /* Destination address required */
        E_MsgSize           = osl_Socket_E_MsgSize,           /* Message too sal_Int32 */
        E_Prototype         = osl_Socket_E_Prototype,         /* Protocol wrong type for socket */
        E_NoProtocol        = osl_Socket_E_NoProtocol,        /* Protocol not available */
        E_ProtocolNoSupport = osl_Socket_E_ProtocolNoSupport, /* Protocol not supported */
        E_TypeNoSupport     = osl_Socket_E_TypeNoSupport,     /* Socket type not supported */
        E_OpNotSupport      = osl_Socket_E_OpNotSupport,      /* Operation not supported on socket */
        E_PfNoSupport       = osl_Socket_E_PfNoSupport,       /* Protocol family not supported */
        E_AfNoSupport       = osl_Socket_E_AfNoSupport,       /* Address family not supported by */
                                                              /* protocol family */
        E_AddrInUse         = osl_Socket_E_AddrInUse,         /* Address already in use */
        E_AddrNotAvail      = osl_Socket_E_AddrNotAvail,      /* Can't assign requested address */
        E_NetDown           = osl_Socket_E_NetDown,           /* Network is down */
        E_NetUnreachable    = osl_Socket_E_NetUnreachable,    /* Network is unreachable */
        E_NetReset          = osl_Socket_E_NetReset,          /* Network dropped connection because */
                                                              /* of reset */
        E_ConnAborted       = osl_Socket_E_ConnAborted,       /* Software caused connection abort */
        E_ConnReset         = osl_Socket_E_ConnReset,         /* Connection reset by peer */
        E_NoBufferSpace     = osl_Socket_E_NoBufferSpace,     /* No buffer space available */
        E_IsConnected       = osl_Socket_E_IsConnected,       /* Socket is already connected */
        E_NotConnected      = osl_Socket_E_NotConnected,      /* Socket is not connected */
        E_Shutdown          = osl_Socket_E_Shutdown,          /* Can't send after socket shutdown */
        E_TooManyRefs       = osl_Socket_E_TooManyRefs,       /* Too many references: can't splice */
        E_TimedOut          = osl_Socket_E_TimedOut,          /* Connection timed out */
        E_ConnRefused       = osl_Socket_E_ConnRefused,       /* Connection refused */
        E_HostDown          = osl_Socket_E_HostDown,          /* Host is down */
        E_HostUnreachable   = osl_Socket_E_HostUnreachable,   /* No route to host */
        E_WouldBlock        = osl_Socket_E_WouldBlock,        /* call would block on non-blocking socket */
        E_Already           = osl_Socket_E_Already,           /* operation already in progress */
        E_InProgress        = osl_Socket_E_InProgress,        /* operation now in progress */

        E_Invalid = osl_Socket_E_InvalidError   /* unmapped error */
    };

    enum TResult {
        TResult_Ok          = osl_Socket_Ok,          /* successful completion */
        TResult_Error       = osl_Socket_Error,       /* error occurred, check osl_getLastSocketError() for details */
        TResult_TimedOut    = osl_Socket_TimedOut,    /* blocking operation timed out */
        TResult_Interrupted = osl_Socket_Interrupted, /* blocking operation was interrupted */
        TResult_InProgress  = osl_Socket_InProgress   /* nonblocking operation is in progress */
    };
};


/** Base class for socket addresses.
*/
class ISocketAddr : public vos::ISocketTypes
{
public:
    virtual ~ISocketAddr() { }


    virtual TAddrFamily SAL_CALL getFamily() const= 0;
    virtual TResult SAL_CALL getHostname(::rtl::OUString& strHostName) const= 0;
    virtual SAL_CALL operator oslSocketAddr() const= 0;
    virtual void SAL_CALL operator= (oslSocketAddr Addr)= 0;
    virtual sal_Bool SAL_CALL operator== (oslSocketAddr Addr)= 0;
};

class OSocketAddr : public vos::ISocketAddr,
            public vos::OObject

{
    VOS_DECLARE_CLASSINFO(vos::OSocketAddr);
public:

    /** Creates socket address of unknown type.
    */
    OSocketAddr();

    /** Copy constructor.
    */
    OSocketAddr(const OSocketAddr& Addr);

    /**
    */
    OSocketAddr(oslSocketAddr Addr);

    /** destroys underlying oslSocketAddress
    */
    virtual ~OSocketAddr();

    /** Queries the socket for its address family.
        @return the address family of the socket.
    */
    virtual TAddrFamily SAL_CALL getFamily() const;

    /** Cast Object to the underlying oslSocketAddr.
    */
    virtual SAL_CALL operator oslSocketAddr() const;

    /** Converts the address to a (human readable) domain-name.
        @return the hostname represented by the address.
        On failure returns the empty string.
    */
    virtual TResult SAL_CALL getHostname(::rtl::OUString& strHostName) const;

    /** Get the hostname for the local interface.
        @return the hostname or an error.
    */
    static TResult SAL_CALL getLocalHostname(::rtl::OUString& strLocalHostName);

    /** Tries to find an address for a host.
        @return A new created socket-address or 0 if the name could not be found.
    */
    static oslSocketAddr SAL_CALL resolveHostname(const ::rtl::OUString& strHostName);

    /** Wraps itself around the osl Socket-Address.
        The object assumes ownership of the Addr, it
        will be destroyed by destructor(). If the socket is already attached to
        an oslSocketAddr, the existing one will be destroyed.
    */
    virtual void SAL_CALL operator= (oslSocketAddr Addr);

    /** Compares to Addr
    */
    virtual sal_Bool SAL_CALL operator== (oslSocketAddr Addr);

    /** Makes a copy of Addr.
    */
    OSocketAddr& SAL_CALL operator= (const OSocketAddr& Addr);


protected:

    oslSocketAddr m_SockAddr;
};


/** Represents an internet-address.
*/
class OInetSocketAddr : public vos::OSocketAddr
{
    VOS_DECLARE_CLASSINFO(vos::OInetSocketAddr);
public:

    /** Creates an empty internet-address (INADDR_ANY).
    */
    OInetSocketAddr();

    /** Wraps itself around the osl Socket-Address.
        The object assumes ownership of the Addr, it
        will be destroyed by ~OInetSocketAddr().
    */
    OInetSocketAddr(oslSocketAddr Addr);

    /**
        Create a socket address either from a dotted decimal address
        (e.g. 141.99.128.50) or a hostname (e.g. www.stardiv.de).
    */
    OInetSocketAddr(const ::rtl::OUString& strAddrOrHostName, sal_Int32 Port);

    /**
        Copy constructor.
    */
    OInetSocketAddr(const OInetSocketAddr& Addr);

    /**
    */
    OInetSocketAddr(const OSocketAddr& Addr);


    virtual ~OInetSocketAddr();

    /**
    */
    virtual void SAL_CALL operator= (oslSocketAddr Addr);

    /**
    */
    virtual sal_Bool SAL_CALL operator== (oslSocketAddr Addr);

    /**
    */
    OInetSocketAddr& SAL_CALL operator= (const OInetSocketAddr& Addr);

    /**
    */
    OInetSocketAddr& SAL_CALL operator= (const OSocketAddr& Addr);

    /**
        Tries to find the port associated with the given service/protocol-
        pair (e.g. "ftp"/"tcp").
        @return the port number in host-byte order or CVOS_PORT_NONE
        if no service/protocol pair could be found.
    */
    static sal_Int32 SAL_CALL getServicePort(const ::rtl::OUString& strServiceName,
                              const ::rtl::OUString& strProtocolName= ::rtl::OUString::createFromAscii( "tcp" ) );


    /** Delivers the port number of the address.
        @return the port in host-byte order or or OSL_INVALID_PORT on errors.
    */
    sal_Int32   SAL_CALL getPort() const;

    /** Sets the port number of the address.
        @return False if the port couldn't be set
        (e.g because the address is not of family TFamily_Inet).
    */
    sal_Bool    SAL_CALL setPort(sal_Int32 Port);

    /** @return the dotted-address-form (141.99.128.90) of this address.
        On failure returns the empty string.
    */
    TResult SAL_CALL getDottedAddr(::rtl::OUString& strDottedAddr) const;

    /** Sets the host-part of the address from the dotted-address-form (141.99.128.90)
        or from a hostname.
        @param strDottedAddrOrHostname the address in dotted form or a hostname.
    */
    sal_Bool SAL_CALL setAddr(const ::rtl::OUString& strDottedAddrOrHostname);

};

/** Represents an IPX/SPX address.
*/
class OIpxSocketAddr :  public vos::OSocketAddr
{
    VOS_DECLARE_CLASSINFO(vos::OIpxSocketAddr);
public:

    typedef oslSocketIpxNetNumber  TIpxNetNumber;
    typedef oslSocketIpxNodeNumber TIpxNodeNumber;

    /** Creates an empty ipx-address.
    */
    OIpxSocketAddr();

    /** Wraps itself around the osl Socket-Address.
        The object assumes ownership of the Addr, it
        will be destroyed by the destructor.
    */
    OIpxSocketAddr(oslSocketAddr Addr);

    /** Create an IPX/SPX socketaddress from native parameters.
    */
    OIpxSocketAddr(const ::rtl::OUString& strNetNumber,
                   const ::rtl::OUString& strNodeNumber,
                   sal_uInt32 SocketNumber);

    /** Copy constructor.
    */
    OIpxSocketAddr(const OIpxSocketAddr& Addr);

    /**
    */
    OIpxSocketAddr(const OSocketAddr& Addr);

    virtual  ~OIpxSocketAddr();

    /**
    */
    virtual void SAL_CALL operator= (oslSocketAddr Addr);

    /**
    */
    virtual sal_Bool SAL_CALL operator== (oslSocketAddr Addr);

    /**
    */
    OIpxSocketAddr& SAL_CALL operator= (const OIpxSocketAddr& Addr);

    /**
    */
    OIpxSocketAddr& SAL_CALL operator= (const OSocketAddr& Addr);

    /**
    */
    TResult SAL_CALL getNetNumber(TIpxNetNumber& NetNumber) const;

    /**
    */
    TResult SAL_CALL getNodeNumber(TIpxNodeNumber& NodeNumber) const;

    /**
    */
    sal_uInt32 SAL_CALL getSocketNumber() const;

    /** Builds a human readable string in the format network.node:socket.
        The numbers are given in hexadecimal form.
    */
    void SAL_CALL getAddressString(::rtl::OUString& strAddressString) const;
};


/** Represents a socket.
*/
class OSocket : public vos::ISocketTypes,
                public vos::OReference,
                public vos::OObject
{
    VOS_DECLARE_CLASSINFO(vos::OSocket);

protected:
    typedef ORefObj<oslSocket> SockRef;

    SockRef* m_pSockRef;

    TimeValue* m_pSendTimeout;
    TimeValue* m_pRecvTimeout;

public:

    /** Does not create a socket. Use assignment operator to
        make this a useable socket.
    */
    OSocket();

    /** Creates a socket.
        @param Family
        @param Type
        @param Protocol
    */
    OSocket(TSocketType Type,
            TAddrFamily Family = TFamily_Inet,
            TProtocol   Protocol = TProtocol_Ip);

    /** Copy constructor.
    */
    OSocket(const OSocket& sock);

    /** Creates socket as wrapper around the underlying oslSocket.
        @param Socket
    */
    OSocket(oslSocket Socket);

    /** Destructor. Destroys the underlying oslSocket.
    */
    virtual ~OSocket();

    /** Create a socket with the given attributes.
        If socket was already created, the old one will be discarded.
        @param Type
        @param Family
        @param Protocol
        @return True if socket was successfully created.
    */
    sal_Bool SAL_CALL create(TSocketType Type,
                   TAddrFamily Family = TFamily_Inet,
                   TProtocol   Protocol = TProtocol_Ip);

    /** Assignment operator. If socket was already created, the old one will
        be discarded.
    */
    OSocket& SAL_CALL operator= (const OSocket& sock);

    /** Allow cast to underlying oslSocket.
    */
    SAL_CALL operator oslSocket() const;

    /** Checks if the socket is valid.
        @return True if the object represents a valid socket.
    */
    sal_Bool SAL_CALL isValid() const;

    sal_Bool SAL_CALL operator==( const OSocket& rSocket )
    {
        return m_pSockRef == rSocket.m_pSockRef;
    }

    /** Closes the socket.
    */
    virtual void SAL_CALL close();

    /** Retrieves the address of the local interface of this socket.
        @param Addr [out] receives the address.
    */
    void SAL_CALL getLocalAddr(OSocketAddr& Addr) const;

    /** Get the local port of the socket.
        @return the port number or OSL_INVALID_PORT on errors.
    */
    sal_Int32   SAL_CALL getLocalPort() const;

    /** Get the hostname for the local interface.
        @return the hostname or an empty string ("").
    */
    TResult SAL_CALL getLocalHost(::rtl::OUString& strLocalHost) const;

    /** Retrieves the address of the remote host of this socket.
        @param Addr [out] receives the address.
    */
    void SAL_CALL getPeerAddr(OSocketAddr& Addr) const;

    /** Get the remote port of the socket.
        @return the port number or OSL_INVALID_PORT on errors.
    */
    sal_Int32   SAL_CALL getPeerPort() const;

    /** Get the hostname for the remote interface.
        @return the hostname or an empty string ("").
    */
    TResult SAL_CALL getPeerHost(::rtl::OUString& strPeerHost) const;

    /** Binds the socket to the specified (local) interface.
        @param LocalInterface Address of the Interface
        @return True if bind was successful.
    */
    sal_Bool SAL_CALL bind(const OSocketAddr& LocalInterface);


    /** Blocking send operations will unblock after the send-timeout.
        @return 0 for disables timeout else timeout value.
    */
    const TimeValue* SAL_CALL getSendTimeout() const
        { return m_pSendTimeout; }

    /** Blocking receive operations will unblock after the send-timeout.
        @return 0 for disables timeout else timeout value.
    */
    const TimeValue* SAL_CALL getRecvTimeout() const
        { return m_pRecvTimeout; }

    /** Blocking send operations will unblock after the send-timeout.
        @param time pTimeout == 0 disables timeout. pTimeout != 0 sets timeout value.
    */
    void SAL_CALL setSendTimeout(const TimeValue* pTimeout = 0);

    /** Blocking receive operations will unblock after the send-timeout.
        @param time pTimeout == 0 disables timeout. pTimeout != 0 sets timeout value.
    */
    void SAL_CALL setRecvTimeout(const TimeValue* pTimeout = 0);

    /** Checks if read operations will block.
        You can specify a timeout-value in seconds/nanoseconds that denotes
        how sal_Int32 the operation will block if the Socket is not ready.
        @return True if read operations (recv, recvFrom, accept) on the Socket
        will NOT block; False if it would block or if an error occurred.

        @param pTimeout if 0, the operation will block without a timeout. Otherwise
        the specified amout of time.
    */
    sal_Bool    SAL_CALL isRecvReady(const TimeValue* pTimeout = 0) const;

    /** Checks if send operations will block.
        You can specify a timeout-value in seconds/nanoseconds that denotes
        how sal_Int32 the operation will block if the Socket is not ready.
        @return True if send operations (send, sendTo) on the Socket
        will NOT block; False if it would block or if an error occurred.

        @param pTimeout if 0, the operation will block without a timeout. Otherwise
        the specified amout of time.
    */
    sal_Bool    SAL_CALL isSendReady(const TimeValue* pTimeout = 0) const;

    /** Checks if a request for out-of-band data will block.
        You can specify a timeout-value in seconds/nanoseconds that denotes
        how sal_Int32 the operation will block if the Socket has no pending OOB data.

        @return True if OOB-request operations (recv with appropriate flags)
        on the Socket will NOT block; False if it would block or if an error occurred.

        @param pTimeout if 0, the operation will block without a timeout. Otherwise
        the specified amout of time.
    */
    sal_Bool    SAL_CALL isExceptionPending(const TimeValue* pTimeout = 0) const;

    /** Retrieves option-attributes associated with the socket.
        @param Option The attribute to query.
        Valid values (depending on the Level) are:
        <ul>
        <li> TOption_Debug
        <li> TOption_AcceptConn
        <li> TOption_ReuseAddr
        <li> TOption_KeepAlive
        <li> TOption_DontRoute
        <li> TOption_Broadcast
        <li> TOption_UseLoopback
        <li> TOption_Linger
        <li> TOption_OOBinLine
        <li> TOption_SndBuf
        <li> TOption_RcvBuf
        <li> TOption_SndLowat
        <li> TOption_RcvLowat
        <li> TOption_SndTimeo
        <li> TOption_RcvTimeo
        <li> TOption_Error
        <li> TOption_Type
        <li> TOption_TcpNoDelay
        </ul>
        If not above mentioned otherwise, the options are only valid for
        level TLevel_Socket.

        @param pBuffer The Buffer will be filled with the attribute.

        @param BufferSize The size of pBuffer.

        @param Level The option level. Valid values are:
        <ul>
        <li> TLevel_Socket : Socket Level
        <li> TLevel_Tcp    : Level of Transmission Control Protocol
        </ul>

        @return The size of the attribute copied into pBuffer ot -1 if an error
        occurred.
    */
    sal_Int32 SAL_CALL getOption(TSocketOption Option,
                      void* pBuffer,
                      sal_uInt32 BufferLen,
                      TSocketOptionLevel Level= TLevel_Socket) const;

    /** Sets the sockets attributes.

        @param Option denotes the option to modify.
        Valid values (depending on the Level) are:
        <ul>
        <li> TOption_Debug
        <li> TOption_AcceptConn
        <li> TOption_ReuseAddr
        <li> TOption_KeepAlive
        <li> TOption_DontRoute
        <li> TOption_Broadcast
        <li> TOption_UseLoopback
        <li> TOption_Linger
        <li> TOption_OOBinLine
        <li> TOption_SndBuf
        <li> TOption_RcvBuf
        <li> TOption_SndLowat
        <li> TOption_RcvLowat
        <li> TOption_SndTimeo
        <li> TOption_RcvTimeo
        <li> TOption_Error
        <li> TOption_Type
        <li> TOption_TcpNoDelay
        </ul>
        If not above mentioned otherwise, the options are only valid for
        level TLevel_Socket.

        @param pBuffer Pointer to a Buffer which contains the attribute-value.

        @param BufferSize contains the length of the Buffer.

        @param Level selects the level for which an option should be changed.
        Valid values are:
        <ul>
        <li> TLevel_Socket : Socket Level
        <li> TLevel_Tcp    : Level of Transmission Control Protocol
        </ul>

        @return True if the option could be changed.
    */
    sal_Bool SAL_CALL setOption(TSocketOption Option,
                      void* pBuffer,
                      sal_uInt32 BufferLen,
                      TSocketOptionLevel Level= TLevel_Socket) const;


    /** Enables/disables non-blocking mode of the socket.
        @param On If True, non-blocking mode will be switched on, if False
        socket will become a blocking socket, which is the default behaviour of a
        socket.
        @return True if mode could be set.
    */
    sal_Bool SAL_CALL enableNonBlockingMode(sal_Bool On= sal_True);

    /** Query non-blocking mode of the socket.
    @return True if non-blocking mode is set.
    */
    sal_Bool SAL_CALL isNonBlockingMode() const;

    /** Queries the socket for its type.
        @return one of:
        <ul>
        <li> TType_Stream
        <li> TType_Dgram
        <li> TType_Raw
        <li> TType_Rdm
        <li> TType_SeqPacket
        <li> TType_Invalid
        </ul>
    */
    TSocketType SAL_CALL getType() const;


    /** Gets and clears the error status of the socket.
        @returns the current error state.
    */
    sal_Int32   SAL_CALL clearError() const;

    /** Enables/Disables debugging.
        @param opt 1 sets, 0 resets, -1 won't change anything
        @return the previous setting
    */
    sal_Int32   SAL_CALL setDebug(sal_Int32 opt = -1) const;

    /** Allow the socket to be bound to an address that is already in use.
        @param opt 1 sets, 0 resets, -1 won't change anything
        @return the previous setting
    */
    sal_Int32   SAL_CALL setReuseAddr(sal_Int32 opt = -1) const;

    /** Send keepalive-packets.
        @param opt 1 sets, 0 resets, -1 won't change anything
        @return the previous setting
    */
    sal_Int32   SAL_CALL setKeepAlive(sal_Int32 opt = -1) const;

    /** Do not route: send directly to interface.
        @param opt 1 sets, 0 resets, -1 won't change anything
        @return the previous setting
    */
    sal_Int32   SAL_CALL setDontRoute(sal_Int32 opt = -1) const;


    /** Allow transmission of broadcast messages on the socket.
        @param opt 1 sets, 0 resets, -1 won't change anything
        @return the previous setting
    */
    sal_Int32   SAL_CALL setBroadcast(sal_Int32 opt = -1) const;

    /** Receive out-of-band data in the normal data stream.
        @param opt 1 sets, 0 resets, -1 won't change anything
        @return the previous setting
    */
    sal_Int32   SAL_CALL setOobinline(sal_Int32 opt = -1) const;

    /** Linger on close if unsent data is present.
        @param time values > 0 enable lingering with a timeout of time in seconds.
        If time is 0, lingering will be disabled. If time is -1 no changes will occur.
        @return the previous setting (0 == off, > 0 timeout-value in seconds).
    */
    sal_Int32   SAL_CALL setLinger(sal_Int32 time = -1) const;

    /** Specify buffer size for sends.
        You might want to use getOption() to check if the size changes were
        really successful.
        @param size Size >= 0 sets the size, -1 won't change anything.
        @return the previous setting
    */
    sal_Int32   SAL_CALL setSendBufSize(sal_Int32 size =-1) const;

    /** Specify buffer size for receives.
        You might want to use getOption() to check if the size changes were
        really successful.
        @param size Size >= 0 sets the size, -1 won't change anything.
        @return the previous setting
    */
    sal_Int32   SAL_CALL setRecvBufSize(sal_Int32 size =-1) const;

    /** Disables the Nagle algorithm for send coalescing. (Do not
        collect data until a packet is full, instead send immediately.
        This increases network traffic but might improve response-times.)
        @param opt 1 sets, 0 resets, -1 won't change anything
        @return the previous setting
    */
    sal_Int32   SAL_CALL setTcpNoDelay(sal_Int32 sz =-1) const;

    /** Builds a string with the last error-message for the socket.
        @param pBuffer is filled with the error message.
        @param nSize the size of pBuffer. The message will be cut
        sal_Int16 if the buffer isn't large enough, but still remains
        a valid zero-terminated string.
    */
    void SAL_CALL getError(::rtl::OUString& strError) const;

    /** Delivers a constant describing the last error for the socket system.
        @return ENONE if no error occurred, invalid_SocketError if
        an unknown (unmapped) error occurred, otherwise an enum describing the
        error.
    */
    TSocketError SAL_CALL getError() const;

};

/** A socket to send or receive a stream of data.
*/
class OStreamSocket : public vos::OSocket,
                      public vos::IStream
{
    VOS_DECLARE_CLASSINFO(vos::OStreamSocket);
public:

    /** Creates an unattached socket. You must attach the socket to an oslSocket
        e.g. by using the operator=(oslSocket), before you can use the stream-
        functionality of the object.
    */
    OStreamSocket();



    /** Creates socket as wrapper around the underlying oslSocket.
        @param Socket
    */
    OStreamSocket(oslSocket Socket);


    /** Copy constructor.
        @param Socket
    */
    OStreamSocket(const OStreamSocket& Socket);


    /**
    */
    OStreamSocket(const OSocket& Socket);

    /** Destructor. Calls shutdown(readwrite) and close().
    */
    virtual ~OStreamSocket();

    /** Closes the socket after calling shutdown.
    */
    virtual void SAL_CALL close();

    /** Attaches the oslSocket to this object. If the object
        already was attached to an oslSocket, the old one will
        be closed and destroyed.
        @param Socket.
    */
    OStreamSocket& SAL_CALL operator=(oslSocket Socket);

    /**
    */
    OStreamSocket& SAL_CALL operator=(const OSocket& Socket);

    /**
    */
    OStreamSocket& SAL_CALL operator=(const OStreamSocket& Socket);

    /** Retrieves n bytes from the stream and copies them into pBuffer.
        The method avoids incomplete reads due to packet boundaries.
        @param pBuffer receives the read data.
        @param n the number of bytes to read. pBuffer must be large enough
        to hold the n bytes!
        @return the number of read bytes. The number will only be smaller than
        n if an exceptional condition (e.g. connection closed) occurs.
    */
    virtual sal_Int32 SAL_CALL read(void* pBuffer, sal_uInt32 n) const;

    /** Writes n bytes from pBuffer to the stream. The method avoids
        incomplete writes due to packet boundaries.
        @param pBuffer contains the data to be written.
        @param n the number of bytes to write.
        @return the number of written bytes. The number will only be smaller than
        n if an exceptional condition (e.g. connection closed) occurs.
    */
    virtual sal_Int32 SAL_CALL write(const void* pBuffer, sal_uInt32 n);

    /** Checks if socket is closed.
        @return True if socket is closed.
    */
    virtual sal_Bool SAL_CALL isEof() const;

    /** Tries to receives BytesToRead data from the connected socket,

        @param pBuffer [out] Points to a buffer that will be filled with the received
        data.
        @param BytesToRead [in] The number of bytes to read. pBuffer must have at least
        this size.
        @param Flag [in] Modifier for the call. Valid values are:
        <ul>
        <li> TMsg_Normal
        <li> TMsg_OOB
        <li> TMsg_Peek
        <li> TMsg_DontRoute
        <li> TMsg_MaxIOVLen
        </ul>

        @return the number of received bytes.
    */
    sal_Int32   SAL_CALL recv(void* pBuffer,
                 sal_uInt32 BytesToRead,
                 TSocketMsgFlag Flag= TMsg_Normal);


    /** Tries to sends BytesToSend data from the connected socket.

        @param pBuffer [in] Points to a buffer that contains the send-data.
        @param BytesToSend [in] The number of bytes to send. pBuffer must have at least
        this size.
        @param Flag [in] Modifier for the call. Valid values are:
        <ul>
        <li> TMsg_Normal
        <li> TMsg_OOB
        <li> TMsg_Peek
        <li> TMsg_DontRoute
        <li> TMsg_MaxIOVLen
        </ul>

        @return the number of transferred bytes.
    */
    sal_Int32 SAL_CALL send(const void* pBuffer,
                 sal_uInt32 BytesToSend,
                 TSocketMsgFlag Flag= TMsg_Normal);

    /** Closes a connection in a controlled manner.
        @param Direction Says which "end" of the socket is to be closed.
    */
    sal_Bool SAL_CALL shutdown(TSocketDirection Direction= TDirection_ReadWrite);
protected:

    /** Creates a socket. This constructor is used only by derived classes
        (e.g. OConnectorSocket).
        @param Family
        @param Protocol
        @param Type For some protocols it might be desirable to
                    use a different type than sock_stream (like sock_seqpacket).
                    Therefore we do not hide this parameter here.
    */
    OStreamSocket(TAddrFamily Family,
                  TProtocol   Protocol,
                  TSocketType Type= TType_Stream);


};


/** A socket to accept incoming connections.
*/
class OAcceptorSocket : public vos::OSocket
{
    VOS_DECLARE_CLASSINFO(vos::OAcceptorSocket);
public:

    /** Creates a socket that can accept connections.
        @param Type For some protocols it might be desirable to
                    use a different type than sock_stream (like sock_seqpacket).
                    Therefore we do not hide this parameter here.
    */
    OAcceptorSocket(TAddrFamily Family= TFamily_Inet,
                    TProtocol   Protocol= TProtocol_Ip,
                    TSocketType Type= TType_Stream);

    /** Copy constructor.
    */
    OAcceptorSocket(const OAcceptorSocket& Socket);

    /** Destructor. Closes the socket and destroys the underlying oslSocket.
    */
    virtual ~OAcceptorSocket();

    /** Closes the socket. Also calls shutdown, needed to unblock
        accept on some systems.
    */
    virtual void SAL_CALL close();

    /** Prepare a socket for the accept-call.
        @param MaxPendingConnections The maximum number of pending
        connections (waiting to be accepted) on this socket. If you use
        -1, a system default value is used.
        @return True if call was successful.
    */
    sal_Bool SAL_CALL listen(sal_Int32 MaxPendingConnections= -1);

    /** Accepts incoming connections on the socket. You must
        precede this call with bind() and listen().
        @param Connection receives the incoming connection.
        @return result_ok: if a connection has been accepted,
                result_timeout: if m_RecvTimeout milliseconds passed without connect,
                result_error: on errors.
    */
    TResult SAL_CALL acceptConnection(OStreamSocket& Connection);

    /** Accepts incoming connections on the socket. You must
        precede this call with bind() and listen().
        @param PeerAddr receives the address of the connecting entity
        (your communication partner).
        @param Connection receives the incoming connection.
        @return True if a connection has been accepted, False on errors.
        @return result_ok: if a connection has been accepted,
                result_timeout: if m_RecvTimeout milliseconds passed without connect,
                result_error: on errors.
    */
    TResult SAL_CALL acceptConnection(OStreamSocket&    Connection,
                             OSocketAddr& PeerAddr);

};


/** A socket to initiate a conenction.
*/
class OConnectorSocket : public vos::OStreamSocket
{
    VOS_DECLARE_CLASSINFO(vos::OConnectorSocket);
public:

    /** Creates a socket that can accept connections.
        @param Type For some protocols it might be desirable to
                    use a different type than sock_stream (like sock_seqpacket).
                    Therefore we do not hide this parameter here.
    */
    OConnectorSocket(TAddrFamily Family= TFamily_Inet,
                     TProtocol   Protocol= TProtocol_Ip,
                     TSocketType Type= TType_Stream);

    /** Copy constructor. Doesn't duplicate oslSocket.
    */
    OConnectorSocket(const OConnectorSocket& Socket);

    /** Destructor. Relies on ~OStreamSocket to close down connection gracefully.
    */
    virtual ~OConnectorSocket();

    /** Connects the socket to a (remote) host.
        @param TargetHost The address of the target.
        @param msTimeout The timeout in milliseconds. Use -1 to block.
        @return result_ok if connected successfully,
                result_timeout on timeout,
                result_interrupted if unblocked forcefully (by close()),
                result_error if connect failed.
    */
    TResult SAL_CALL connect(const OSocketAddr& TargetHost, const TimeValue* pTimeout = 0);
};


/** A connectionless socket to send and receive datagrams.
*/
class ODatagramSocket : public vos::OSocket
{
    VOS_DECLARE_CLASSINFO(vos::ODatagramSocket);
public:

    /** Creates a datagram socket.
        @param Type is sock_dgram by default.
    */
    ODatagramSocket(TAddrFamily Family= TFamily_Inet,
                    TProtocol   Protocol= TProtocol_Ip,
                    TSocketType Type= TType_Dgram);

    /** Copy constructor.
    */
    ODatagramSocket(const ODatagramSocket& Socket);

    /** Destructor. Closes the socket.
    */
    virtual ~ODatagramSocket();


    /** Tries to receives BufferSize data from the socket, if no error occurs.

        @param pSenderAddr [out] You must provide pointer to a SocketAddr.
        It will be  filled with the address of the datagrams sender.
        If pSenderAddr is 0, it is ignored.
        @param pBuffer [out] Points to a buffer that will be filled with the received
        datagram.
        @param BufferSize [in] The size of pBuffer.
        @param Flag [in] Modifier for the call. Valid values are:
        <ul>
        <li> TMsg_Normal
        <li> TMsg_OOB
        <li> TMsg_Peek
        <li> TMsg_DontRoute
        <li> TMsg_MaxIOVLen
        </ul>

        @return the number of received bytes.
    */
    sal_Int32   SAL_CALL recvFrom(void*  pBuffer,
                     sal_uInt32 BufferSize,
                     OSocketAddr* pSenderAddr= 0,
                     TSocketMsgFlag Flag= TMsg_Normal);

    /** Tries to send one datagram with BytesToSend data to the given ReceiverAddr.
        Since we only send one packet, we don't need to concern ourselfes here with
        incomplete sends due to packet boundaries.

        @param ReceiverAddr [in] A SocketAddr that contains
        the destination address for this send.

        @param pBuffer [in] Points to a buffer that contains the send-data.
        @param BufferSize [in] The number of bytes to send. pBuffer must have at least
        this size.
        @param Flag [in] Modifier for the call. Valid values are:
        <ul>
        <li> TMsg_Normal
        <li> TMsg_OOB
        <li> TMsg_Peek
        <li> TMsg_DontRoute
        <li> TMsg_MaxIOVLen
        </ul>

        @return the number of transferred bytes.
    */
    sal_Int32   SAL_CALL sendTo(const OSocketAddr& ReceiverAddr,
                   const void* pBuffer,
                   sal_uInt32 BufferSize,
                   TSocketMsgFlag Flag= TMsg_Normal);
};



}

#endif // _VOS_SOCKET_HXX_

