/**
 * @file FLCICV.h
 * @brief Specification for the FLUC iconv interface
 * @author limes datentechnik gmbh
 * @date 21.11.2014\n
 * @copyright (c) 2014 limes datentechnik gmbh
 *
 * @mainpage FLUC ICONV Interface
 *
 * This module provides a *libiconv*-compatible interface for memory to
 * memory character conversion. All special feature of FLUC character
 * conversion module are provided through the TO and FROM string
 * specification in #fliconv_open() function.
 *
 * Example for C:
 * <pre>
 * iconvlist(NULL,NULL);
 * h=iconv_open("UTF16LE//BOM","1141//ELF2NL//IGNORE//TRANSLIT//REPORT(report.txt)");
 * r=iconv(h,&inDat,&inLen,&outDat,&outLen);
 * iconv_close(h);
 * </pre>
 * Example in Cobol: (Compile with the dll-option on mainframes)
 * <pre>
 * *
 *  DATA DIVISION.
 * *
 *  FILE SECTION.
 *  FD  OUTDAT  BLOCK CONTAINS 0 CHARACTERS
 *              RECORDING MODE V
 *              RECORD IS VARYING FROM 1 TO 240 CHARACTERS
 *                     DEPENDING ON OUTREC-LEN
 *              LABEL  RECORD IS STANDARD.
 *  01  OUTDAT-RECORD.
 *      02 FILLER   PIC X(240).
 * *
 *  FD  INDAT   BLOCK CONTAINS 0 CHARACTERS
 *              RECORDING MODE F
 *              RECORD CONTAINS 80 CHARACTERS
 *              LABEL  RECORD IS STANDARD.
 *  01  INDAT-RECORD.
 *      02 FILLER   PIC X(80).
 *
 * *
 *  WORKING-STORAGE SECTION.
 * *
 * .......
 * 01  DISPAREA       PIC  X(8120)   VALUE SPACES.
 * 01  FLICONV-PARAMETER.
 *   05 FLICV-FROM.
 *      10 CCSID-FROM PIC X(8) VALUE 'IBM-1141'.
 *      10 FILLER     PIC X(8) VALUE '//IGNORE'.
 *      10 FILLER     PIC X(1) VALUE LOW-VALUE.
 *   05 FLICV-TO.
 *      10 CCSID-TO   PIC X(4) VALUE 'UTF8'.
 *      10 FILLER     PIC X(1) VALUE LOW-VALUE.
 *   77  FLICV-HDL      PIC  9(8) COMP VALUE ZERO.
 *   77  FLICV-RC       PIC S9(8) COMP VALUE ZERO.
 *   77  IN-PTR         USAGE IS POINTER.
 *   77  OUT-PTR        USAGE IS POINTER.
 *   77  INLEFT         PIC  9(8) COMP.
 *   77  OUTLEFT        PIC  9(8) COMP.
 * .......
 *
 * *
 * PROCEDURE DIVISION.
 * .......
 * GET-CCSID-LIST SECTION.
 * GET-CCSID-LIST-01.
 * .......
 *     CALL 'fliconv_list'  USING OMITTED, DISPAREA
 * .......
 * GET-VERSION-EX.
 *     EXIT.
 * *
 * OPEN-FLICONV SECTION.
 * OPEN-FLICONV-01.
 * .......
 *     CALL 'fliconv_open'  USING FLICV-TO, FLICV-FROM
 *                          RETURNING FLICV-HDL
 * .......
 * OPEN-FLICONV-EX.
 *     EXIT.
 * *
 * DO-CONVERSION SECTION.
 * DO-CONVERSION-01.
 * .......
 *     CALL  'fliconv'      USING BY VALUE     FLICV-HDL,
 *                                BY REFERENCE IN-PTR,
 *                                BY REFERENCE INLEFT,
 *                                BY REFERENCE OUT-PTR,
 *                                BY REFERENCE OUTLEFT
 *                          RETURNING FLICV-RC
 * .......
 * DO-CONVERSION-EX.
 *     EXIT.
 * *
 * CLOSE-FLICONV SECTION.
 * CLOSE-FLICONV-01.
 * .......
 *     CALL 'fliconv_close' USING BY VALUE  FLICV-HDL
 * .......
 * CLOSE-FLICONV-EX.
 *     EXIT.
* .......
 * </pre>
 * Example in PL/1: (Compile with the dll-option on mainframes)
 * <pre>
 * .......
 * /-------------------------------------------------------------------
 * /   DECLARATIONS FOR USED C FUNCTIONS
 * /-------------------------------------------------------------------
 * .......
 *     DCL FLICONV_LIST          EXT('fliconv_list')
 *                               ENTRY(POINTER    BYADDR,
 *                                     CHAR(8120) BYADDR)
 *                               OPTIONS (NODESCRIPTOR);
 * *
 *     DCL FLICONV_OPEN          EXT('fliconv_open')
 *                               ENTRY(CHAR(*) VARYINGZ NONASGN BYADDR,
 *                                     CHAR(*) VARYINGZ NONASGN BYADDR )
 *                               RETURNS (BIN FIXED(31,0) BYVALUE)
 *                               OPTIONS (NODESCRIPTOR);
 * *
 *     DCL FLICONV               EXT('fliconv')
 *                               ENTRY
 *                                    (BIN FIXED(31,0) BYVALUE,
 *                                     POINTER         BYADDR,
 *                                     BIN FIXED(31,0) BYADDR,
 *                                     POINTER         BYADDR,
 *                                     BIN FIXED(31,0) BYADDR)
 *                               RETURNS (BIN FIXED(31,0) BYVALUE)
 *                               OPTIONS (NODESCRIPTOR);
 * *
 *    DCL FLICONV_CLOSE          EXT('fliconv_close')
 *                               ENTRY(BIN FIXED(31,0) byvalue)
 *                               RETURNS (BIN FIXED(31,0) byvalue)
 *                               OPTIONS (NODESCRIPTOR);
 * .......
 * /-------------------------------------------------------------------
 * /                        E N T R I E S
 * /-------------------------------------------------------------------
 *     DCL SYSOUT FILE STREAM OUTPUT PRINT ENV (FB RECSIZE (132));
 *     DCL INPUT  FILE RECORD INPUT  ENV (FB RECSIZE (80));
 *     DCL OUTPUT FILE RECORD OUTPUT ENV (VB RECSIZE (244));
 *
 * /-------------------------------------------------------------------
 * /              O T H E R    V A R I A B L E S
 * /-------------------------------------------------------------------
 * .......
 *   DCL  1   LIST_PTR           POINTER;
 *   DCL  1   DISPAREA           CHAR(8120)      INIT(' ');
 *   DCL  1   FLICV_FROM,
 *            10 CCSID_FROM      CHAR(8) INIT ('IBM-1141'),
 *            10 CCSID_FROM_1    CHAR(8) INIT ('//IGNORE'),
 *            10 CCSID_FROM_2    CHAR(1) INIT ('00'X);
 *   DCL  1   FLICV_TO,
 *            10 CCSID_TO        CHAR(4) INIT ('UTF8'),
 *            10 CCSID_TO_2      CHAR(1) INIT ('00'X);
 *   DCL  1   FLICV_TO_K         CHAR(5);
 *   DCL  1   FLICV_FROM_K       CHAR(17);
 *   DCL  1   FLICV_HDL          BIN FIXED(31,0) INIT (0) ALIGNED;
 *   DCL  1   FLICV_RC           BIN FIXED(31,0) INIT (0);
 *   DCL  1   IN_PTR             POINTER;
 *   DCL  1   OUT_PTR            POINTER;
 *   DCL  1   INLEFT             BIN FIXED(31,0) INIT (0) ALIGNED;
 *   DCL  1   OUTLEFT            BIN FIXED(31,0) INIT (0) ALIGNED;
 * .......
 *
 * .......
 * GET_CCSID_LIST:
 * PROCEDURE;
 *           CALL PLIFILL (ADDR(DISPAREA), '00'X, SIZE(PRINT_AREA));
 *           CALL FLICONV_LIST(LIST_PTR, DISPAREA);
 * .......
 * END GET_CCSID_LIST;
 * *
 * OPEN_FLICONV:
 * PROCEDURE;
 *           FLICV_TO_K   = CCSID_TO   || CCSID_TO_2;
 *           FLICV_FROM_K = CCSID_FROM || CCSID_FROM_1 || CCSID_FROM_2;
 *           FLICV_HDL = FLICONV_OPEN(FLICV_TO_K, FLICV_FROM_K);
 * .......
 * END OPEN_FLICONV;
 * *
 * DO_CONVERSION:
 * PROCEDURE;
 * .......
 *           FLICV_RC = FLICONV( FLICV_HDL,
 *                               IN_PTR,
 *                               INLEFT,
 *                               OUT_PTR,
 *                               OUTLEFT);
 * .......
 * DO_CONVERSION_EX:
 * *
 * CLOSE_FLICONV:
 * PROCEDURE;
 *           FLICV_HDL = FLICONV_CLOSE(FLICV_HDL);
 * END CLOSE_FLICONV;
* .......
 * </pre>
 *
 * Please have a look at the FLICONV.c sample file which implements the
 * linux like ICONV utility (fliconv) based on this library, the COBOL
 * sample SOFLCICV or the PL/1 sample SPFLCICV for mainframe systems.
 *
 * @section CCSIDS CCSID's, encoding strings and defines
 * The open function supports encoding strings and CCSIDS. The #fliconv_list()
 * function provides all supported CCSIDs, CHARSETs and the corresponding
 * encoding strings.
 *
 * @section COMPAT Compatibility mode
 * If the compiler switch FICONV is defined, then all * <em>fliconv*</em>
 * entries are also available as <em>iconv*</em> functions. I.e. to port
 * your existing code you must simply replace:
 *
 * <pre>
 * \#include<iconv.h>
 * </pre>
 * by
 * <pre>
 * \#define  FICONV
 * \#include"FLCICV.h"
 * </pre>
 *
 * With this replacement you can re-build your source. To use the
 * special features you must append one or more of the encoding string
 * specifications (see #fliconv_open()).
 *
 * @section IMPROVE Improvements compared to standard iconv implementations:
 * - Support of encoding strings and CCSIDs, list supported CCSIDs and encoding strings
 * - EBCDIC New Line (0x15) to Line Feed (0x0A) management
 * - Subset support (String.Latin, SEPA, ...) and custom user tables
 * - Recursive mapping and transliteration ('U:'->'UE')
 * - Case mapping, comprehensive reporting, byte order change handling
 * - Reads 5 and 6 byte UTF-8 encoded characters (values with preceding zeros)
 * - Slightly faster and less memory and CPU utilization
 *
 * @section DIFFS Differences to the standard iconv library:
 * - Supports more errno values (mainly for user table parsing, not for conversion itself)
 * - E2BIG is set if the output buffer is smaller than the input data multiplied by the provided expansion factor
 *   --> No data is converted if the output buffer is too small (increases performance significantly)
 * - Functions to provide about, version, license, statistics, error and other information
 * - Add a few errno-functions to manage errno in other programming languages (COBOL/PLI)
 * - Byte order mark is only printed to the output file if the BOM keyword is specified in the TO string
 * - The list function gets available encoding strings, the CCSID and the corresponding CHARSET (UTF/ASCII/EBCDIC) information
 *
 * @section SAMPLES Sample programs
 * A sample program in C with name FLICONV can be found as part of the
 * installation package for mainframe systems in the library SRCLIBC(FLICONV),
 * with the corresponding compile and link step in JOBLIB(SBUILD).
 * For other platforms (Windows, UNIX) the sample program source of FLICONV
 * is located in the 'sample' directory and the compile and link procedures
 * can be found in the Makefile of the same directory.
 *
 * This sample program implements the Linux like 'iconv' utility with all
 * features of FLAM character conversion module.
 *
 * @section ZOSHNT Hints for z/OS
 * On z/OS you must define the language level with EXTC99, as _POSIX_SOURCE
 * and use of long names to compile this sample.
 *
 *    DEFINE(_POSIX_SOURCE),LANGLVL(EXTC99),LO
 *
 **********************************************************************/
 /*! @cond PRIVATE */

#ifdef __cplusplus
   extern "C" {
#endif

#ifndef INC_FLCICV_H
#define INC_FLCICV_H

#include <stddef.h>
#include <inttypes.h>

/*! @endcond */
/**********************************************************************/

#ifdef FICONV
#  define iconv_version       fliconv_version
#  define iconv_about         fliconv_about
#  define iconv_license       fliconv_license
#  define iconv_zusmode       fliconv_zusmode
#  define iconv_open          fliconv_open
#  define iconv_close         fliconv_close
#  define iconv               fliconv
#  define iconvlist           fliconv_list
#  define iconv_seterrno      fliconv_seterrno
#  define iconv_geterrno      fliconv_geterrno
#  define iconv_chkerrno      fliconv_chkerrno
#  define iconv_strerror      fliconv_strerror
#  define iconv_error_trace   fliconv_error_trace
#  define iconv_expansion     fliconv_expansion
#  define iconv_position      fliconv_position
#  define ICONVLISTBYTES      FLICONV_LISTBYTES
#  define ICONV_EINVAL        FLICONV_EINVAL
#  define ICONV_ENOMEM        FLICONV_ENOMEM
#  define ICONV_EILSEQ        FLICONV_EILSEQ
#  define ICONV_ENOMSG        FLICONV_ENOMSG
#  define ICONV_E2BIG         FLICONV_E2BIG
#  define ICONV_REOPEN        FLICONV_REOPEN
#  define ICONV_BOMCHG        FLICONV_BOMCHG
#  define ICONV_UTFAIL        FLICONV_UTFAIL
#  define ICONV_MAXEXP        FLICONV_MAXEXP
#  define ICONV_LICVIL        FLICONV_LICVIL
#  define ICONV_WITSPC        FLICONV_WITSPC
#  define ICONV_IBMUCS        FLICONV_IBMUCS
#  define ICONV_REREST        FLICONV_REREST
#endif

/**********************************************************************/

/**
 * @defgroup ERRCOD Error codes
 * Use this predefined values in function *fliconv_chkerrno().
 * @{
 */
#define FLICONV_EINVAL        1   /**< Incomplete character*/
#define FLICONV_ENOMEM        2   /**< Not enought memory*/
#define FLICONV_EILSEQ        3   /**< Invalid character*/
#define FLICONV_ENOMSG        4   /**< Malformed encoding*/
#define FLICONV_E2BIG         5   /**< Need more space*/
#define FLICONV_REOPEN        6   /**< Reopen failed (internal error)*/
#define FLICONV_BOMCHG        7   /**< Byte order change*/
#define FLICONV_UTFAIL        8   /**< Parse of user table failed*/
#define FLICONV_MAXEXP        9   /**< Maximal expansion reached*/
#define FLICONV_LICVIL        10  /**< License violation*/
#define FLICONV_WITSPC        11  /**< Output whitespace handling*/
#define FLICONV_IBMUCS        12  /**< Error from IBM Unicode Services*/
#define FLICONV_REREST        13  /**< Remaining rest*/
/** @} */
/**********************************************************************/

/**
 * @defgroup MISC Miscellaneous stuff
 * @{
 */

/**
 * @brief Internal buffer sizes for listings
 *
 * Use this value to allocate the data buffer written to by the default
 * formatting function.
 *
 * Example for C:
 * <pre>
 * char data[FLICONV_LISTBYTES]
 * fliconv_list(NULL,data)
 * </pre>
 */
#define FLICONV_LISTBYTES     8192

/**********************************************************************/

/**
 * @brief Typedef of function pointer for *do_one* call back function
 *
 * A call back function that is used in function #fliconv_list() to
 * format the output of the supported CCSIDs, CHARSETs and encoding
 * strings.
 *
 * @param[in]    namescount 3 + amount of aliases for this CCSID
 * @param[in]    names      array of pointer to the CCSID, CHARSET, encoding string and it's aliases
 * @param[inout] data       pointer to the data buffer (handle for the call back function)
 * @return                  return 0 if success anything else for an error
 */
typedef int (TfDoOneList)(unsigned int namescount, const char* const* names, void* data);
/** @} */
/**********************************************************************/

/**
 * @defgroup FUNC Functions
 * @{
 */

/**
 * @brief Retrieves version information
 *
 * Returns a string with version information for each component used.
 * This should be used in a support case.
 *
 * Example for C:
 * <pre>
 * printf("Version: %s\n",fliconv_version();
 * </pre>
 *
 * Example in Cobol:
 * <pre>
 * *
 *  DATA DIVISION.
 * *
 *  FILE SECTION.
 *  FD  OUTDAT  BLOCK CONTAINS 0 CHARACTERS
 *              RECORDING MODE V
 *              RECORD IS VARYING FROM 1 TO 240 CHARACTERS
 *                     DEPENDING ON OUTREC-LEN
 *              LABEL  RECORD IS STANDARD.
 *  01  OUTDAT-RECORD.
 *      02 FILLER   PIC X(240).
 * *
 *  FD  INDAT   BLOCK CONTAINS 0 CHARACTERS
 *              RECORDING MODE F
 *              RECORD CONTAINS 80 CHARACTERS
 *              LABEL  RECORD IS STANDARD.
 *  01  INDAT-RECORD.
 *      02 FILLER   PIC X(80).
 *
 * *
 *  WORKING-STORAGE SECTION.
 * *
 * .......
 * 77  RET-PTR        USAGE IS POINTER.
 * 77  MSGLEN         PIC  9(8) BINARY VALUE ZERO.
 * 01  DISPAREA       PIC  X(8120)     VALUE SPACES.
 * 01  MSGAREA        PIC  X(256).
 * .......
 *
 * *
 * PROCEDURE DIVISION.
 * .......
 * GET-VERSION SECTION.
 * GET-VERSION-01.
 * .......
 *      CALL  'fliconv_version' RETURNING RET-PTR
 *      SET ADDRESS OF MSGAREA  TO RET-PTR
 *      UNSTRING MSGAREA  DELIMITED BY X'00'
 *                        INTO DISPAREA COUNT MSGLEN
 *      DISPLAY 'Version Message:'
 *      DISPLAY  DISPAREA(1:MSGLEN).
 * *
 * GET-VERSION-EX.
 *     EXIT.
 * .......
 * </pre>
 *
 * Example in PL/1:
 * <pre>
 * .......
 * /-------------------------------------------------------------------
 * /   DECLARATIONS FOR USED C FUNCTIONS
 * /-------------------------------------------------------------------
 * .......
 *     DCL FLICONV_VERSION       EXT('fliconv_version')
 *                               ENTRY()
 *                               RETURNS (POINTER BYVALUE)
 *                               OPTIONS (NODESCRIPTOR);
 * .......
 * /-------------------------------------------------------------------
 * /                        E N T R I E S
 * /-------------------------------------------------------------------
 *     DCL SYSOUT FILE STREAM OUTPUT PRINT ENV (FB RECSIZE (132));
 *     DCL INPUT  FILE RECORD INPUT  ENV (FB RECSIZE (80));
 *     DCL OUTPUT FILE RECORD OUTPUT ENV (VB RECSIZE (244));
 *
 * /-------------------------------------------------------------------
 * /              O T H E R    V A R I A B L E S
 * /-------------------------------------------------------------------
 * .......
 * DCL  1  RET_PTR             POINTER;
 * DCL  1  MSGAREA             CHAR(256) BASED (RET_PTR);
 * DCL  1  MSGLEN              BIN FIXED(31,0) INIT (0);
 * .......
 *
 * .......
 * GET_VERSION:
 * PROCEDURE;
 *           CALL PLIFILL (ADDR(MSGAREA), '00'X, SIZE(MSGAREA));
 *           RET_PTR = FLICONV_VERSION();
 *           MSGLEN = INDEX(MSGAREA, '00'X, 1);
 *           PUT FILE(SYSOUT) SKIP EDIT('VERSION MESSAGE:')(A);
 *           PUT FILE(SYSOUT) SKIP EDIT
 *           (SUBSTR(MSGAREA, 1, MSGLEN)) (A);
 * .......
 * END GET_VERSION;
 * .......
 * </pre>
 *
 * @return a pointer to a static area containing the zero-terminated
 *         version string
 */
extern const char* fliconv_version(void);

/**
 * @brief Retrieves about information
 *
 * Returns a string with about information for this library on multiple
 * lines and license information if external libraries are used.
 *
 * Example for C:
 * <pre>
 * printf("About:\n%s\n",fliconv_about();
 * </pre>
 *
 * Example in Cobol:
 * <pre>
 * *
 *  DATA DIVISION.
 * *
 *  WORKING-STORAGE SECTION.
 * *
 * .......
 *  77  RET-PTR        USAGE IS POINTER.
 *  77  MSGLEN         PIC  9(8) BINARY VALUE ZERO.
 *  01  DISPAREA       PIC  X(8120)     VALUE SPACES.
 *  01  MSGAREA        PIC  X(256).
 * .......
 *
 * *
 * PROCEDURE DIVISION.
 * .......
 *     CALL  'fliconv_about' RETURNING RET-PTR
 *     SET ADDRESS OF MSGAREA  TO RET-PTR
 *     UNSTRING MSGAREA  DELIMITED BY X'00'
 *                       INTO DISPAREA COUNT MSGLEN
 *     DISPLAY 'About Message:'
 *     DISPLAY  DISPAREA(1:MSGLEN)
 * .......
 * </pre>
 *
 * @return a pointer to a static area containing the zero-terminated
 *         about string
 */
extern const char* fliconv_about(void);

/**
 * @brief Retrieves the license text
 *
 * This function can be used to get the current license text on multiple
 * lines. The license text defines the permissible use of this library.
 *
 * Example for C:
 * <pre>
 * printf("License:\n%s\n",fliconv_license();
 * </pre>
 *
 * Example in Cobol:
 *
 * <pre>
 * *
 *  DATA DIVISION.
 * *
 *  WORKING-STORAGE SECTION.
 * *
 * .......
 * 77  RET-PTR        USAGE IS POINTER.
 * 77  MSGLEN         PIC  9(8) BINARY VALUE ZERO.
 * 01  DISPAREA       PIC  X(8120)     VALUE SPACES.
 * 01  MSGAREA        PIC  X(256).
 * .......
 *
 * *
 * PROCEDURE DIVISION.
 * .......
 *     CALL  'fliconv_license' RETURNING RET-PTR.
 *     SET ADDRESS OF MSGAREA  TO RET-PTR.
 * DISP-MSGS.
 *     MOVE ZERO  TO MSGLEN.
 *     UNSTRING MSGAREA  DELIMITED BY X'15' OR X'00'
 *                       INTO DISPAREA
 *                       DELIMITER DISP-DLIM COUNT MSGLEN
 *                       WITH POINTER DISP-PTR.
 *     IF  DISP-DLIM = X'15'
 *        THEN
 *           DISPLAY DISPAREA(1:MSGLEN)
 *           GO TO DISP-MSGS
 *     END-IF.
 * .......
 * </pre>
 *
 * @return a pointer to a static area with a zero-terminated string
 *         containing the current license text.
 */
extern const char* fliconv_license(void);

/**
 * @brief Returns string describing use of IBM Unicode Services
 *
 * @param pvHdl Pointer to the handle
 * @return Static pointer to Zero terminated string
 */
extern const char* fliconv_zusmode(void* pvHdl);

/**
 * This function corresponds to the *iconvlist()* function of *libiconv* and
 * can be used to get a list of supported CCSIDs, CHARSETs and encoding
 * strings. The formatting can be defined by passing a function pointer
 * of type TfDoOneList. If this function pointer is NULL, a default
 * formatting function is used. This default formatting function writes
 * to STDERR if the data pointer is also NULL. If the data pointer is
 * non-NULL and the function pointer is NULL, the data pointer must
 * point to a buffer that is at least #FLICONV_LISTBYTES bytes long. The
 * default formatting function writes the list this buffer. If the buffer
 * is shorter than #FLICONV_LISTBYTES bytes, behavior is undefined (risk
 * of segmentation fault).
 *
 * For example:
 *
 * - <tt>fliconv_list(NULL,NULL)</tt> writes the CCSID list to stderr
 * - <tt>fliconv_list(NULL,data)</tt> writes the CCSID list to the data buffer
 *
 * When specifying a custom callback function (<tt>fliconv_list(myone,mydata)</tt>)
 * the data pointer is passed to the function on each call. In contrast
 * to other *fliconv_list()* implementations, the *namescount* is at least 3
 * and the index has the meaning below:
 *
 * - 0   CCSID
 * - 1   CHARSET (not valid as input for fliconv_open())
 * - 2   Main encoding string
 * - >2  Alias encoding strings (currently not supported)
 *
 * The default formatting function writes lines (delimiter='\n') of the
 * following format to STDERR or the specified buffer. If using the
 * buffer version, the resulting string is null-terminated.
 *
 * <pre>
 * 'CCSID' CHRSET (encoding string)
 * </pre>
 *
 * The character sets below are currently supported:
 *
 * - ASCII           all single byte ASCII code pages (CP1252)
 * - EBCDIC          all single byte EBCDIC code pages (IBM1141)
 * - UTF8            for UTF-8
 * - UTF16BE         for UTF-16BE
 * - UTF16LE         for UTF-16LE
 * - UTF32BE         for UTF-32BE
 * - UTF32LE         for UTF-32LE
 * - UCS1            for UCS-1
 * - UCS2BE          for UCS-2BE
 * - UCS2LE          for UCS-2LE
 * - UCS4BE          for UCS-4BE
 * - UCS4LE          for UCS-4LE
 *
 * NOTE: UCS(*)- subset of UTF(*) with first 65536 codepoints, mostly
 * enough for usual applications
 *
 * The function may set the errno values below:
 *  - EINVAL   error in *do_one* function
 *
 *
 * Below you can find an example of a *do_one* function:
 * <pre>
 * static int oneFwrite(unsigned int         namescount,
 *                      const char* const*   names,
 *                      void*                data){
 *    int i;
 *    if(namescount<3){ return -1; }
 *
 *    fprintf((FILE*)data,"'%s' %7s (%s",names[0],names[1],names[2]);
 *    for(i=3;i<namescount;i++){
 *       fprintf((FILE*)data,"/%s",names[i]);
 *    }
 *    fprintf((FILE*)data,")\n");
 *
 *    return 0;
 * }
 * </pre>
 *
 * Example in Cobol:
 * <pre>
 * *
 *  DATA DIVISION.
 * *
 *  FILE SECTION.
 *  FD  OUTDAT  BLOCK CONTAINS 0 CHARACTERS
 *              RECORDING MODE V
 *              RECORD IS VARYING FROM 1 TO 240 CHARACTERS
 *                     DEPENDING ON OUTREC-LEN
 *              LABEL  RECORD IS STANDARD.
 *  01  OUTDAT-RECORD.
 *      02 FILLER   PIC X(240).
 * *
 *  FD  INDAT   BLOCK CONTAINS 0 CHARACTERS
 *              RECORDING MODE F
 *              RECORD CONTAINS 80 CHARACTERS
 *              LABEL  RECORD IS STANDARD.
 *  01  INDAT-RECORD.
 *      02 FILLER   PIC X(80).
 * *
 *  WORKING-STORAGE SECTION.
 * *
 * .......
 * 01  DISPAREA       PIC  X(8120)   VALUE SPACES.
 * 77  MSGLEN         PIC  9(8) BINARY VALUE ZERO.
 * 01  DISP-CCSID     PIC  X(80).
 * 77  DISP-DLIM      PIC  X.
 * 77  DISP-PTR       PIC  9(8) COMP VALUE 1.
 * .......
 *
 * *
 * PROCEDURE DIVISION.
 * .......
 * GET-CCSID-LIST SECTION.
 * GET-CCSID-LIST-01.
 * .......
 *      CALL 'fliconv_list' USING OMITTED,
 *                                DISPAREA.
 *      DISPLAY 'Supported CCSIDs:'.
 *  GET-CCSID-LIST-02.
 *      MOVE ZERO  TO MSGLEN.
 *      UNSTRING DISPAREA DELIMITED BY X'15' OR X'00'
 *                        INTO DISP-CCSID
 *                        DELIMITER DISP-DLIM COUNT MSGLEN
 *                        WITH POINTER DISP-PTR.
 *      IF  DISP-DLIM = X'15'
 *        THEN
 *           DISPLAY DISP-CCSID(1:MSGLEN)
 *           GO TO GET-CCSID-LIST-02
 *      END-IF.
 * *
 * GET-CCSID-LIST-EX.
 *     EXIT.
 * .......
 * </pre>
 *
 * Example in PL/1:
 * <pre>
 * .......
 * /-------------------------------------------------------------------
 * /   DECLARATIONS FOR USED C FUNCTIONS
 * /-------------------------------------------------------------------
 * .......
 *     DCL FLICONV_LIST          EXT('fliconv_list')
 *                               ENTRY(POINTER    BYADDR,
 *                                     CHAR(8120) BYADDR)
 *                               OPTIONS (NODESCRIPTOR);
 * .......
 *
 * /-------------------------------------------------------------------
 * /              O T H E R    V A R I A B L E S
 * /-------------------------------------------------------------------
 * .......
 * DCL  1  DISPAREA            CHAR(8120)      INIT(' ');
 * DCL  1  MSGLEN              BIN FIXED(31,0) INIT (0);
 * DCL  1  DISP_DLIM           CHAR(01)        INIT(' ');
 * DCL  1  LIST_PTR            POINTER;
 * DCL  1  PRINT_AREA          CHAR(80)        INIT (' ');
 * DCL  1  REMAINDER_LEN       BIN FIXED(31,0) INIT (256);
 * .......
 *
 * .......
 * GET_CCSID_LIST:
 * PROCEDURE;
 *           CALL PLIFILL (ADDR(DISPAREA), '00'X, SIZE(PRINT_AREA));
 *           CALL FLICONV_LIST(LIST_PTR, DISPAREA);
 *           PUT FILE(SYSOUT) SKIP EDIT('SUPPORTED CCSIDS:') (A);
 * GET_CCSID_LIST_01:
 *     MSGLEN = 0;
 *     CALL PLIFILL (ADDR(PRINT_AREA), '00'X, SIZE(PRINT_AREA));
 *     MSGLEN = INDEX(DISPAREA, '15'X, 1);
 *     IF MSGLEN = 0
 *        THEN
 *           MSGLEN = INDEX(DISPAREA, '00'X, 1);
 *     DISP_DLIM    = SUBSTR(DISPAREA, MSGLEN, 1);
 *     IF DISP_DLIM = '15'X
 *        THEN
 *           DO;
 *            PRINT_AREA=SUBSTR(DISPAREA, 1, (MSGLEN - 1));
 *            PUT FILE(SYSOUT) SKIP EDIT(PRINT_AREA)(A);
 *            REMAINDER_LEN = REMAINDER_LEN - MSGLEN;
 *            DISPAREA =
 *             SUBSTR(DISPAREA, (MSGLEN + 1), REMAINDER_LEN);
 *            GO TO GET_CCSID_LIST_01;
 *           END;
 * END GET_CCSID_LIST;
 * .......
 * </pre>
 *
 * @param[in]  do_one NULL for default formatting or function pointer to an own formatting function
 * @param[in]  data   Pointer passed to the callback function specified by *do_one*
 *
 */
extern void fliconv_list(TfDoOneList* do_one, void* data);

/**
 * @brief Open character conversion module
 *
 * Opens the character conversion module. A target and a source encoding
 * string is required. The target encoding string defines to which
 * character set the data is converted. The source encoding string
 * defines from which character set the input data is converted.
 *
 * Both strings can be enhanced to use the features below:
 *
 * Input encoding string enhancements:
 * - //BOM        Manage byte order change
 * - //NL2LF      Convert EBCDIC new line (0x15) to line feed (0x0A)
 *
 * Output encoding string enhancements:
 * - //BOM        Write byte order mark
 * - //LF2NL      Convert EBCDIC line feed (0x0A) to new line (0x15)
 * - //TOUPPER    Upper case mapping
 * - //TOLOWER    Lower case mapping
 * - //TOSUPPER   Special upper case mapping
 * - //TOSLOWER   Special lower case mapping
 * - //TOFOLD     Special case folding
 * - //TOUSER     User module/table defined case mapping
 * - //IGNORE     Ignore invalid characters
 * - //TRANSLIT['('[systab]')'] Transliterate invalid characters [ICONV]
 * - //SUBSTITUTE['('[codepoint_list]')'] Substitute invalid characters [0x1A]
 * - //USRMOD'('module_name')'            Use a predefined user table module
 * - //USRTAB'('file_name')'              Use a custom user table text file
 * - //REPORT['('[file_name]')']          Write a report file [STDERR]
 * - //NFD        Normalisation Form D (Canonical Decomposition)
 * - //NFC        Normalisation Form D (Canonical Decomposition, followed by Canonical Composition)
 * - //COMBINED   Character conversion with combined character support
 *
 * Currently supported system transliteration tables:
 * - ICONV       Transliteration table of libiconv
 *
 * Currently supported user table module names:
 * - CCUTNPAS    UCS subset for String-Latin (XOEV/NPA, with best fit mapping and case folding)
 * - CCUTSPEA    UCS subset for SEPA (all valid UTF-8 character < 128, with transliteration)
 * - CCUTDELA    UCS subset of IBM1141, CP1252 and ISO8859-15 (only CP check)
 * - CCUTDLAX    UCS Subset of IBM1141, CP1252, ISO8859-15 and XOEF (only CP check)
 *
 * For more information about custom user table text files please refer
 * to the FLCL user manual.
 *
 * Example for C:
 * <pre>
 * h=fliconv_open("UTF16LE//BOM","1141//ELF2NL//IGNORE//TRANSLIT//REPORT(report.txt)");
 * if (h==NULL) return(fliconv_geterrno());
 * </pre>
 *
 * Example in Cobol:
 * <pre>
 * *
 *  DATA DIVISION.
 * *
 *  FILE SECTION.
 *  FD  OUTDAT  BLOCK CONTAINS 0 CHARACTERS
 *              RECORDING MODE V
 *              RECORD IS VARYING FROM 1 TO 240 CHARACTERS
 *                     DEPENDING ON OUTREC-LEN
 *              LABEL  RECORD IS STANDARD.
 *  01  OUTDAT-RECORD.
 *      02 FILLER   PIC X(240).
 * *
 *  FD  INDAT   BLOCK CONTAINS 0 CHARACTERS
 *              RECORDING MODE F
 *              RECORD CONTAINS 80 CHARACTERS
 *              LABEL  RECORD IS STANDARD.
 *  01  INDAT-RECORD.
 *      02 FILLER   PIC X(80).
 *
 * *
 *  WORKING-STORAGE SECTION.
 * *
 * .......
 * 77  RET-PTR        USAGE IS POINTER.
 * 77  FLICV-HDL      PIC  9(8) COMP VALUE ZERO.
 * 77  FLICV-ERRNO    PIC  9(8) COMP.
 * 77  MSGLEN         PIC  9(8) BINARY VALUE ZERO.
 * 01  DISPAREA       PIC  X(8120)   VALUE SPACES.
 * 01  FLICONV-PARAMETER.
 *   05 FLICV-FROM.
 *      10 CCSID-FROM PIC X(8) VALUE 'IBM-1141'.
 *      10 FILLER     PIC X(8) VALUE '//IGNORE'.
 *      10 FILLER     PIC X(1) VALUE LOW-VALUE.
 *   05 FLICV-TO.
 *      10 CCSID-TO   PIC X(4) VALUE 'UTF8'.
 *      10 FILLER     PIC X(1) VALUE LOW-VALUE.
 * 01  MSGAREA     PIC X(256).
 * .......
 *
 * *
 * PROCEDURE DIVISION.
 * .......
 * OPEN-FLICONV SECTION.
 * OPEN-FLICONV-01.
 * .......
 *     CALL 'fliconv_open'  USING FLICV-TO, FLICV-FROM
 *                          RETURNING FLICV-HDL
 *     IF  FLICV-HDL = ZERO THEN error-handling ...
 * .......
 * OPEN-FLICONV-EX.
 *     EXIT.
 * .......
 * </pre>
 *   Example for error handling:
 * <pre>
 *     CALL 'fliconv_geterrno' RETURNING FLICV-ERRNO
 *     CALL 'fliconv_strerror' USING BY VALUE FLICV-ERRNO
 *                             RETURNING RET-PTR
 *     SET ADDRESS OF MSGAREA  TO RET-PTR
 *     UNSTRING MSGAREA  DELIMITED BY X'00'
 *                       INTO DISPAREA COUNT MSGLEN
 *     DISPLAY 'Error Message:'
 *     DISPLAY  DISPAREA(1:MSGLEN).
 * </pre>
 *
 * Example in PL/1:
 * <pre>
 * .......
 * /-------------------------------------------------------------------
 * /   DECLARATIONS FOR USED C FUNCTIONS
 * /-------------------------------------------------------------------
 * .......
 *     DCL FLICONV_OPEN          EXT('fliconv_open')
 *                               ENTRY(CHAR(*) VARYINGZ NONASGN BYADDR,
 *                                     CHAR(*) VARYINGZ NONASGN BYADDR )
 *                               RETURNS (BIN FIXED(31,0) BYVALUE)
 *                               OPTIONS (NODESCRIPTOR);
 * .......
 * /-------------------------------------------------------------------
 * /              O T H E R    V A R I A B L E S
 * /-------------------------------------------------------------------
 * .......
 *    DCL  1  MSGLEN              BIN FIXED(31,0) INIT (0);
 *    DCL  1  FLICV_HDL           BIN FIXED(31,0) INIT (0) ALIGNED;
 *    DCL  1  FLICV_ERRNO         BIN FIXED(31,0) INIT (0);
 *    DCL  1   FLICV_FROM,
 *             10 CCSID_FROM      CHAR(8) INIT ('IBM-1141'),
 *             10 CCSID_FROM_1    CHAR(8) INIT ('//IGNORE'),
 *             10 CCSID_FROM_2    CHAR(1) INIT ('00'X);
 *    DCL  1   FLICV_TO,
 *             10 CCSID_TO        CHAR(4) INIT ('UTF8'),
 *             10 CCSID_TO_2      CHAR(1) INIT ('00'X);
 *    DCL  1   FLICV_FROM_K       CHAR(17);
 *    DCL  1   FLICV_TO_K         CHAR(5);
 *    DCL  1  RET_PTR             POINTER;
 *    DCL  1  MSGAREA             CHAR(256) BASED (RET_PTR);
 * .......
 *
  * .......
 * OPEN_FLICONV:
 * PROCEDURE;
 *           FLICV_TO_K   = CCSID_TO   || CCSID_TO_2;
 *           FLICV_FROM_K = CCSID_FROM || CCSID_FROM_1 || CCSID_FROM_2;
 *           FLICV_HDL = FLICONV_OPEN(FLICV_TO_K, FLICV_FROM_K);
 *           IF FLICV_HDL = ZERO THEN error-handling ...
 * .......
 * END OPEN_FLICONV;
  * .......
 * </pre>
 *   Example for error-handling:
 * <pre>
 *           FLICV_ERRNO = FLICONV_GETERRNO();
 *           CALL PLIFILL (ADDR(MSGAREA), '00'X, SIZE(MSGAREA));
 *           RET_PTR = FLICONV_STRERROR(FLICV_ERRNO);
 *           MSGLEN = INDEX(MSGAREA, '00'X, 1);
 *           PUT FILE(SYSOUT) SKIP EDIT('Error Message:') (A);
 *           PUT FILE(SYSOUT) SKIP EDIT(SUBSTR(MSGAREA, 1, MSGLEN))(A);
 * </pre>
 *
 * The function may set the errno values below:
 * - EINVAL   parameter wrong or not supported
 * - ENOMEM   allocation failed, not enough space left
 * - UTFAIL   loading the user table failed
 * - MAXEXP   maximum expansion reached
 * - LICVIL   license violation
 * - WITSPC   Output whitespace handling
 * - IBMUCS   Error from IBM Unicode Services
 * - REREST   Remaining rest
 *
 * You can use fliconv_strerror() to get a corresponding error
 * message and fliconv_error_trace() to get more error information.
 *
 * @param[in] pcTo_Code   Target encoding string
 * @param[in] pcFrmCode   Source encoding string
 *
 * @return a pointer to a handle to manage character conversion, must be
 *         passed to subsequent functions, NULL in case of an error.
 *
 */
extern void* fliconv_open( const char* pcTo_Code, const char* pcFrmCode);

/**
 * @brief Close character conversion module
 *
 * The module must be closed through this function after conversion is
 * finished. All allocated resources are released.
 *
 * You can use #fliconv_strerror() to get an corresponding error
 * message and #fliconv_error_trace() to get more error information.
 *
 * Example for C:
 * <pre>
 * fliconv_close(h);
 * </pre>
 *
 * Example in Cobol:
 * <pre>
 * *
 *  DATA DIVISION.
 * *
 *  WORKING-STORAGE SECTION.
 * *
 * .......
 *   77  FLICV-HDL      PIC  9(8) COMP VALUE ZERO.
 * .......
 *
 * *
 * PROCEDURE DIVISION.
 * .......
 * CLOSE-FLICONV SECTION.
 * CLOSE-FLICONV-01.
 * .......
 *     CALL 'fliconv_close' USING BY VALUE  FLICV-HDL
 * .......
 * CLOSE-FLICONV-EX.
 *     EXIT.
  * .......
 * </pre>
 *
 * Example in PL/1:
 * <pre>
  * .......
 * /-------------------------------------------------------------------
 * /   DECLARATIONS FOR USED C FUNCTIONS
 * /-------------------------------------------------------------------
 * .......
 *    DCL FLICONV_CLOSE          EXT('fliconv_close')
 *                               ENTRY(BIN FIXED(31,0) byvalue)
 *                               RETURNS (BIN FIXED(31,0) byvalue)
 *                               OPTIONS (NODESCRIPTOR);
 * .......

 * /-------------------------------------------------------------------
 * /              O T H E R    V A R I A B L E S
 * /-------------------------------------------------------------------
 * .......
 *   DCL  1   FLICV_HDL          BIN FIXED(31,0) INIT (0) ALIGNED;
 * .......
 *
 * .......
 * CLOSE_FLICONV:
 * PROCEDURE;
 *           FLICV_HDL = FLICONV_CLOSE(FLICV_HDL);
 * END CLOSE_FLICONV;
 * .......
 * </pre>
 *
 * @param[in] hdl Handle from fliconv_open()
 * @return Upon successful completion 0 is returned. Otherwise, -1 is
 *         returned.
 */
extern int fliconv_close(void* hdl);

/**
 * @brief Convert a data block
 *
 * Converts at most <em>*inbytesleft</em> bytes starting at <em>*inbuf</em>,
 * writing at most <em>*outbytesleft</em> bytes starting at <em>*outbuf</em>.
 * The function decrements <em>*inbytesleft</em> and increments <em>*inbuf</em>
 * by the same amount. On the other side, it also decrements <em>*outbytesleft</em>
 * and increments <em>*outbuf</em> by the same amount.
 *
 * If <em>*inbytesleft</em> multiplied by the maximum expansion factor is
 * greater than <em>*outbytesleft</em>, no data is converted, errno is set
 * to E2BIG and -1 is returned. You have to reallocate <em>*outbuf</em> in
 * order to provide enough space for conversion.
 *
 * If <em>*inbytesleft</em> is not 0, an incomplete multi-byte character
 * might have been found at the end of the input data block
 * (return code = -1, errno = EINVAL). If the input block was the last
 * block to be processed, the input data is incomplete. Otherwise, the
 * rest (pointed to by <em>*inbuf</em> must be at the beginning of the next
 * input block.
 *
 * To save memory for Unicode character sets the pre-calculated tables
 * are first limit to to 64k entries. If a multibyte character encountered
 * which requires more than 16 bit, then a reopen is done to pre-calculate
 * bigger (1.1M) tables. If not enought memory available the reopen can fail.
 *
 * The function may set the errno values below:
 *  - EILSEQ   invalid byte sequence
 *  - ENOMSG   malformed encoding
 *  - EINVAL   incomplete  byte sequence
 *  - REOPEN   reopen failed
 *  - BOMCHG   byte order changed
 *  - E2BIG    out buffer smaller than input_length*expansion
 *  - E2BIG    after reopen, expansion factor changed
 *  - MAXEXP   in reopen, max expansion reached
 *
 * You can use #fliconv_strerror() to get a corresponding error
 * message and #fliconv_error_trace() to get more error information.
 *
 * Example for C:
 * <pre>
 * r=iconv(h,&inDat,&inLen,&outDat,&outLen);
 * </pre>
 *
 * Example in Cobol:
 * <pre>
 * *
 *  DATA DIVISION.
 * *
 *  WORKING-STORAGE SECTION.
 * *
 * .......
 * 77  FLICV-HDL      PIC  9(8) COMP VALUE ZERO.
 * 77  IN-PTR         USAGE IS POINTER.
 * 77  INLEFT         PIC  9(8) COMP.
 * 77  OUT-PTR        USAGE IS POINTER.
 * 77  OUTLEFT        PIC  9(8) COMP.
 * 77  FLICV-RC       PIC S9(8) COMP VALUE ZERO.
 * .......
 *
 * *
 * PROCEDURE DIVISION.
 * .......
 * *
 * DO-CONVERSION SECTION.
 * DO-CONVERSION-01.
 * .......
 *     CALL  'fliconv'      USING BY VALUE     FLICV-HDL,
 *                                BY REFERENCE IN-PTR,
 *                                BY REFERENCE INLEFT,
 *                                BY REFERENCE OUT-PTR,
 *                                BY REFERENCE OUTLEFT
 *                          RETURNING FLICV-RC
 * .......
 * DO-CONVERSION-EX.
 *     EXIT.
 * .......
 * </pre>
 *
 * Example in PL/1:
 * <pre>
 * /-------------------------------------------------------------------
 * /   DECLARATIONS FOR USED C FUNCTIONS
 * /-------------------------------------------------------------------
 * .......
 *     DCL FLICONV               EXT('fliconv')
 *                               ENTRY
 *                                    (BIN FIXED(31,0) BYVALUE,
 *                                     POINTER         BYADDR,
 *                                     BIN FIXED(31,0) BYADDR,
 *                                     POINTER         BYADDR,
 *                                     BIN FIXED(31,0) BYADDR)
 *                               RETURNS (BIN FIXED(31,0) BYVALUE)
 *                               OPTIONS (NODESCRIPTOR);
 * .......
 * /-------------------------------------------------------------------
 * /              O T H E R    V A R I A B L E S
 * /-------------------------------------------------------------------
 * .......
 * DCL  1  FLICV_HDL           BIN FIXED(31,0) INIT (0) ALIGNED;
 * DCL  1  IN_PTR              POINTER;
 * DCL  1  INLEFT              BIN FIXED(31,0) INIT (0) ALIGNED;
 * DCL  1  OUT_PTR             POINTER;
 * DCL  1  OUTLEFT             BIN FIXED(31,0) INIT (0) ALIGNED;
 * DCL  1  FLICV_RC            BIN FIXED(31,0) INIT (0);
 * .......
 *
 * .......
 * DO_CONVERSION:
 * PROCEDURE;
 * .......
 *           FLICV_RC = FLICONV( FLICV_HDL,
 *                               IN_PTR,
 *                               INLEFT,
 *                               OUT_PTR,
 *                               OUTLEFT);
 * .......
 * DO_CONVERSION_EX:
 * .......
 * </pre>
 *
 * @param[in]    cd           Handle from fliconv_open()
 * @param[inout] inbuf        Pointer to the input data buffer
 * @param[inout] inbytesleft  Input data length
 * @param[inout] outbuf       Pointer to the output data buffer
 * @param[inout] outbytesleft Output buffer size
 *
 * @return The function returns the number of characters converted in a
       non-reversible way (ignored, substituted or transliterated) during
       this call; reversible conversions are not counted. If the return
       code > 0, then entries in the report file can be found. A positive
       return code is a warning that an internal error handling was done.
       In case of error, it sets errno and returns (size_t) -1.
 */
extern size_t fliconv (       void*    cd,
                              char**   inbuf,
                              size_t*  inbytesleft,
                              char**   outbuf,
                              size_t*  outbytesleft);

/**
 * @brief Set error number
 *
 * Use this function in non C programming languages to set the global
 * variable *errno* of the c runtime library. For error handling you
 * must set *errno* in front of a call to 0, to check after the call
 * the value.
 *
 * Example for C:
 * <pre>
 * fliconv_seterrno(0);
 * r=fliconv(...);
 * if (r==-1) {
 *    if (fliconv_chkerrno(fliconv_geterrno(),FLICONV_EINVAL)) {
 *     ...
 *    }
 * }
 * </pre>
 *
 * Example in Cobol:
 * <pre>
 * CALL  'fliconv_seterrno'   USING BY VALUE ERRNO.
 * </pre>
 *
 * @param[in] err Error number (mainly only 0 make sense)
 */
extern void fliconv_seterrno(const int err);

/**
 * @brief Get error number
 *
 * Use this function in non C programming languages to get the global
 * variable *errno* of the c runtime library. For error handling you
 * need access to the *errno* after a call. Attention: This integer
 * contains platform dependent values. You can use the function
 * *fliconv_chkerrno()* to verify the *errno* against the predefined
 * platform independent values above.
 *
 * Example for C:
 * <pre>
 * if (fliconv_chkerrno(fliconv_geterrno(),FLICONV_E2BIG)) ...
 * </pre>
 *
 * Example in Cobol:
 * <pre>
 * *
 *  DATA DIVISION.
 * *
 *  WORKING-STORAGE SECTION.
 * *
 * .......
 *  77  FLICV-ERRNO    PIC  9(8) COMP.
 *  77  RET-PTR        USAGE IS POINTER.
 *  01  MSGAREA        PIC  X(256).
 *  01  DISPAREA       PIC  X(8120)   VALUE SPACES.
 *  77  MSGLEN         PIC  9(8) BINARY VALUE ZERO.
 * .......
 *
 * *
 * PROCEDURE DIVISION.
 * .......
 * *
 * ERROR-FOUND SECTION.
 * ERROR-FOUND-01.
 *     CALL 'fliconv_geterrno' RETURNING FLICV-ERRNO
 *     DISPLAY FLICV-ERRNO
 * *
 *     CALL 'fliconv_strerror' USING BY VALUE FLICV-ERRNO
 *                             RETURNING RET-PTR
 * *
 *     SET ADDRESS OF MSGAREA  TO RET-PTR
 * *
 *     UNSTRING MSGAREA  DELIMITED BY X'00'
 *                       INTO DISPAREA COUNT MSGLEN
 * *
 *     DISPLAY 'Error Message:'.
 *     DISPLAY  DISPAREA(1:MSGLEN).
 * *
 * ERROR-FOUND-EX.
 *     EXIT.
 * </pre>
 *
 * Example in PL/1:
 * <pre>
 * .......
 * /-------------------------------------------------------------------
 * /   DECLARATIONS FOR USED C FUNCTIONS
 * /-------------------------------------------------------------------
 * .......
 *     DCL FLICONV_GETERRNO      EXT('fliconv_geterrno')
 *                               ENTRY()
 *                               RETURNS (BIN FIXED(31,0) BYVALUE)
 *                               OPTIONS (NODESCRIPTOR);
 * *
 *     DCL FLICONV_STRERROR      EXT('fliconv_strerror')
 *                               ENTRY(BIN FIXED(31,0) BYVALUE)
 *                               RETURNS (POINTER BYVALUE)
 *                               OPTIONS (NODESCRIPTOR);
 * .......
 * /-------------------------------------------------------------------
 * /              O T H E R    V A R I A B L E S
 * /-------------------------------------------------------------------
 * .......
 *     DCL  1  RET_PTR             POINTER;
 *     DCL  1  MSGAREA             CHAR(256) BASED (RET_PTR);
 *     DCL  1  FLICV_ERRNO         BIN FIXED(31,0) INIT (0);
 *     DCL  1  MSGLEN              BIN FIXED(31,0) INIT (0);
 * .......
 *
 * .......
 * ERROR_FOUND:
 * PROCEDURE;
 * .......
 *          FLICV_ERRNO = FLICONV_GETERRNO();
 * *
 *          PUT FILE(SYSOUT) SKIP EDIT
 *          (FLICV_ERRNO) (P'99999999');
 * *
 *          CALL PLIFILL (ADDR(MSGAREA), '00'X, SIZE(MSGAREA));
 * *
 *          RET_PTR = FLICONV_STRERROR(FLICV_ERRNO);
 * *
 *          MSGLEN = INDEX(MSGAREA, '00'X, 1);
 * *
 *          PUT FILE(SYSOUT) SKIP EDIT
 *          ('Error Message:') (A);
 * *
 *          PUT FILE(SYSOUT) SKIP EDIT(SUBSTR(MSGAREA, 1, MSGLEN))(A);
 * *
 * END ERROR_FOUND;
 * .......
 * </pre>
 *
 *
 * @return Error number
 */
extern int fliconv_geterrno(void);

/**
 * @brief Check error number
 *
 * Use this function in non C programming languages to check the global
 * variable *errno* of the C runtime environment. The value *err* is
 * provided by function *fliconv_geterrno()* and the value *val* is one
 * of the predefined constants above.
 *
 * Example for C:
 * <pre>
 * if (fliconv_chkerrno(fliconv_geterrno(),FLICONV_E2BIG)) ...
 * </pre>
 *
 * @param err  Error number
 * @param val  Error value (see defined values above)
 * @return     1 if match, 0 don't match or unknown
 */
extern int fliconv_chkerrno(const int err, const int val);

/**
 * @brief Get error message
 *
 * This function can be used to retrieve a human-readable error message
 * using the errno set by <em>fliconv</em> functions.
 *
 * Example for C:
 * <pre>
 * printf("Error message: %s\n",fliconv_strerror(fliconv_geterrno());
 * </pre>
 *
 * Example in Cobol:
 * <pre>
 * *
 *  DATA DIVISION.
 * *
 *  WORKING-STORAGE SECTION.
 * *
 * .......
 *  77  FLICV-ERRNO    PIC  9(8) COMP.
 *  77  RET-PTR        USAGE IS POINTER.
 *  01  MSGAREA        PIC  X(256).
 *  01  DISPAREA       PIC  X(8120)   VALUE SPACES.
 *  77  MSGLEN         PIC  9(8) BINARY VALUE ZERO.
 * .......
 *
 * *
 * PROCEDURE DIVISION.
 * .......
 * *
 * ERROR-FOUND SECTION.
 * ERROR-FOUND-01.
 *     CALL 'fliconv_geterrno' RETURNING FLICV-ERRNO
 *     DISPLAY FLICV-ERRNO
 * *
 *     CALL 'fliconv_strerror' USING BY VALUE FLICV-ERRNO
 *                             RETURNING RET-PTR
 * *
 *     SET ADDRESS OF MSGAREA  TO RET-PTR
 * *
 *     UNSTRING MSGAREA  DELIMITED BY X'00'
 *                       INTO DISPAREA COUNT MSGLEN
 * *
 *     DISPLAY 'Error Message:'.
 *     DISPLAY  DISPAREA(1:MSGLEN).
 * *
 * ERROR-FOUND-EX.
 *     EXIT.
 * </pre>
 *
 * Example in PL/1:
 * <pre>
 * .......
 * /-------------------------------------------------------------------
 * /   DECLARATIONS FOR USED C FUNCTIONS
 * /-------------------------------------------------------------------
 * .......
 *     DCL FLICONV_GETERRNO      EXT('fliconv_geterrno')
 *                               ENTRY()
 *                               RETURNS (BIN FIXED(31,0) BYVALUE)
 *                               OPTIONS (NODESCRIPTOR);
 * *
 *     DCL FLICONV_STRERROR      EXT('fliconv_strerror')
 *                               ENTRY(BIN FIXED(31,0) BYVALUE)
 *                               RETURNS (POINTER BYVALUE)
 *                               OPTIONS (NODESCRIPTOR);
 * .......
 * /-------------------------------------------------------------------
 * /              O T H E R    V A R I A B L E S
 * /-------------------------------------------------------------------
 * .......
 *     DCL  1  RET_PTR             POINTER;
 *     DCL  1  MSGAREA             CHAR(256) BASED (RET_PTR);
 *     DCL  1  FLICV_ERRNO         BIN FIXED(31,0) INIT (0);
 *     DCL  1  MSGLEN              BIN FIXED(31,0) INIT (0);
 * .......
 *
 * .......
 * ERROR_FOUND:
 * PROCEDURE;
 * .......
 *          FLICV_ERRNO = FLICONV_GETERRNO();
 * *
 *          PUT FILE(SYSOUT) SKIP EDIT
 *          (FLICV_ERRNO) (P'99999999');
 * *
 *          CALL PLIFILL (ADDR(MSGAREA), '00'X, SIZE(MSGAREA));
 * *
 *          RET_PTR = FLICONV_STRERROR(FLICV_ERRNO);
 * *
 *          MSGLEN = INDEX(MSGAREA, '00'X, 1);
 * *
 *          PUT FILE(SYSOUT) SKIP EDIT
 *          ('Error Message:') (A);
 * *
 *          PUT FILE(SYSOUT) SKIP EDIT(SUBSTR(MSGAREA, 1, MSGLEN))(A);
 * *
 * END ERROR_FOUND;
 * .......
 * </pre>
 *
 * @param[in] err A valid error code
 * @return A pointer to a static area with a zero-terminated string
 *         containing a FLAM error message matching the passed error code
 *         as one line. (no LF)
 *
 */
extern const char* fliconv_strerror(int err);

/**
 * @brief Get error trace
 *
 * This function can be used to get an error trace after a call to
 * #fliconv_open(), #fliconv() or #fliconv_close(). The error trace
 * contains the FLAM error stack.
 *
 * Example for C:
 * <pre>
 * printf("Error message: %s\n",fliconv_strerror(fliconv_geterrno());
 * printf("Error trace:\n%s\n" ,fliconv_error_trace());
 * </pre>
 *
 * @return a pointer to a static area with a zero-terminated string
 *         containing the current FLAM error trace on several lines
 */
extern const char* fliconv_error_trace(void);

/**
 * @brief Get error message
 *
 * This function can be used to get the last error message after a call to
 * #fliconv(). The message contains information about the
 * last error of the FLAM ICV module.
 *
 * Example for C:
 * <pre>
 * printf("ICV Error message:\n%s\n", fliconv_error_msg(hdl));
 * </pre>
 *
 * @param[in] cd Conversion descriptor (the handle returned from #fliconv_open())
 * @return a pointer to a static area with a zero-terminated string
 *         containing the last FLAM ICV error message
 */
extern const char* fliconv_error_msg(void* cd);

/**
 * @brief Get expansion factor
 *
 * Returns the maximum expansion factor. This should be used to allocate
 * enough memory for the output buffer. You must pass a valid descriptor
 * obtained from #fliconv_open(). This function must be used after #fliconv_open()
 * and if you get *errno==E2BIG*.
 *
 * Example for C:
 * <pre>
 * outlen=inlen*fliconv_expansion(h);
 * outbuf=(unsigned char*)realloc(outbuf,outlen);
 * </pre>
 *
 * Example in Cobol:
 * <pre>
 * *
 *  DATA DIVISION.
 * *
 *  WORKING-STORAGE SECTION.
 * *
 * .......
 *  77  FLICV-HDL      PIC  9(8) COMP VALUE ZERO.
 *  77  BUFFEXP        PIC  9(8) COMP VALUE ZERO.
 * .......
 *
 * *
 * PROCEDURE DIVISION.
 * .......
 * *
 * CHECK-BUFFER-SPACE SECTION.
 * CHECK-BUFFER-SPACE-01.
* .......
 *     CALL 'fliconv_expansion' USING BY VALUE FLICV-HDL
 *                              RETURNING BUFFEXP
 * *
 *     DISPLAY 'Expansion factor: ' BUFFEXP
 * ......
 * CHECK-BUFFER-SPACE-EX.
 *     EXIT
 * .......
 * </pre>
 *
 * Example in PL/1l:
 * <pre>
 * .......
 * /-------------------------------------------------------------------
 * /   DECLARATIONS FOR USED C FUNCTIONS
 * /-------------------------------------------------------------------
 * .......
 *     DCL FLICONV_EXPANSION     EXT('fliconv_expansion')
 *                               ENTRY(BIN FIXED(31,0) BYVALUE)
 *                               RETURNS (BIN FIXED(31,0) BYVALUE)
 *                               OPTIONS (NODESCRIPTOR);
 * .......
 * /-------------------------------------------------------------------
 * /              O T H E R    V A R I A B L E S
 * /-------------------------------------------------------------------
 * .......
 *     DCL  1  FLICV_HDL  BIN FIXED(31,0) INIT (0) ALIGNED;
 *     DCL  1  BUFFEXP    BIN FIXED(31,0) INIT (0);
 * .......
 *
 * .......
 * CHECK_BUFFER_SPACE:
 * PROCEDURE;
 * .......
 *          BUFFEXP = FLICONV_EXPANSION(FLICV_HDL);
 * *
 *          PUT FILE(SYSOUT) SKIP EDIT
 *          EDIT('EXPANSION FACTOR: ', BUFFEXP) (A,P'999999999');
 * .......
 * END CHECK_BUFFER_SPACE;
 * .......
 * </pre>
 *
 * @param[in] cd   Conversion descriptor
 * @return         Expansion factor (0 in case of an error)
 *
 */
extern int fliconv_expansion(void* cd);

/**
 * @brief Get position
 *
 * Return the current position as byte offset. This is mainly for error
 * handling or statistics (before close). The position is the amount of
 * processed bytes. To point to the wrong byte in the case of an error
 * an addition of 1 is required.
 *
 * Example for C:
 * <pre>
 * printf("Error at byte %"PRIi64"\n",fliconv_position()+1);
 * printf("Statistics: Processed %"PRIi64" bytes\n",fliconv_position());
 * </pre>
 *
 * @param[in] cd   Conversion descriptor
 * @return         Current position or 0 if no position available
 */
extern int64_t fliconv_position(void* cd);

/** @} */
/**********************************************************************/

/*! @cond PRIVATE */
#endif /* INC_FLCICV_H */

#ifdef __cplusplus
   }
#endif
/*! @endcond */

/**********************************************************************/
