/*
 * zUdpClient.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_ZUDPCLIENT_H_INCLUDED
#define LMITECH_ZUDPCLIENT_H_INCLUDED

#include <zSocket.h>
#include <zApiBegin.h>

typedef zHandle zUdpClient;     // Represents a UDP client.

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

ZAPI_EXPORT(zStatus) zUdpClient_Construct(zUdpClient* client); //
//
//  Description:
//      Constructs a zUdpClient object.
//  Arguments:
//      client - Destination for the constructed object handle. 

ZAPI_EXPORT(zStatus) zUdpClient_Destroy(zUdpClient client); //
//
//  Description:
//      Destroys a zUdpClient object. 
//  Arguments:
//      client - The zUdpClient object to be destroyed.

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

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

ZAPI_EXPORT(zStatus) zUdpClient_Receive(zUdpClient client, zIPEndPoint* endPoint, zUIntPtr* received); //
//
//  Description:
//      Blocks until a datagram is received into zUdpClient's read buffer (or until a read timeout occurs). 
//  Arguments:
//      client - zUdpClient object.
//      endPoint - The end point of the sender. 
//      received - The size of the recieved datagram. 
//  Remarks: 
//      The Receive method is used to receive a datagram into zUdpClient's internal read buffer. 
//      Once the datagram has been recieved, the zUdpClient_Read method can be used to read out the 
//      datagram. zUdpClient_Read is typically called indirectly via a zSerializer object.

ZAPI_EXPORT(zStatus) zUdpClient_Send(zUdpClient client, zIPAddress address, z32u port); //
//
//  Description:
//      Blocks until the datagram in zUdpClient's internal write buffer is written to the underlying socket 
//     (or until a write timeout occurs). 
//  Arguments:
//      client - zUdpClient object.
//      address - IP address of the recpient. 
//      port - Port number of the recipient. 
//  Remarks: 
//      The Send method is used to send a datagram that has been written into zUdpClient's internal 
//      write buffer.  Bytes are written into zUdpClient's internal buffer via the zUdpClient_Write method. 
//      zUdpClient_Write is typically called indirectly via a zSerializer object.
      
ZAPI_EXPORT(zStatus) zUdpClient_Read(zUdpClient client, void* buffer, zUIntPtr size); //
//
//  Description:
//      Extracts the specified number of bytes from zUdpClient's internal read buffer.
//  Arguments:
//      client - zUdpClient object.
//      buffer - Buffer to receive bytes.
//      size - The number of bytes to read.

ZAPI_EXPORT(zStatus) zUdpClient_Write(zUdpClient client, const void* buffer, zUIntPtr size); //
//
//  Description:
//      Appends the specified bytes to zUdpClient's internal write buffer.
//  Arguments:
//      client - zUdpClient object.
//      buffer - Buffer of bytes to write. 
//      size - The number of bytes to write.

ZAPI_EXPORT(zStatus) zUdpClient_EnableBroadcast(zUdpClient client, zBool broadcast); //
//
//  Description:
//      Enables or disables broadcasting.
//  Arguments:
//      client - zUdpClient object.
//      broadcast - zTRUE to enable broadcasts; zFALSE otherwise.
//  Remarks: 
//      If broadcasting is enabled, sending to zIP_ADDRESS_BROADCAST will broadast a datagram 
//      on the subnet associated with the address to which the client is bound.
//  Remarks: 
//      Broadcasts are disabled by default.

ZAPI_EXPORT(zStatus) zUdpClient_EnableReuseAddress(zUdpClient client, zBool reuse);//
//
//  Description:
//      Enables or disables reuse of a local end point within a short period of time.
//  Arguments:
//      client - zUdpClient 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) zUdpClient_SetWriteBuffer(zUdpClient client, zUIntPtr size); //
//
//  Description:
//      Sets the size of the write buffer used by the underlying socket.
//  Arguments:
//      client - zUdpClient object.
//      size - Size of the socket write buffer.
//  Remarks: 
//      This method sets the size of the socket write buffer associated with the 
//      client. Socket buffers decouple the sender and receiver, so that the sender does not 
//      need to block while waiting for the receiver to receive all bytes. zUdpClient also 
//      maintains an internal write buffer that is large enough to accomodate one UDP datagram, 
//      but the size of this buffer cannot be explicitly set.

ZAPI_EXPORT(zStatus) zUdpClient_SetReadBuffer(zUdpClient client, zUIntPtr size); //
//
//  Description:
//       Sets the size of the read buffer used by the underlying socket.
//  Arguments:
//      client - zUdpClient object.
//      size - Size of the socket read buffer.
//  Remarks: 
//      This method sets the size of the socket read buffer associated with the 
//      client. Socket buffers decouple the sender and receiver, so that the sender does not 
//      need to block while waiting for the receiver to receive all bytes. zUdpClient also 
//      maintains an internal read buffer that is large enough to accomodate one UDP datagram, 
//      but the size of this buffer cannot be explicitly set.

ZAPI_EXPORT(zSocket) zUdpClient_Socket(zUdpClient client);  //
//
//  Description:
//      Returns the underlying zSocket object.
//  Arguments:
//      client - zUdpClient object.

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

#include <zApiEnd.h>

#endif   /* #ifndef LMITECH_ZUDPCLIENT_H_INCLUDED */
