#ifndef _aplmt_fd_fdapi_h_
#define _aplmt_fd_fdapi_h_
/*----------------------------------------------------------------------------
** SUMMARY: File Descriptor IO Interface (FD)
**
** DESCRIPTION:
**  This file provides a common interface for using objects/devices that can
**  exchange data with the application.  A 'file descriptor' is defined as a
**  handle and/or identifier to an object/device that can exchange (read/write)
**  data in an orderly fashion with the application.  For example, a file
**  descriptor can be used to read/write to a serial port, non-volatile storage
**  devices, a individual file on a storage device, sockets, pipes, etc. 
**  APL's file descriptor is basically the same as a POSIX file descriptor.
**
**  CREATE/OPEN:
**  ------------
**  This interface intentionally does NOT include any methods to open/create
**  a file descriptor.  Opening/Creating a file descriptor is very device
**  specific and is handled in other (device specific) interfaces.
**
**  INTIALIZATION
**  -------------
**  No initialization is needed.  This is because the FD sub-system assumes 
**  that its internal data structure are already all ZEROs as per the C/C++ 
**  standard for static un-initialized data.
** 
**
** CONFIGURATION 
** -------------
**  COMPILE:     none.
**
**  APPLICATION: The application can override the following types/defintions
**                  AplmtFD
**                  OPTION_APLMT_FD_MAX_FILE_DESCRIPTORS
**
**  PLATFORM:    none.
**
**
**  NOTES:
**  1. Unless explicitly stated otherwise, NONE of the following methods may be 
**     called from interrupt service routines.
**  2. Unless explicitly stated otherwise, NONE of the following methods may be 
**     called before the platform's kernel is running.
**  3. Unless explicitly stated otherwise, all of the following methods ARE 
**     thread-safe.
**  4. For efficency/optimization some methods are 'inlined'.  The inlining
**     is done by using the preprocessor/macros.  The application should
**     treat all methods as function calls and not rely on the fact they may
**     be currently defined as macros.
----------------------------------------------------------------------------*/

#include "aplcfg.h"                 /* For: Application configuration */
#include "apl/types/types.h"        /* For: basic types */

#ifdef __cplusplus
extern "C" {
#endif


/*-------------- ERROR CODES (non-fatal) ------------------------------------*/
/** Exceeded the internel kernel limit for concurrently opened
    file descriptors.  This method is only returned by create and open 
    methods.
 */
#define APLMT_ERRSTR_FD_OUT_OF_FDS              "FD: Create/Open exceeeded the system's internal limit for opened descriptors."
/***/
#define APLMT_ERR_FD_OUT_OF_FDS                 _APLMT_ERR_FD_OUT_OF_FDS

/** The request for a file descriptor has been denied because the associated
    device/entity/object is busy and/or already in use.  This method is 
    only returned by create and open methods.
 */
#define APLMT_ERRSTR_FD_NOT_AVAILABLE           "FD: Create/Open failed because device is already in use."
/***/
#define APLMT_ERR_FD_NOT_AVAILABLE              _APLMT_ERR_FD_NOT_AVAILABLE

/** An error occurred in underlying device driver(s) and the called operation
    can not be completed.  There is no guaranty on what state the device is
    left in, or what data is/was transfered.
 */ 
#define APLMT_ERRSTR_FD_IO_ERROR                "FD: Underyling device driver error occured."
/***/
#define APLMT_ERR_FD_IO_ERROR                   _APLMT_ERR_FD_IO_ERROR

/** The specified descriptor does not reference a currently opened file
    descriptor.
 */
#define APLMT_ERRSTR_FD_BAD_DESCRIPTOR          "FD: Specified descriptor does not reference a currently open file descriptor."
/***/
#define APLMT_ERR_FD_BAD_DESCRIPTOR             _APLMT_ERR_FD_BAD_DESCRIPTOR

/** The device associated with the specified descriptor does not support
    and/or is not suitable for the invoked method.
 */
#define APLMT_ERRSTR_FD_INVALID_DESCRIPTOR      "FD: The specified descriptor does not support the invoked method."
/***/
#define APLMT_ERR_FD_INVALID_DESCRIPTOR         _APLMT_ERR_FD_INVALID_DESCRIPTOR

/** End-of-file has been reached. When EOF is returned, the invoked method 
    acts like a "NOP" in that no action and/or data is transferred. This error
    only occurs on devices that support the concept of EOF/EOS.
 */
#define APLMT_ERRSTR_FD_EOF                     "FD: End-of-File/Stream was encountered."
/***/
#define APLMT_ERR_FD_EOF                        _APLMT_ERR_FD_EOF

/** Attempt to set the stream/file offset past the eos/eof.  This error
    only occurs on devices that support the concept of stream/file offset.
 */
/***/
#define APLMT_ERRSTR_FD_EXCEED_EOF              "FD: Attempted to set the file/stream offset past EOF/EOS."
/***/
#define APLMT_ERR_FD_EXCEED_EOF                 _APLMT_ERR_FD_EXCEED_EOF


/*-------------- TYPES -----------------------------------------------------*/
/** File descriptor Handle.  Default limits max num FDs to 128.
 */
#ifndef AplmtFD
#define AplmtFD                                 _AplmtFD
#endif 



/*-------------- MACROS/CONSTANTS ------------------------------------------*/
/** Default number of open'd file descriptors */
#ifndef OPTION_APLMT_FD_MAX_FILE_DESCRIPTORS
#define OPTION_APLMT_FD_MAX_FILE_DESCRIPTORS    8
#endif


/*-------------- INLINE IMPLEMENTATION -------------------------------------*/
#include "aplmt/fd/fd.h"            /* For: inline implementation */



/*-------------- PUBLIC/PUBLISHED API --------------------------------------*/
/** This method will close the object identified by 'handle'.  The result of 
    closing the object on the underlying device driver(s) is dependent on the 
    actual concrete device/platform.  On success, the method returns a value 
    >=0.  If an error occurrs, then an error code (value <0) is returned.
    Prototype:
        AplSSize_t Aplmt_close( AplmtFD handle );
 */
#define Aplmt_close                         _Aplmt_close

/** Attempts to read the specified number of bytes from the stream, identified
    by 'handle', into the supplied buffer.  The method returns the number of 
    actual bytes read (which is >=0) if successful, and the stream/file 
    position is advanced by the number returned. If an error occurrs, then an
    error code (value <0) is returned. 
    NOTES: 
        o When operating on a device that has a concept of 'end-of-stream' 
          or 'end-of-file' and the eos/eof is encounter the method returns
          an error. The application must check the error code to determine 
          the exact cause of the error. 
        o 'count' must be >= 0.

    Prototype:
        AplSSize_t Aplmt_read( AplmtFD handle, void* buffer, AplSSize_t count );
 */
#define Aplmt_read                          _Aplmt_read

/** Writes the content of the buffer to the stream, identified by 'handle'. At 
    most 'count' will be outputted.  The method returns the number of actual 
    bytes written (which is >=0), and the stream/file position is advanced by
    the number returned.  If an error occurrs, then an error code 
    (value <0) is returned. 
    NOTES: 
        o When operating on a device that has a concept of 'end-of-stream' 
          or 'end-of-file' and the eos/eof is encounter the method returns
          an error. The application must check the error code to determine 
          the exact cause of the error. 
        o 'count' must be >= 0.

    Prototype:
        AplSSize_t Aplmt_write( AplmtFD handle, void* buffer, AplSSize_t count );
     */ 
#define Aplmt_write                         _Aplmt_write

/** Returns the number of bytes (>=0) that can be read from the stream WITHOUT
    the Aplmt_read() call blocking.  If an error occurrs, then an error code 
    (value <0) is returned. 

    Prototype:
        AplSSize_t Aplmt_available( AplmtFD handle );
 */
#define Aplmt_available                     _Aplmt_available

/** Forces all buffered data (if any) to be written to the device 'media'. On
    On success, the method returns a value >=0.  If an error occurrs, then 
    an error code (value <0) is returned. 

    Prototype:
        AplSSize_t Aplmt_flush( AplmtFD handle );
 */
#define Aplmt_flush                         _Aplmt_flush

/** This method returns, via 'curpos', the current stream/file position, in 
    bytes, with respect to the the beginning of the 'file'. On success, the 
    method returns a value >=0.  If an error occurrs, then an error code 
    (value <0) is returned and the contents of 'curpos' is undefined.
    NOTES: 
        o This method only has meaning for devices that have a concept
          of 'position'.  For example, position has no meaning for a serial
          port, but is meaningful for a file and/or storage devices.

    Prototype:
        AplSSize_t Aplmt_getPos( AplmtFD handle, AplSize_t* curpos );
 */
#define Aplmt_getPos                        _Aplmt_getPos

/** This method repositions the current stream/file position, in bytes from 
    the start of the file/stream, to 'offset'. On success, the method returns 
    a value >=0.  If an error occurrs, then an error code (value <0) is 
    returned.
    NOTES: 
        o This method only has meaning for devices that have a concept
          of 'position'.  For example, position has no meaning for a serial
          port, but is meaningful for a file and/or storage devices.

    Prototype:
        AplSSize_t Aplmt_setPos( AplmtFD handle, AplSize_t offset );
 */
#define Aplmt_setPos                        _Aplmt_setPos

/** This method returns the stream/file offset position, via 'eofOffset', of 
    EOF (i.e. returns the size/length of the file). The offset is returned as
    the number of bytes from the start of the file.  On success, the method 
    returns a value >=0.  If an error occurrs, then an error code (value <0) is 
    returned.
    NOTES: 
        o This method only has meaning for devices that have a concept
          of 'position'.  For example, position has no meaning for a serial
          port, but is meaningful for a file and/or storage devices.

    Prototype:
        AplSSize_t Aplmt_getEof( AplmtFD handle, AplSize_t* eofOffset );
 */
#define Aplmt_getEof                        _Aplmt_getEof



#ifdef __cplusplus
}
#endif
/*--------------------------------------------------------------------------*/
#endif  /* end _aplmt_fd_fdapi_h_ */
