/**
 * @file FL4RECUC.h
 * @brief Specification of FLAM4 Record Interface (upper case entries)
 *
 * The FLAM4 record interface only uses variables whose types are given in the Typedef section
 *
 * @author limes datentechnik gmbh
 * @date  04.12.2018
 * @copyright (c) 2018 limes datentechnik gmbh
 *
 * @mainpage FLAM4 Record Interface
 *
 * This interface provides a platform independent record-oriented read
 * and write access to <b>FLAM4</b> files. It contains all functions of the
 * Windows, UNIX and HOST record interfaces to provide backward compatibility,
 * required for sequential access.
 *
 * This stub provides the function names in upper case for Windows
 * and Unix systems as on the mainframe. All parameters are
 * call-by-reference and no return value will be used. There are 4 types
 * of parameters:
 *
 * <pre>
 * POINTER:   pointer to an address (usually 32 or 64 bit)
 * INTEGER:   pointer to a 32 bit number in two's complement
 * STRING[x]: pointer to a byte (8 bit) array of length x
 * STRING:    pointer to a variable length byte (8 bit) array
 * </pre>
 *
 * It provides functions similar to the record-oriented file I/O functions
 * used with COBOL, PL/I or assembler on mainframes. Only the file open
 * function differs in that it gives 3 different open function and a few
 * setter (or FLMSET()) which must be called in the right sequence, to
 * open a FLAMFILE of version 4. To simplify the use of FKME (FLAM key
 * management extensions) we have add the callable service FLMKME, which
 * works like FLMPWD.
 *
 * FL4REC consists of a number of subroutines that can be called by any
 * programming language such as COBOL, PL/I, C, FORTRAN, etc., as well as
 * by ASSEMBLER programs. Except for the key descriptions all parameters
 * are implemented as elementary data types (INTEGER, STRING). Deliberately
 * no control blocks are required to avoid alignment problems and additional
 * copying of parameter values before and after a function call. Key
 * descriptions are organized as a structured data type in order to shorten
 * the parameter list.
 *
 * Application programs written in C must include the header
 * <code>FL4REC.h</code>. This C header file contains the definitions of
 * the symbolic constants, as well as the structure of the key description.
 * These definitions must be ported to other programming languages accordingly
 * if C is not used.
 *
 * @section ARGS Function arguments
 * All argument lists begin with an ID, which identifies the compression
 * file uniquely. This flmid argument contains the address of the work
 * area for the compressed file, which was specified by #FLMOPN(), and must
 * not be modified until #FLMCLS(). All other arguments are only relevant
 * to the function to which they are transferred.
 *
 * The identification is followed by a return code that informs the caller
 * about successful execution or occurring errors. Processing of a
 * compressed file always starts with function FLMOPN that assigns the
 * program to the compressed file and defines the operation mode. A file
 * opened successfully must always be closed with function FLMCLS. There
 * are no messages generated at the record level interface. During transfer
 * of original data the parameter RECORD always contains the true data
 * without any length fields or record delimiters. Or the parameter RECPTR
 * points to a field with such a content. The parameter RECLEN always
 * contains the length of the true data (exclusive length).
 *
 * COBOL programs can be translated using the <b>DYNAM</b> option. As a result,
 * the FLAM modules are loaded from the library only at the moment of
 * execution. If a dynamic call is not wanted (<b>NO-DYNAM</b> option in COBOL
 * or V constants in ASSEMBLER), the FLAM module FL4REC should be
 * specified explicitly when linking.

 * @section MFEDZ Micro Focus EDZ support
 * The API is supported also in MF-EDZ environments. See install.txt on
 * Windows or Unix for more information.
 *
 * <b>Functions passing pointer adresses, for example #FLMLOC(), only work if the cobol
 * compiler directiv AMODE is NOT used. With AMODE mainframe pointers are used in the
 * cobol program which cannot be converted.</b>
 *
 * For use with Micro Focus Enterprise Server the following environment
 * variables might be used.
 *
 * <dl>
 * <dt>FLAM4MF=unset:</dt><dd>
 *      The filename needs to be specified as either <code>DD:name</code> or <code>//'name'</code> if the Micro Focus support
 *      is needed. Otherwise normal <b>FLAM4</b> use is done.<br>
 *      If <code>DD:name</code> or <code>//'name'</code> cannot be accessed an error is returned.</dd>
 * <dt>FLAM4MF=encoding:</dt><dd>
 *      Micro Focus libraries will be used and an error is returned if they are not found.<br>
 *      The encoding is used to automatically convert all input character strings from this to the local system encoding.
 *      The output character strings are converted from the local system to this encoding.<br>
 *      The command <code>flcl info get.enc</code> prints a list of all supported encodings.<br>
 *      For convenience the strings <code>:EBCDIC</code> or <code>:ASCII</code> might be used.</dd>
 *      If the encoding strings begins with 'IBM' big endian is assumed and binary values will be byte swapped.
 * <dt>FLAM4MF=YES:</dt><dd>
 *      Micro Focus libraries will be used and an error is returned if they are not found.<br>
 *      No character conversion is done.</dd>
 * <dt>FLAM4MF=NO:</dt><dd>
 *      Micro Focus support is switched off, standard <b>FLAM4</b> use.<br>
 *      This must be done in order to work with filenames starting with <code>DD:</code></dd>
 * </dl>
 * For tracing:
 * <dl>
 * <dt>FLAM4MF_TRACEFILE=unset</dt><dd>
 *      Without trace file name tracing of library calls is omitted.</dd>
 * <dt>FLAM4MF_TRACEFILE=filename</dt><dd>
 *      trace output of library function calls is written to <code>filename</code></dd>
 * </dl>
 * For system symbols:
 * <dl>
 * <dt>FLAM4MF_STATIC_SYSVAR=filename</dt><dd>
 *      to define static system variables as environment variables.</dd>
 * <dt>FLAM4MF_STATIC_SYSVAR=filename</dt><dd>
 *      to use the JCL user exit to define dynamic system symbols</dd>
 * </dl>
 * For dynamic system variables the DD:SYSVAR is also supported.
 *
 * To use the function in COBOL the libfl4recuc.dll/so must be copied in
 * the working directory of the EDZ server under FLMOPN.dll/so and
 * FLMERR.dll/so.
 *
 * @section RETCODES Return codes
 * Return codes are mainly the same between HOST and other platforms but
 * in the higher values a few differences exists. This is mainly in cases
 * where the return code is more the reason code for an error. To simplify
 * the error handling a function (FLMERR) which provides the correct error
 * message independent of the platform are add to this interface. Below
 * you can find a list of important FLAM4 return codes. This list covers
 * any return code to control the program, if another return code occur
 * this will mainly a severe error to terminate execution.
 *
 * <table frame="no">
 *      <tr><td align="right" valign="top" width="4%"><b> 0</b></td><td width="8px"></td><td>No error, success
 * </td><tr><td align="right" valign="top" width="4%"><b> 1</b></td><td width="8px"></td><td>A record has been shortened to the length of the record buffer.
 * </td><tr><td align="right" valign="top" width="4%"><b> 2</b></td><td width="8px"></td><td>The end of the file has been reached while reading; no data is transferred.
 * </td><tr><td align="right" valign="top" width="4%"><b> 3</b></td><td width="8px"></td><td>A gap has been found in a relative file; the record length is zero.
 * </td><tr><td align="right" valign="top" width="4%"><b> 4</b></td><td width="8px"></td><td>When a record is converted to fixed format, it is padded with fill characters.
 * </td><tr><td align="right" valign="top" width="4%"><b> 5</b></td><td width="8px"></td><td>A key is missing when reading from or is invalid when writing to an index sequential file.
 * </td><tr><td align="right" valign="top" width="4%"><b> 6</b></td><td width="8px"></td><td>When reading in a group file, a new file is starting; no data is transferred.
 * </td><tr><td align="right" valign="top" width="4%"><b> 7</b></td><td width="8px"></td><td>Password / cryptokey missing on decompression.
 * </td><tr><td align="right" valign="top" width="4%"><b> 8</b></td><td width="8px"></td><td>Parameter or function not supported.
 * </td><tr><td align="right" valign="top" width="4%"><b> 9</b></td><td width="8px"></td><td>When compressing with the statistics switched on, FLAMUP or FLAM reports that the compressed file is larger than the original file (expansion).
 * </td><tr><td align="right" valign="top" width="4%"><b>10</b></td><td width="8px"></td><td>During decompression, the input file has not been recognized as being a FLAM compressed file.
 * </td><tr><td align="right" valign="top" width="4%"><b>11</b></td><td width="8px"></td><td>The format of the FLAMFILE is wrong.
 * </td><tr><td align="right" valign="top" width="4%"><b>14</b></td><td width="8px"></td><td>The checksum of a compressed record is wrong.
 * </td><tr><td align="right" valign="top" width="4%"><b>22</b></td><td width="8px"></td><td>Invalid compression method.
 * </td><tr><td align="right" valign="top" width="4%"><b>29</b></td><td width="8px"></td><td>Password missing or invalid (passed by FLMPWD).
 * </td><tr><td align="right" valign="top" width="4%"><b>30</b></td><td width="8px"></td><td>Input file is empty.
 * </td><tr><td align="right" valign="top" width="4%"><b>31</b></td><td width="8px"></td><td>Input file does not exist.
 * </td></table>
 *
 * @section COMP Programming the Record Interface at Compression
 *
 * The process of creating a FLAMFILE can be divided
 * into three phases:
 *
 * - open sequence
 * - one or more compression cycles
 * - termination (function #FLMCLS())
 *
 * The open sequence always starts calling the #FLMOPN() function.
 * Subsequently, #FLMOPD() and/or #FLMOPF() can be called if
 * #FLMOPN() was called with continue_param set. When both
 * functions are called, #FLMOPD() must be done first and also have
 * continue_param set.
 *
 * When #FLMOPD() or #FLMOPF() are not called by the application
 * program, FLAM uses implicit settings to generate such
 * calls internally. Default values used with the flam command
 * and flamup calls are not effective here.
 *
 * Finally, if encryption is used, a password must be provided
 * by a #FLMPWD() call.
 *
 * In the second phase, one compression cycle must be
 * done for each file being compressed.
 *
 * Such a cycle would normally begin with a #FLMPHD() call to
 * generate a common FLAM fileheader. Only when a single
 * file is compressed without encryption, this may be omitted.
 * If a FLAM fileheader was created, a user-specific header
 * may be appended by invoking #FLMPUH(). With Secure
 * FLAMFILEs, this invocation is mandatory even if the
 * header data length is 0.
 *
 * Now data can be submitted for compression by repeated
 * execution of #FLMPUT(). Each such call passes a record in the
 * FLAM terminology, which can be later replicated identically
 * or with modified record attributes thanks to the structure
 * information kept by FLAM. FLAM collects the data
 * passed to it in the compression buffer and controls compression
 * and the resulting output without involving the application
 * program.
 *
 * A compression cycle is terminated by a call to #FLMFLU()
 * which causes the remainder in the compression buffer to
 * be compressed and the output of the result. This function
 * also returns statistical information to the application.
 * Following this, a new compression cycle may be initiated
 * by another #FLMPHD() or the FLAMFILE can be closed by
 * calling #FLMCLS().
 *
 * Control is always returned to the invoking program. There
 * are no error exits and no error messages are generated
 * by the record interface. Rather, a return code is passed
 * back to the application.
 *
 * @section DECO Programming the Record Interface at Decompression
 *
 * As with compression, decompressing a FLAMFILE also
 * consists of three phases:
 *
 * * open sequence
 * * decompression cycle(s)
 * * termination (function #FLMCLS())
 *
 * The open sequence here consists of the same function
 * calls as at compression. Only the direction of the flow of
 * information is reversed for some of the arguments, e.g.
 * the compression mode. They are returned to the application.
 *
 * Every function used in the compression cycle has its decompression
 * counterpart that performs the complementary
 * operation. The complements for #FLMPHD() and #FLMPUH()
 * are #FLMGHD() and #FLMGUH(), respectively, that for #FLMPUT() is
 * #FLMGET(). A decompression cycle is also terminated with
 * #FLMFLU(). In addition, there is a function, #FLMPOS(), which advances
 * the read position in a FLAMFILE to the beginning
 * of the next original file. This function has no counterpart
 * with compression.
 *
 * Typically, a decompression cycle initially invokes #FLMGHD()
 * which returns details about the original file such as file
 * name, record format, etc. This may be followed by #FLMGUH()
 * to retrieve the user-specific header, if present. Subsequent
 * #FLMGET() calls retrieve one record per call, with the
 * last record of an original file being signalled by a special
 * return code. Skipping the remaining records of an original
 * file can be done by #FLMPOS() which positions to the next file
 * header. A #FLMFLU() terminates a decompression cycle that
 * may be followed by another cycle or by #FLMCLS(), which terminates
 * the processing. One #FLMFLU() or #FLMPOS() per cycle is
 * mandatory, all other calls are optional.
 *
 * Some of the function are not documented. These functions are for
 * internal use only. The setter for FLMSET are also not documented
 * because these entries are not available as load module. To simplify
 * C programming these functions can be used, the functionality is
 * explained over FLMSET. FLMSET is only available on mainframes, to
 * define additional host specific parameters after FLMOPN.
 *
 **********************************************************************/

/*! @cond PRIVATE */
#ifdef __cplusplus
   extern "C" {
#endif

#ifndef INC_FL4RECUC_H
#define INC_FL4RECUC_H

/*! @endcond */

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

#ifndef INC_TYPDEF_H
   typedef int             I32; /**< @brief signed 32 bit integer*/
   typedef unsigned int    U32; /**< @brief unsigned 32 bit integer*/
   typedef long long int   I64; /**< @brief signed 64 bit integer*/
   typedef char            C08; /**< @brief signed 8 bit integer*/
   typedef unsigned char   U08; /**< @brief unsigned 8 bit integer*/
#endif

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

/**
 * @brief The flmset_parameter enum defines constants for the #FLMSET() function.
 */

enum flmset_parameter {
   FLMSET_SPLITMODE            =   1, /**< @brief split mode 0: none, 1: serial, 2: parallel*/
   FLMSET_SPLITNUMBER          =   2, /**< @brief split number 2 - 4*/
   FLMSET_SPLITSIZE            =   3, /**< @brief split size in MiB 1 - 4095*/
   FLMSET_PRIMARY_SPACE        =   4, /**< @brief size of primary in MiB 1 - 4095*/
   FLMSET_SECONDARY_SPACE      =   5, /**< @brief size of secondary space in MiB 1 - 4095*/
   FLMSET_VOLUME               =   6, /**< @brief volume name 1-8 character*/
   FLMSET_UNIT                 =   7, /**< @brief unit name 1 - 8 character*/
   FLMSET_DATA_CLASS           =   8, /**< @brief data class name 1 - 8 character*/
   FLMSET_STORAGE_CLASS        =   9, /**< @brief storage class name 1 - 8 character*/
   FLMSET_MANAGEMENT_CLASS     =  10, /**< @brief management class name 1 - 8 character*/
   FLMSET_DISPOSTION_STATUS    =  11, /**< @brief disposition status 0: Default, 1: NEW, 2: OLD, 3: SHR, 4: MOD*/
   FLMSET_DISPOSITION_NORMAL   =  12, /**< @brief normal disposition 0: Default, 1: DELETE, 2: KEEP, 3: CATLG, 4: UNCATLG*/
   FLMSET_DISPOSITION_ABNORMAL =  13, /**< @brief abnormal disposition 0: Default, 1: DELETE, 2: KEEP, 3: CATLG, 4: UNCATLG*/
   FLMSET_CRYPTOMODE           =2001, /**< @brief mode of encryption 0: none, 1: FLAM, 2: AES*/
   FLMSET_SECUREINFO           =2002  /**< @brief secure info 0: no, 1: yes, 2: ignore, 3: member*/
};

/**
 * @brief The flmget_parameter enum defines constants for the #FLMQRY() function.
 */

enum flmget_parameter {
   FLMGET_SPLITMODE            =   1, /**< @brief split mode 0: none, 1: serial, 2: parallel*/
   FLMGET_SPLITNUMBER          =   2, /**< @brief split number 2 - 4*/
   FLMGET_SPLITSIZE            =   3, /**< @brief split size in MiB 1 - 4095*/
   FLMGET_CRYPTOMODE           =2001, /**< @brief mode of encryption 0: none, 1: FLAM, 2: AES*/
   FLMGET_SECUREINFO           =2002, /**< @brief secure info 0: no, 1: yes, 2: ignore, 3: member*/
   FLMGET_MODE                 =4001, /**< @brief general mode 0: deco/read 1: comp/write*/
   FLMGET_RLCOMPMODE           =6001 /**< @brief real compression mode 3: ADC 8: ZEDC*/
};


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

/**
 * @brief Defines a key element for index sequential access methods (VSAM-KSDS)
 */
typedef struct key_element {
   //!Key position
   /** Byte offset where the key begins (starting at 1, default 1)*/
   U32         KEYPOS;
   //!Length of the key in the record (minimum 1, default 8)
   U32         KEYLEN;
   //!Data type:
   /** <ul><li>0 = printable characters</li><li>1 = binary data</li></ul>*/
   U32         KEYTYP;
}FKE;

/**
 * @brief Key elements for index sequential data access
 *
 * Defines up to 8 key elements for index sequential data access.
 * Such access methods are only supported on mainframe systems (BSAM/VSAM).
 */
typedef struct key_description {
   //!Key flag
   /**Options:<ul><li>0 = No duplicate key (DEFAULT)</li><li>1 = Duplicate keys allowed</li></ul>*/
   U32         KEYFLG;
   //!Number of key elements
   /** The number of elements in key_description::KEYELM (normally 1 (VSAM), maximum 8 (BSAM))*/
   U32         KEYCNT;
   //!Array of key elements
   FKE         KEYELM[8];
}FKD;

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

/**
 * @brief open a FLAMFILE
 *
 * The #FLMOPN() function opens a FLAMFILE. It can be followed by a #FLMOPD()
 * and/or #FLMOPF() call, in order to set or query the attributes of the
 * FLAMFILE or the FLAM settings.
 * @param flmid Identifies the FLAMFILE for which the function is
 *        executed. It is set by the #FLMOPN() function and must not be
 *        changed until calling #FLMCLS().
 * @param rc Return code
 * @param lstpar Set to a non-zero value if you will call #FLMOPD() and/or #FLMOPF() afterwards
 * @param opmode 0=INPUT(read), 1=OUTPUT(write), 2=INOUT(read/write, Host-only)
 * @param filename Zero-terminated filename of file to open (or DD name on mainframes)
 * @param statis Indicates whether to collect statistical data that is returned on #FLMCLS() or #FLMFLU() (0=disable, other=enable)
 */
extern void FLMOPN   ( char **flmid,
                I32  *rc,
                I32  *lstpar,
                I32  *opmode,
                C08  *filename,
                I32  *statis);

/**
 * @brief set/get FLAMFILE organisation attributes
 *
 * #FLMOPD() allows to set and/or get file organistation attributes of the FLAMFILE. Use of #FLMOPD() is optional but has to be done
 * after #FLMOPN() and before #FLMOPF().
 * @param flmid Identifies the FLAMFILE for which the function is
 *        executed. It is set by the #FLMOPN() function and must not be
 *        changed until calling #FLMCLS().
 * @param rc Return code
 * @param lstpar Set to a non-zero value if you will call #FLMOPF() afterwards
 * @param namelen Pass the length of the @p filename buffer; contains the filename length after this call
 * @param filename Buffer used to output the filename of the file to be opened (on mainframes the file name allocated to the DD name)
 * @param org organisation of FLAMFILE 0,8,16=sequential(PS,ESDS) 1,9,17=index-sequential(IS,KSDS) 2,10=RRDS 3,11=LDS
 * @param recf Record format for FLAMFILE 0,8,16=variable 1,9,17=fixed(default) 2,10,18=undefined
 * @param recs maximum record length for FLAMFILE 80 - 32760, 512=default (for CX7 the maximum is 4095)
 * @param recdel Record delimiter for FLAMFILE records (only for CX7 on WIN/UNIX)
 * @param keydesc pointer to key description for the original records see #struct kd (mainframe only)
 * @param blks Blocksize for the FLAMFILE (only for mainframes) 0=unblocked or 80-32760
 * @param cldisp Close disposition (only for mainframes) 0=rewind(default) 1=unload 2=leave/retain
 * @param dev Device type 0=disc(default) 7=user defined I/O functions are used
 *        (for mainframes: 0,8,16=disc(default) 1,9,17=tape 2,10,18=floppy 3,11,19=streamer 7,15,23=user defined I/O functions are used)
 */
extern void FLMOPD   ( char **flmid,
                I32  *rc,
                I32  *lstpar,
                I32  *namelen,
                C08  *filename,
                I32  *org,
                I32  *recf,
                I32  *recs,
                U08  *recdel,
                FKD  *keydesc,
                I32  *blks,
                I32  *cldisp,
                I32  *dev);

/**
 * @brief set/get FLAMFILE attributes
 *
 * Can be used to define (when compressing) or retrieve (when decompressing)
 * the attributes of the compressed file. #FLMOPF() can be called as second
 * function after #FLMOPN(), when #FLMOPD() is not used, or as third function after #FLMOPD().
 * For encrypted FLAMFILES on mainframes the function FLMSET() must be used, other platforms
 * use bit 4 and 5 of the @p modus parameter to specify the encryption method: FLAM and AES
 * @param flmid Identifies the FLAMFILE for which the function is
 *        executed. It is set by the #FLMOPN() function and must not be
 *        changed until calling #FLMCLS().
 * @param rc Return code
 * @param version of FLAMFILE: always 2
 * @param flcode During compression, specifies the character set to use to
 *        write to the FLAMFILE. This information is returned during the
 *        decompression procedure. 0=EBCDIC, 1=ASCII(default)
 * @param modus compression method: 0=CX8 1=CX7 2=VR8 3=ADC 5=NDC
 * @param maxbuf size of matrix buffer 2048 - 262144 default=32768
 * @param header option flag for header generation/existence: 0=no 1=yes
 * @param maxrec maximum number of records in matrix: limits are 255 for CX8,CX7,VR8  and 4095 for ADC
 * @param keydesc pointer to key description for the original records see #struct kd (mainframe only)
 * @param blkmode method of matrix storage: 0=unblocked 1=blocked(default, data from more than 1 matrix might be in 1 block)
 * @param exk20 name of user exit for output of compressed data (unused / z/OS only)
 * @param exd20 name of user exit for input of compressed data (unused / z/OS only)
 */
extern void FLMOPF   ( char **flmid,
                I32  *rc,
                I32  *version,
                I32  *flcode,
                I32  *modus,
                I32  *maxbuf,
                I32  *header,
                I32  *maxrec,
                FKD  *keydesc,
                I32  *blkmode,
                U08  *exk20,
                U08  *exd20);

/* Hinweise
 * cputime Parameter: FLAM4 z/OS Doku behauptet als Einheit Millisekunden,
 *    Unix Doku Sekunden, tatsaechlich werden im Code 2 clock() Aufrufe
 *    subtrahiert => systemspezifische Zeiteinheit
 *
 * rc: FLAM4 Doku enthaelt Hinweis auf die moeglichen Return Codes
 *
 * recin/recout/bytin/bytout/etc scheinen nicht die Semantik wiederzuspiegeln
 */
/**
 * @brief flush FLAMFILE
 *
 * #FLMFLU() finalizes the compression procedure for a file
 * The remaining records in the block are compressed and the last FLAM
 * record is padded where necessary. The compressed file is not closed
 * after #FLMFLU() and the statistics counters are not reset, i.e. another
 * piece of compressed data can be appended. With Secure FLAMFILEs, a
 * member trailer is appended.
 *
 * Statistical information is returned if it has been requested at the
 * corresponding #FLMOPN() call (statis != 0).
 *
 * When compressing Secure FLAMFILEs, #FLMFLU() is permitted only after
 * #FLMPUH() or #FLMPUT(). When decompressing Secure FLAMFILEs, #FLMFLU()
 * must be preceded by either #FLMGET(), #FLMGHD(), or #FLMGUH().
 *
 * @param flmid Identifies the FLAMFILE to be flushed. It is set by the
 *      #FLMOPN() function and must not be changed until calling #FLMCLS().
 * @param rc Return code
 * @param cputime Consumed CPU time in units of time as returned by clock()
 * @param recin If #FLMOPN() was called with @p statis != 0, this argument
 *      returns the number of decompressed records which have been
 *      processed by #FLMPUT() or #FLMGET(). The accumulated values of
 *      this counter are only significant if complete files are processed.
 * @param bytin If #FLMOPN() was called with @p statis != 0, this argument
 *      returns the number of bytes of the decompressed records which
 *      have been transferred with #FLMPUT() or #FLMGET(). The accumulated
 *      value of this counter is only significant if complete files are
 *      processed.
 * @param bytoflin If the accumulated value of the @p bytin argument exceeds
 *      2,000,000,000, this counter is used for multiples of 2,000,000,000.
 * @param recout If #FLMOPN() was called with @p statis != 0, this argument
 *      returns the number of compressed records which were created during
 *      the compression procedure or read during the decompression procedure.
 *      This value is only significant if complete files are processed.
 * @param bytout If #FLMOPN() was called with @p statis != 0, this argument
 *      returns the number of bytes which were created during the
 *      compression procedure or read during the decompression procedure.
 *      This value is only significant if complete files are processed.
 * @param bytoflout If the accumulated value of the @p bytout argument exceeds
 *      2,000,000,000, this counter is used for multiples of 2,000,000,000.
 */
extern void FLMFLU   ( char **flmid,
                I32  *rc,
                U32  *cputime,
                U32  *recin,
                U32  *bytin,
                U32  *bytoflin,
                U32  *recout,
                U32  *bytout,
                U32  *bytoflout);

/**
 * @brief End member in a FLAMFILE (only z/OS)
 *
 * The function FLMEME finishes the current data as member of a
 * Group-FLAMFILE (end member). Duringcompression, the content of
 * the matrix is compressed and written immediately, enlarged with
 * some security information, if required (SECUREINFO=YES); during
 * decompression, the next matrix is decompressed.On AES encryption,
 * a member MAC is created and written. The MAC is returned. On AES
 * decryption, the member MAC is returned. Statistical values are
 * returned. To end only a matrix and not the entire member, function
 * #FLMFLU() is provided
 *
 * @param flmid Identifies the FLAMFILE to be flushed. It is set by the
 *      #flmopn() function and must not be changed until calling #flmcls().
 * @param rc Return code
 * @param cputime Consumed CPU time in units of time as returned by clock()
 * @param recin If #flmopn() was called with @p statis != 0, this argument
 *      returns the number of decompressed records which have been
 *      processed by #flmput() or #flmget(). The accumulated values of
 *      this counter are only significant if complete files are processed.
 * @param bytin If #flmopn() was called with @p statis != 0, this argument
 *      returns the number of bytes of the decompressed records which
 *      have been transferred with #flmput() or #flmget(). The accumulated
 *      value of this counter is only significant if complete files are
 *      processed.
 * @param bytoflin If the accumulated value of the @p bytin argument exceeds
 *      2,000,000,000, this counter is used for multiples of 2,000,000,000.
 * @param recout If #flmopn() was called with @p statis != 0, this argument
 *      returns the number of compressed records which were created during
 *      the compression procedure or read during the decompression procedure.
 *      This value is only significant if complete files are processed.
 * @param bytout If #flmopn() was called with @p statis != 0, this argument
 *      returns the number of bytes which were created during the
 *      compression procedure or read during the decompression procedure.
 *      This value is only significant if complete files are processed.
 * @param bytoflout If the accumulated value of the @p bytout argument exceeds
 *      2,000,000,000, this counter is used for multiples of 2,000,000,000.
 * @param mac pointer to a 8 byte field whre the member mac is returned.
 */
extern void FLMEME   ( char **flmid,
                I32  *rc,
                U32  *cputime,
                U32  *recin,
                U32  *bytin,
                U32  *bytoflin,
                U32  *recout,
                U32  *bytout,
                U32  *bytoflout,
                U08  *membermac);

/**
 * @brief Delete last record (only z/OS)
 *
 * With function FLMDEL it is possible to delete the last
 * read original record from an index sequential FLAMFILE.
 *
 * @param [in]    flmid    POINTER  Identification
 * @param [out]   rc       INTEGER  Return code
 */
extern void FLMDEL(
   C08**       flmid,
   I32*        rc);

/**
 * @brief Find record using a key (only z/OS)
 *
 * The function FLMFKY (Find Key) can be used to search in
 * an index sequential FLAMFILE for a record of the original
 * file, whose key is equal to or greater than a specified key
 * value. The specified value can be generic, i.e. not all of
 * the positions of the key value have to be specified
 * uniquely. The record found is the next record to be
 * processed. If FLMFKY does not find a record, the old
 * position is retained.
 *
 * @param [in]    flmid    POINTER  Identification
 * @param [out]   rc       INTEGER  Return code
 * @param [in]    keylen   INTEGER  Key length
 *                                  This contains the number of significant bytes in the
 *                                  specified key value. It can be less than the key length.
 *                                  In this case, only the length passed here is taken into
 *                                  account in the logical relation specified in the argument
 *                                  checkmod.
 * @param [in]    record   STRING   Record buffer with search key
 * @param [in]    checkmod INTEGER  Type of relation (0 - equal, 1 - greater than or equal, 2 - greater than)
 */
extern void FLMFKY(
   C08**       flmid,
   I32*        rc,
   I32*        keylen,
   U08*        record,
   I32*        checkmod);

/**
 * @brief Find record number (only z/OS)
 *
 * The function FLMFRN (Find Record Number) positions
 * the record pointer to a record with a specified number
 * in an index sequential FLAMFILE. This number corresponds
 * to the record number of the sequential or relative original
 * file. The record is the next record to be processed.
 * Specifying checkmod=1 or 2 allows gaps and empty records
 * to be skipped. If FLMFRN does not find a record, the old
 * position isretained.
 *
 * @param [in]    flmid    POINTER  Identification
 * @param [out]   rc       INTEGER  Return code
 * @param [inout] recno    INTEGER  Record number (1 - File start. With checkmod=1,2 the true record number is returned)
 * @param [out]   checkmod INTEGER  Type of relation (0 - Record with specified number, 1 - Record with specified number, skip gaps and empty records, 2 - Record with next number, skip gaps and empty records)
 */
extern void FLMFRN(
   C08**       flmid,
   I32*        rc,
   I32*        recno,
   I32*        checkmod);

/**
 * @brief Get record addressed by key (only z/OS)
 *
 * The user can obtain an original record from an index
 * sequential FLAMFILE via a key by using the function
 * FLMGKY. The search key must be placed at the key
 * position within the record area.
 *
 * @param [in]    flmid    POINTER  Identification
 * @param [out]   rc       INTEGER  Return code
 * @param [out]   reclen   INTEGER  Length of passed record in bytes
 * @param [out]   record   STRING   Original record (Data with key)
 * @param [in]    buflen   INTEGER  Length of available record buffer in byte
 */
extern void FLMGKY(
   C08**       flmid,
   I32*        rc,
   I32*        reclen,
   U08*        record,
   I32*        buflen);

/**
 * @brief Get record by number (only z/OS)
 *
 * The function FLMGRN (Get Record Number) reads the original
 * record of a sequential or relative file from an index sequential
 * FLAMFILE as specified by the record number. If FLMGRN does not
 * find a valid record, the new position moved to is the next record
 * or the end of the file.
 *
 * @param [in]    flmid    POINTER  Identification
 * @param [out]   rc       INTEGER  Return code
 * @param [out]   reclen   INTEGER  Record length in bytes of the passed record
 * @param [out]   record   STRING   Original record (data)
 * @param [in]    buflen   INTEGER  Length of available record buffer in bytes
 * @param [in]    recno    INTEGER  Record number (1 - file start)
 *
 * With return codes 2, 6 and 7 no record is passed.
 * With return code 3 a record of length =0 is passed.
 */
extern void FLMGRN(
   C08**       flmid,
   I32*        rc,
   I32*        reclen,
   U08*        record,
   I32*        buflen,
   I32*        recno);

/**
 * @brief Get previous record (only z/OS)
 *
 * With function FLMGTR (Get reverse) the previous original
 * record is read in sequential order. It is possible to position
 * to a certain record in the compressed file using FLMGKY or FLMPOS
 * and then to read backward sequentially. Data is transferred from
 * the record buffer to the calling program (MOVE mode).
 *
 * @param [in]    flmid    POINTER  Identification
 * @param [out]   rc       INTEGER  Return code
 * @param [out]   reclen   INTEGER  Record length in bytes of the passed record
 * @param [out]   record   STRING   Original record (data)
 * @param [in]    buflen   INTEGER  Length of available record buffer in bytes
 *
 * With return codes 2 and 6 no record is passed.
 * With return code 3 a record of length 0 is passed.
 */
extern void FLMGTR(
   C08**       flmid,
   I32*        rc,
   I32*        reclen,
   U08*        record,
   I32*        buflen);

/**
 * @brief Insert record with key (only z/OS)
 *
 * The function FLMIKY allows to insert records with a key to
 * an index sequential FLAMFILE (VSAM-KSDS).
 *
 * @param [in]    flmid    POINTER  Identification
 * @param [out]   rc       INTEGER  Return code
 * @param [in]    reclen   INTEGER  Record length (data length) in bytes without record length field
 * @param [in]    record   STRING   Original record (data with key)
 */
extern void FLMIKY(
   C08**       flmid,
   I32*        rc,
   I32*        reclen,
   U08*        record);

/**
 * @brief Locate previous record (only z/OS)
 *
 * The function FLMLCR is equivalent to FLMGTR (Get reverse).
 * The data will not be transmitted but only a pointer on
 * the record is provided (locate Mode).
 *
 * @param [in]    flmid    POINTER  Identification
 * @param [out]   rc       INTEGER  Return code
 * @param [out]   reclen   INTEGER  Record length in bytes of the passed record
 * @param [out]   recptr   POINTER  Record address (data address)
 *
 * With return codes 2 and 6 no record address is passed.
 * With return code 3 the length 0 is passed.
 */
extern void FLMLCR(
   C08**       flmid,
   I32*        rc,
   I32*        reclen,
   U08**       recptr);

/**
 * @brief Put record by key (only z/OS)
 *
 * The function FLMPKY allows to insert records into an
 * index sequential FLAMFILE or to update records within
 * such a file via a key.
 *
 * @param [in]    flmid    POINTER  Identification
 * @param [out]   rc       INTEGER  Return code
 * @param [in]    reclen   INTEGER  Record length (data length) in bytes without record length field (exclusive length)
 * @param [in]    record   STRING   Original record (Data with key)
 */
extern void FLMPKY(
   C08**       flmid,
   I32*        rc,
   I32*        reclen,
   U08*        record);

/**
 * @brief Update record (only z/OS)
 *
 * The function FLMUPD updates the original record last
 * read from a VSAM-KSDS FLAMFILE.
 *
 * @param [in]    flmid    POINTER  Identification
 * @param [out]   rc       INTEGER  Return code
 * @param [in]    reclen   INTEGER  Record length (data length) in bytes without record lengthfield
 * @param [in]    record   STRING   Original record (data)
 */
extern void FLMUPD(
   C08**       flmid,
   I32*        rc,
   I32*        reclen,
   U08*        record);


/* Hinweise
 * cputime Parameter: FLAM4 z/OS Doku behauptet als Einheit Millisekunden,
 *    Unix Doku Sekunden, tatsaechlich werden im Code 2 clock() Aufrufe
 *    subtrahiert => systemspezifische Zeiteinheit
 *
 * rc: FLAM4 Doku enthaelt Hinweis auf die moeglichen Return Codes
 *
 * recin/recout/bytin/bytout/etc scheinen nicht die Semantik wiederzuspiegeln
 */
/**
 * @brief close FLAMFILE
 *
 * The #FLMCLS() function finalizes the record interface.
 *
 * If compression is closed, the last matrix is compressed and the
 * compressed data is written to the FLAMFILE. Additional information
 * (byte-, record counter, MACs) are stored as an 'ending record', if
 * required (SECUREINFO=YES). Then the FLAMFILE is closed.
 *
 * When decompression is closed, only the FLAMFILE is closed. Additional
 * records not yet read from the FLAMFILE are discarded.
 *
 * Statistical information is returned if it has been requested at the
 * corresponding #FLMOPN() call (statis != 0).
 *
 * With Secure FLAMFILEs, #FLMCLS() may only be invoked immediately after
 * #FLMFLU() or #FLMPOS().
 * @param flmid Identifies the FLAMFILE to be closed. It is set by the
 *      #FLMOPN() function and must not be changed until calling #FLMCLS().
 * @param rc Return code
 * @param cputime Consumed CPU time in units of time as returned by clock()
 * @param recin If #FLMOPN() was called with @p statis != 0, this argument
 *      returns the number of decompressed records which have been
 *      processed by #FLMPUT() or #FLMGET(). The accumulated values of
 *      this counter are only significant if complete files are processed.
 * @param bytin If #FLMOPN() was called with @p statis != 0, this argument
 *      returns the number of bytes of the decompressed records which
 *      have been transferred with #FLMPUT() or #FLMGET(). The accumulated
 *      value of this counter is only significant if complete files are
 *      processed.
 * @param bytoflin If the accumulated value of the @p bytin argument exceeds
 *      2,000,000,000, this counter is used for multiples of 2,000,000,000.
 * @param recout If #FLMOPN() was called with @p statis != 0, this argument
 *      returns the number of compressed records which were created during
 *      the compression procedure or read during the decompression procedure.
 *      This value is only significant if complete files are processed.
 * @param bytout If #FLMOPN() was called with @p statis != 0, this argument
 *      returns the number of bytes which were created during the
 *      compression procedure or read during the decompression procedure.
 *      This value is only significant if complete files are processed.
 * @param bytoflout If the accumulated value of the @p bytout argument exceeds
 *      2,000,000,000, this counter is used for multiples of 2,000,000,000.
 */
extern void FLMCLS   ( char **flmid,
                I32  *rc,
                U32  *cputime,
                U32  *recin,
                U32  *bytin,
                U32  *bytoflin,
                U32  *recout,
                U32  *bytout,
                U32  *bytoflout);


/*
 * Unix-Manual enthaelt recf Werte, die es nicht zu geben scheint:
 * 32 var_4b, 40 var_ascii, 48 var_ebcdic
 * recdel ist laut Unix-Manual ein 4 Byte Integer
 * keydesc, blks und prnctr sind im Unix-Manual "reserved"
 * Menge der moeglichen Werte fuer system fehlt, da in jedem Manual+Code unterschiedlich
 */
/**
 * @brief get file header
 *
 * #FLMGHD() allows retrieving the file attributes of the
 * original file during decompression if they were stored in the
 * FLAMFILE during compression. If the FLAMFILE contains several file
 * headers (see #FLMPHD()), the last file header found by FLAM is returned.
 *
 * The first file header is usually available immediately after #FLMOPN()
 * (see #FLMOPF() header=1). When FLAM recognizes additional file headers,
 * it will inform the user via the return code (RETCO=6) of #FLMGET() or
 * #FLMLOC().
 * @param flmid Identifies the FLAMFILE for which the function is
 *        executed. It is set by the #FLMOPN() function and must not be
 *        changed until calling #FLMCLS().
 * @param rc Return code
 * @param namelen Pass the length of the @p filename buffer in which the name
 *        of the original file will be returned. Is set to the actual
 *        length when function returns.
 * @param filename Buffer area in which to store the original filename.
 *        If the buffer is too small, the filename will be truncated to
 *        the length of the buffer.
 * @param org returns a value for the organization of the original file.
 *        Possible values (not all are supported on Unix): 0=sequential,
 *        1=index-sequential, 2=relative, 3=direct access, 4=no record
 *        structure, 5=library 6=physical
 * @param recf returns a value for the record format of the original file.
 *        Possible values (not all are supported on Unix):
 *        0/8/16/24 = variable / blocked / blocked/spanned / VFC;
 *        1/9/17 = fix / blocked / blocked/Standard;
 *        2/10/18 = undefined / / EAF;
 *        3/11/19 = stream / text delimiter / length fields
 * @param recs This argument returns the record size of the original file.
 *        For variable record sizes and the stream record format, the value is 0.
 * @param recdel This argument specifies the record delimiter for the stream record format.
 * @param keydesc Key description  (mainframe only)
 * @param blks Block length of original file (0=unblocked)
 * @param prnctr Printer control characters (0=none, 1=ASA, 2=Machine specific)
 * @param system This argument consists of two bytes and is used to return a
 *        code for the operating system in which the FLAMFILE was created.
 */
extern void FLMGHD   ( char **flmid,
                I32  *rc,
                I32  *namelen,
                C08  *filename,
                I32  *org,
                I32  *recf,
                I32  *recs,
                U08  *recdel,
                FKD  *keydesc,
                I32  *blks,
                I32  *prnctr,
                C08  *system);

/*
 * recdel ist laut Unix-Manual ein 4 Byte Integer, wird in cmpphd.c gar nicht benutzt
 * keydesc, blks und prnctr sind im Unix-Manual "reserved"
 */
/**
 * @brief put file  header
 *
 * The #FLMPHD() function is only allowed during
 * compression and if header=1 was set with #FLMOPF(). It generates a
 * common file header, which describes the file format of the original
 * records that are transferred subsequently. If several different files
 * are compressed into a single FLAMFILE, a separate file header can be
 * generated for each file with the #FLMPHD() function. FLAM returns this
 * file header information during the decompression procedure if it has
 * been requested to do so (#FLMGHD()).
 *
 * Calls to #FLMPHD() with @p continue_param!=0 or after #FLMPWD() must be
 * followed immediately by #FLMPUH().
 *
 * Using SECUREINFO=YES, function #FLMPHD() is mandatory!
 *
 * Note: The parameter in #FLMPHD() also controls the construction of an
 * index-sequential FLAMFILE. On DSORG=0 (sequential data), a record
 * number is created and used as a record key; on DSORG=1 (index-sequential)
 * the original key is used.
 * @param flmid Identifies the FLAMFILE for which the function is
 *        executed. It is set by the #FLMOPN() function and must not be
 *        changed until calling #FLMCLS().
 * @param rc Return code
 * @param namelen Length of the @p filename
 * @param filename Buffer containing the original filename
 * @param org Code for the organization of the original file. For permissible values, see the #FLMGHD() function.
 * @param recf Code for the record format of the original file. For permissible values, see the #FLMGHD() function.
 * @param recs The maximum record size of the original file
 * @param recdel Record delimiter
 * @param keydesc Key description (only for mainframes)
 * @param blks Block length of original file (0=unblocked)
 * @param prnctr Printer control characters (0=none, 1=ASA, 2=Machine specific)
 * @param system This argument consists of two bytes and is used to return a code
 *        for the operating system in which the FLAMFILE was created. For a list of valid values, see #FLMGHD().
 * @param cont Indicates whether a call to #FLMPUH() will follow (0=no, 1=yes)
 */
extern void FLMPHD   ( char **flmid,
                I32  *rc,
                I32  *namelen,
                C08  *filename,
                I32  *org,
                I32  *recf,
                I32  *recs,
                U08  *recdel,
                FKD  *keydesc,
                I32  *blks,
                I32  *prnctr,
                C08  *system,
                I32  *cont);

/**
 * @brief get user header
 *
 * Retrieves the data from the user-specific FLAM file header. Calling
 * this function is only allowed during decompression and immediately
 * following an #FLMGHD() call.
 *
 * @param flmid Identifies the FLAMFILE for which the function is
 *        executed. It is set by the #FLMOPN() function and must not be
 *        changed until calling #FLMCLS().
 * @param rc Return code
 * @param hdrlen Pass the length of the buffer in which the user-specific
 *        file header will be returned. Is set to the actual length when function returns.
 * @param header Buffer to write the user-specific file header data to
 */
extern void FLMGUH   ( char **flmid,
                I32  *rc,
                I32  *hdrlen,
                C08  *header);

/**
 * @brief put user header
 *
 * The FLMPUH() function adds a user-specific header with
 * information of arbitrary structure to the FLAMFILE. This information
 * is added in binary form and can be retrieved during decompression with
 * #FLMGUH() (the complementary function).
 *
 * Calling this function is only allowed during compression and immediately
 * following an #FLMPHD() call.
 *
 * @param flmid Identifies the FLAMFILE for which the function is
 *        executed. It is set by the #FLMOPN() function and must not be
 *        changed until calling #FLMCLS().
 * @param rc Return code
 * @param hdrlen Length of the user-specific @p header data (max. 3500 (Host, 8-bit), 1750 (Host, 7-bit, CX7), 32732 bytes (other))
 * @param header User-specific header data
 */
extern void FLMPUH   ( char **flmid,
                I32  *rc,
                I32  *hdrlen,
                C08  *header);

/**
 * @brief Sets a password for encryption/decryption while compressing/decompressing
 *
 * It is the first call after the last FLMOPx function during encryption.
 *
 * The encryption mode is set by the function #FLMSET(). On decryption,
 * the information is read from the FLAMFILE and can be obtained by calling #FLMQRY().
 *
 * @param flmid Identifies the FLAMFILE for which the function is
 *        executed. It is set by the #FLMOPN() function and must not be
 *        changed until calling #FLMCLS().
 * @param rc Return code
 * @param pwdlen The password's length in characters
 * @param passwd The password string
 */
extern void FLMPWD   ( char **flmid,
                I32  *rc,
                U32  *pwdlen,
                C08  *passwd);


/**
 * @brief load and use FKME
 *
 * Works like SETPWD but use FKME parameters. It dynamically loads the
 * FKME module, runs the function code INFO, if @p inflen provided and
 * execute function code COMP or DECO with the provided values.
 *
 * @param flmid Identifies the FLAMFILE for which the function is
 *        executed. It is set by the #FLMOPN() function and must not be
 *        changed until calling #FLMCLS().
 * @param rc Return code
 * @param kmclen   length of key management context
 * @param kmc      pointer to key mangement context
 * @param liblen   length of the library name (not relevant on z/OS)
 * @param lib      pointer to the library name
 * @param fuclen   length of the function name
 * @param fuc      pointer to the function name (for dynamic load)
 * @param parlen   length of the parameter string
 * @param par      pointer to the paramter string
 * @param msglen   size/length of return message
 * @param msg      point to the return message
 * @param inflen   size/length of return info string (could be 0 to prevent call of function code INFO)
 * @param inf      point to the info string
 */
extern void FLMKME   ( char      **flmid,
                I32        *rc,
                U32        *kmclen,
                U08        *kmc,
                const U32  *liblen,
                const C08  *lib,
                const U32  *fuclen,
                const C08  *fuc,
                const U32  *parlen,
                const C08  *par,
                U32        *msglen,
                C08        *msg,
                U32        *inflen,
                C08        *inf);

/**
 * @brief set read position
 *
 * With #FLMPOS() the read position can be changed. The @p pos parameter is used as follows:
 *
 * On mainframes:
 *        -MAXINT -> Start of file
 *        +MAXINT -> End of file
 *        -99999999 -> Start of file for Cobol
 *        +99999999 -> End of file for Cobol
 *        -99999998 -> Start of previous file in a group file
 *        +99999998 -> Start of next file in a group file
 *        -N        -> N records backward
 *        +N        -> N records forward
 *
 * otherwise only one relative position is supported:
 *        +99999998 -> Start of next file in a group file
 *
 * @param flmid Identifies the FLAMFILE for which the function is
 *        executed. It is set by the #FLMOPN() function and must not be
 *        changed until calling #FLMCLS().
 * @param rc Return code
 * @param pos new position to use on next read
 */
extern void FLMPOS   ( char **flmid,
                I32  *rc,
                I32  *pos);

/**
 * @brief get next record
 *
 * #FLMGET() reads the next original record sequentially. The
 * data is transferred to the supplied @p record buffer. A special return
 * code indicates when a new file header is encountered.
 *
 * It is possible to position to a certain record in the compressed file
 * using #FLMPOS() and then to continue with sequential reading.
 *
 * #FLMGET() may only be used at decompression. With encrypted FLAMFILEs,
 * a password must be provided via #FLMPWD() before the first invocation
 * of #FLMGET().
 * @param flmid Identifies the FLAMFILE for which the function is
 *        executed. It is set by the #FLMOPN() function and must not be
 *        changed until calling #FLMCLS().
 * @param rc Return code
 * @param reclength Returns the length in bytes of the @p record which has been read
 * @param record Record buffer used to put record data into
 * @param buflength Length of the @p record buffer in bytes
 */
extern void FLMGET   ( char **flmid,
                I32  *rc,
                I32  *reclength,
                U08  *record,
                I32  *buflength);

/**
 * @brief locate record
 *
 * The function #FLMLOC() is equivalent to #FLMGET(), except that it does
 * not put a read record into a supplied buffer. Instead, a pointer to
 * the record is returned (LOCATE mode).
 * @param flmid Identifies the FLAMFILE for which the function is
 *        executed. It is set by the #FLMOPN() function and must not be
 *        changed until calling #FLMCLS().
 * @param rc Return code
 * @param reclength Length of the record pointed to by @p record
 * @param record Contains pointer to the read record after call
 */
extern void FLMLOC   ( char **flmid,
                I32  *rc,
                I32  *reclength,
                U08  **record);

/**
 * @brief put record
 *
 * The FLMPUT function compresses one original record at a time.
 *
 * @param flmid Identifies the FLAMFILE for which the function is
 *        executed. It is set by the #FLMOPN() function and must not be
 *        changed until calling #FLMCLS().
 * @param rc Return code
 * @param reclength Record length in bytes
 * @param record Buffer containing the buffer
 */
extern void FLMPUT   ( char **flmid,
                I32  *rc,
                I32  *reclength,
                U08  *record );

/**
 * @brief provides an error message
 *
 * With #FLMERR() a return code can be translated into a talking error message.
 *
 * @param rc Return code
 * @param msglen at input space for the error message, at output length of the error message
 * @param errmsg pointer to the error message buffer
 */
extern void FLMERR    ( I32  *rc,
                 I32  *msglen,
                 const C08 **errmsg);

/**
 * @brief query extended FLAMFILE attributes
 *
 * With #FLMQRY() parameters can be obtained during decompression.
 * It may be called at any time after #FLMOPN(), but the results depend
 * on the moment it is called. E.g. SPLIT.. are first known after #FLMOPD(),
 * CRYPTOMODE after #FLMOPF().
 *
 * Note: In opposite to the other function calls the return code
 * @p rc was expanded into two words (2 x 4 byte). The
 * first word is still the return code, the second word is the
 * info code. The info code is the parameter in error on return.
 *
 * @see #FLMSET() and #flmset_parameter
 *
 * @param flmid Identifies the FLAMFILE for which the function is
 *        executed. It is set by the #FLMOPN() function and must not be
 *        changed until calling #FLMCLS().
 * @param rc Return code
 * @param parameter identifies the extended parameter to query
 * @param value will contain the value of the specified @p parameter after return
 */
extern void FLMQRY( char **flmid, I32  *rc, I32* parameter, void* value);
/**
 * @brief set extended FLAMFILE attributes
 *
 * #FLMSET() sets parameter that open functions do not support.
 * It must be called before #FLMOPD() and/or #FLMOPF(). A later call will
 * fail with return code 90.
 *
 * Note: In opposite to the other function calls the return code
 * @p rc was expanded into two words (2 x 4 byte). The
 * first word is still the return code, the second word is the
 * info code. The info code is the parameter in error on return.
 *
 * Besides #FLMSET_CRYPTOMODE Extended attributes are only meaningful on
 * the mainframe.
 * #FLMSET_CRYPTOMODE is used to set the encryption mode when writing a FLAMFILE
 * @see #FLMQRY() and #flmset_parameter
 *
 * @param flmid Identifies the FLAMFILE for which the function is
 *        executed. It is set by the #FLMOPN() function and must not be
 *        changed until calling #FLMCLS().
 * @param rc Return code
 * @param parameter identifies the extended parameter to set
 * @param value will be used to set the specified @p parameter
 */
extern void FLMSET( char **flmid, I32  *rc, I32* parameter, void* value);

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

#endif /* INC_FL4RECUC_H */

#ifdef __cplusplus
   }
#endif

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