/*
 * zSocket.h
 * 
 * The Zen API 
 * Copyright (C) 2008-2009 by LMI Technologies Inc.
 * 
 * Licensed under The MIT License.
 * Redistributions of files must retain the above copyright notice.
 */ 
#ifndef LMITECH_ZSOCKET_H_INCLUDED
#define LMITECH_ZSOCKET_H_INCLUDED

#include <zNetwork.h>
#include <zApiBegin.h>

typedef zHandle zSocket;            // Represents a network socket.

typedef enum zSocketType
{
    zSOCKET_TYPE_TCP,               // TCP Socket.
    zSOCKET_TYPE_UDP                // UDP Socket.
} zSocketType;                      // Represents the type of socket.

ZAPI_EXPORT(zStatus) zSocket_WaitAny(const zSocket* sockets, z32u count, zBool* status, z64u timeout); //
//
//  Description:
//      Waits until one or more of the specified sockets has bytes to read (enqueued connection 
//      requests for server sockets) or until the specified timeout period elapses. 
//  Arguments:
//      sockets - An array of sockets to wait on. 
//      count - The number of sockets in the array.
//      status - An array of returned status values, indicating which sockets are ready to be read.
//      timeout - Timeout, in microseconds. 
//  Remarks: 
//      This function will return zERROR_TIMEOUT in the event that none of the sockets are ready 
//      for reading by the end of the timeout period. 

ZAPI_EXPORT(zStatus) zSocket_Construct(zSocket* socket, zSocketType type); //
//
//  Description:
//      Constructs a zSocket object.
//  Arguments:
//      socket - Destination for the constructed object handle. 
//      type - The type of socket to create (i.e. TCP or UDP). 

ZAPI_EXPORT(zStatus) zSocket_Destroy(zSocket socket); //
//
//  Description:
//      Destroys a zSocket object. 
//  Arguments:
//      socket - The zSocket object to be destroyed.
//  Remarks: 
//      If the socket is connected, this function will close the connection before destroying
//      the socket object.

ZAPI_EXPORT(zStatus) zSocket_Bind(zSocket socket, zIPAddress address, z32u port); //
//
//  Description:
//      Binds the socket to a local IP address and/or port. 
//  Arguments:
//      socket - zSocket object.
//      address - A local IP address, or zIP_ADDRESS_ANY. 
//      port - A local port number, or zIP_PORT_ANY.

ZAPI_EXPORT(zStatus) zSocket_Connect(zSocket socket, zIPAddress address, z32u port, z64u timeout); //
//
//  Description:
//      Attempts to connect the socket to a remote end point until either a connection is established, 
//      the remote end point refuses the connection, or the specified timeout interval elapses. 
//  Arguments:
//      socket - zSocket object.
//      address - The remote IP address. 
//      port - The remote port number.
//      timeout - The timeout interval, in microseconds. 
//  Remarks: 
//      A connection can be attempted only once per zSocket object.  After an initial connection 
//      attempt, the zSocket object cannot be used to create another connection and should be destroyed. 

ZAPI_EXPORT(zStatus) zSocket_Listen(zSocket socket, z32u backlog); //
//
//  Description:
//      Places a server zSocket object into a listening state, in which it monitors for incoming connection requests.
//  Arguments:
//      socket - A server zSocket object.
//      backlog - The maximum number of pending connection requests to enqueue. 

ZAPI_EXPORT(zStatus) zSocket_Accept(zSocket socket, zSocket* connection); //
//
//  Description:
//      Blocks until an incoming connection request is accepted. 
//  Arguments:
//      socket - A server zSocket object in the listening state.
//      connection - Returns a socket object representing the newly-established connection, or zNIL.
//  Remarks: 
//      The returned connection object can be zNIL if the connection was closed by the remote client 
//      before being accepted.

ZAPI_EXPORT(zStatus) zSocket_Wait(zSocket socket, z64u timeout); //
//
//  Description:
//      Waits until the socket has bytes to read (enqueued connection requests for server sockets) 
//      or until the specified timeout period elapses. 
//  Arguments:
//      socket - zSocket object.
//      timeout - Timeout, in microseconds. 
//  Remarks: 
//      This function will return zERROR_TIMEOUT in the event that the socket is not ready 
//      for reading by the end of the timeout period. 

ZAPI_EXPORT(zStatus) zSocket_Read(zSocket socket, void* buffer, zUIntPtr size, zUIntPtr* read); //
//
//  Description:
//      Blocks until at least one byte is available for reading (or until a read timeout occurs),
//      and returns the bytes that were read.
//  Arguments:
//      socket - zSocket object.
//      buffer - Buffer to receive bytes. 
//      size - The maximum number of bytes to read.
//      read - The number of bytes that were read.

ZAPI_EXPORT(zStatus) zSocket_ReadFrom(zSocket socket, zIPEndPoint *endPoint, void* buffer, zUIntPtr size, zUIntPtr* read); //
//
//  Description:
//      Blocks until a datagram is received (or until a read timeout occurs), and returns the datagram.
//  Arguments:
//      socket - zSocket object.
//      endPoint - The address of the sender. 
//      buffer - Buffer to receive the datagram. 
//      size - The maximum number of bytes to return.
//      read - The number of bytes that were read.

ZAPI_EXPORT(zStatus) zSocket_Write(zSocket socket, const void* buffer, zUIntPtr size); //
//
//  Description:
//      Blocks until all of the specified bytes are written (or until a write timeout occurs). 
//  Arguments:
//      socket - zSocket object.
//      buffer - Buffer of bytes to write. 
//      size - The number of bytes to write.

ZAPI_EXPORT(zStatus) zSocket_WriteTo(zSocket socket, zIPAddress address, z32u port, const void* buffer, zUIntPtr size); //
//
//  Description:
//      Blocks until the specified datagram is written (or until a write timeout occurs). 
//  Arguments:
//      socket - zSocket object.
//      address - IP address of the recpient. 
//      port - Port number of the recipient. 
//      buffer - Buffer containing the datagram to send.
//      size - The number of bytes in the supplied buffer.

ZAPI_EXPORT(zStatus) zSocket_SetWriteBuffer(zSocket socket, zUIntPtr size); //
//
//  Description:
//      Sets the size of the write buffer used for this socket by the underlying operating system.
//  Arguments:
//      socket - zSocket object.
//      size - Size of the write buffer.

ZAPI_EXPORT(zStatus) zSocket_SetReadBuffer(zSocket socket, zUIntPtr size); //
//
//  Description:
//      Sets the size of the read buffer used for this socket by the underlying operating system.
//  Arguments:
//      socket - zSocket object.
//      size - Size of the read buffer.

ZAPI_EXPORT(zStatus) zSocket_SetWriteTimeout(zSocket socket, z64u timeout); //
//
//  Description:
//      Sets the timeout duration for write operations.  
//  Arguments:
//      socket - zSocket object.
//      timeout - Timeout value, in microseconds.
//  Remarks: 
//      By default, zSocket objects do not use a timeout interval and can block indefinitely.

ZAPI_EXPORT(zStatus) zSocket_SetReadTimeout(zSocket socket, z64u timeout); //
//
//  Description:
//      Sets the timeout duration for read operations.  
//  Arguments:
//      socket - zSocket object.
//      timeout - Timeout value, in microseconds.
//  Remarks: 
//      By default, zSocket objects do not use a timeout interval and can block indefinitely.

ZAPI_EXPORT(zStatus) zSocket_EnableBroadcast(zSocket socket, zBool broadcast); //
//
//  Description:
//      Enables or disables datagram broadcasting.
//  Arguments:
//      socket - zSocket object.
//      broadcast - zTRUE to enable broadcasts; zFALSE otherwise.
//  Remarks: 
//      This function is typically used in conjunction with a UDP socket that is bound 
//      to a local address. Sending to zIP_ADDRESS_BROADCAST will broadast a 
//      datagram on the subnet associated with the bound address.
//  Remarks: 
//      This option is disabled by default.

ZAPI_EXPORT(zStatus) zSocket_EnableReuseAddress(zSocket sock, zBool reuse); //
//
//  Description:
//      Enables or disables reuse of a local end point within a short period of time.
//  Arguments:
//      socket - zSocket object.
//      reuse - zTRUE to enable reuse of IP addresses; zFALSE otherwise.
//  Remarks: 
//      The option is typically used to allow a server to rebind to a local end point 
//      while a previous socket with the same local end point is in the TIME_WAIT state. 
//      This can be useful when a server must be stopped and started within a brief interval, 
//      but there is a small risk that packets with identical source/destination information 
//      could be misdirected to the new socket. 
//  Remarks: 
//      This option is disabled by default.

ZAPI_EXPORT(zStatus) zSocket_SetNoDelay(zSocket socket, zBool noDelay); //
//
//  Description:
//      Can be used to disable the Nagle algorithm.
//  Arguments:
//      socket - zSocket object.
//      broadcast - zTRUE to disable the Nagle algorithm; zFALSE to enable. 
//  Remarks: 
//      The Nagle algorithm is enabled by default. When enabled, small segments of outbound 
//      data are coalesced over a brief time period in order to improve network efficiency. 

ZAPI_EXPORT(zStatus) zSocket_SetLingerTime(zSocket socket, z64u lingerTime); //
//
//  Description:
//      Specifies the duration that a TCP connection can remain open when the socket is closed
//      in order to ensure that all outbound bytes are trasmitted to the receiver. 
//  Arguments:
//      socket - zSocket object.
//      lingerTime - Linger time, in microseconds (0 for immediate closuse). 
//  Remarks: 
//      If the linger time is not set, then a default linger time will be selected by 
//      the underlying operating system.

ZAPI_EXPORT(zHandle) zSocket_Handle(zSocket socket); //
//
//  Description:
//      Returns the socket handle used by the underlying operating system.
//  Arguments:
//      socket - zSocket object.

ZAPI_EXPORT(zStatus) zSocket_LocalEndPoint(zSocket socket, zIPEndPoint* endPoint); //
//
//  Description:
//      Returns the local end point for a bound socket. 
//  Arguments:
//      socket - zSocket object.
//      endPoint - Local end point.

ZAPI_EXPORT(zStatus) zSocket_RemoteEndPoint(zSocket socket, zIPEndPoint* endPoint); //
//
//  Description:
//      Returns the remote end point for a connected socket. 
//  Arguments:
//      socket - zSocket object.
//      endPoint - Remote end point.

#include <zApiEnd.h>

#endif      /* #ifndef LMITECH_ZSOCKET_H_INCLUDED */
