Skip to content

MDRFrame Copybook

These are the MDRFRAME framework functions available for usage in Provider and Consumer Programs.

Some procedures are specific to REST Consumers ( e.g MDR_request) or REST Providers (e.g. MDR_getPathVar), and some procedures can be used in both (e.g. MDR_jsonPathV).

Note

YAJL functions have been wrappered in MDRest4i - with some enhancements. The copybook for these YAJL functions in MDRest4i is included by default in the MDRFRAME copybook. The copybook content, can be found in MDRST/MDRYAJLR4

Contents

Program Compilation
Provider or Consumer Functions
Provider Only Functions
Consumer Only Functions
JSON Functions
Attachment Functions
IFS Functions
Advanced Consumer Functions

Program Compilation

Midrange Dynamics recommends that you compile your program with ACTGRP(CALLER) when creating a PROVIDER. CONSUMERS should use either NEW or a NAMED activation group.

If you need the MDREST4i Framework to run in a specific activation group you can accomplish this by running the following commands:

UPDPGM PGM(lib/MDRAPI) MODULE(NONE) ACTGRP(your-actgrp) UPDSRVPGM PGM(lib/MDRFRAME) MODULE(NONE) ACTGRP(your-actgrp)

This causes the MDRest4i API controller (MDRAPI) and the MDRest4i framework (MDRFRAME) to run in an activation group named your-actgrp. After this, when your program uses ACTGRP(*CALLER), it will also run in that actgrp.

It is important that MDRAPI and MDRFRAME always have the same named activation group.

MDRST/MDRFRAME copybook header

mdrframe_copybook.md
      /include mdryajlr4
      /if defined(MDRFRAME_H)
      /eof
      /endif
      /define MDRFRAME_H

Provider or Consumer Functions

MDR_Handle_t

        ///===============================================================================
        // MDR_Handle_t
        // Since MDRest4i supports high-speed,
        // multi-threaded operation, a handle is needed
        // to tell the framework which session is running
        // in which execution thread.
        // When your RPG program is called by the MDRest4i controller,
        // the first parameter passed to your program is always the
        // handle.
        //
        // Each time you call an MDRest4i subprocedure, you must provide
        // the same handle.
        ///===============================================================================

        dcl-s MDR_Handle_t char(128) template;

MDR_setHeader

        ///===============================================================================
        // MDR_setHeader
        //
        // Set an HTTP header to be sent as output.
        //
        // NOTE: This may be used with either an API provider or an
        //       API consumer, depdending on the way the handle is created
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //   @param (input) header = name of the header to set
        //   @param (input) value = value of the header to set
        //
        // Example:
        //
        //  MDR_setHeader( handle
        //               : 'content-type':
        //               : 'application/octet-stream');
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_setHeader extproc(*cwiden: 'MDR_C_setHeader');
          handle          like(MDR_handle_t);
          header          pointer value options(*string);
          value           pointer value options(*string);
        end-pr;

MDR_setCookie

        ///===============================================================================
        // MDR_setCookie
        //
        // Set an HTTP cookie to be set during output
        //
        // NOTE: This may be used with either an API provider or an
        //       API consumer, depdending on the way the handle is
        //       created.
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //   @param (input) cookie = name of the cookie to set
        //
        //   @param (input) value = value of the cookie to set
        //
        // Example:
        //  SESSION_ID = '12345';
        //  MDR_setCookie(handle: 'SessionId': SESSION_ID);
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_setCookie extproc(*cwiden: 'MDR_C_setCookie');
          handle          like(MDR_handle_t);
          cookie          pointer value options(*string);
          value           pointer value options(*string);
        end-pr;

MDR_getHeader

        ///===============================================================================
        // MDR_getHeader
        //
        // Retrieves the value of an HTTP header on input.
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //   @param (input) name = name of HTTP header to retrieve
        //
        //   @return the value of the header.
        //           or '*NOTFOUND' if you specify a header that does not exist
        //
        // Example:
        //   agent = MDR_getHeader(handle: 'user-agent');
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_getHeader varchar(2048)
                             rtnparm
                             extproc(*cwiden:'MDR_RPG_getHeader');
          handle          like(MDR_handle_t);
          name            varchar(200) const;
        end-pr;

MDR_getOutgoingHeader

        ///===============================================================================
        // MDR_getOutgoingHeader
        //
        // Retrieves the value of an HTTP header in the response to an HTTP request.
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //   @param (input) name = name of HTTP header to retrieve
        //
        //   @return the value of the header.
        //           or '*NOTFOUND' if you specify a header that does not exist
        //
        // Example:
        //   agent = MDR_getOutgoingHeader(handle: 'user-agent');
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_getOutgoingHeader varchar(2048)
                                     rtnparm
                                     extproc(*cwiden
                                            :'MDR_RPG_getOutgoingHeader');
          handle          like(MDR_handle_t);
          name            varchar(200) const;
        end-pr;

MDR_getCookie

        ///===============================================================================
        // MDR_getCookie
        //
        // Retrieves the value of an HTTP cookie on input.
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //   @param (input)  name = name of HTTP cookie to retrieve
        //
        //   @return the value of the cookie
        //           or '*NOTFOUND' if you specify a cookie that does not exist
        //
        // Example:
        //   session = MDR_getCookie(handle: 'SessionId');
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_getCookie varchar(2048)
                             rtnparm
                             extproc(*cwiden:'MDR_RPG_getCookie');
          handle          like(MDR_handle_t);
          name            varchar(200) const;
        end-pr;

MDR_getOutgoingCookie

        ///===============================================================================
        // MDR_getOutgoingCookie
        //
        // Retrieves the value of an HTTP cookie in the response to an HTTP request
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //   @param (input) name = name of HTTP cookie to retrieve
        //
        //   @return the value of the cookie
        //           or '*NOTFOUND' if you specify a cookie that does not exist
        //
        // Example:
        //   session = MDR_getOutgoingCookie(handle: 'SessionId');
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_getOutgoingCookie varchar(2048)
                                     rtnparm
                                     extproc(*cwiden
                                            :'MDR_RPG_getOutgoingCookie');
          handle          like(MDR_handle_t);
          name            varchar(200) const;
        end-pr;

MDR_getHeaderCount

        ///===============================================================================
        // MDR_getHeaderCount
        //
        // Returns the number of headers in the current request
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //
        //   @return the number of headers in current http request
        //
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_getHeaderCount packed(7: 0) extproc('MDR_getHeaderCount');
          handle like(MDR_handle_t);
        end-pr;

MDR_getCookieCount

        ///===============================================================================
        // MDR_getCookieCount
        //
        // Returns the number of cookies in the current request
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //
        //   @return the number of cookies in current http request
        //
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_getCookieCount packed(7: 0) extproc('MDR_getCookieCount');
          handle like(MDR_handle_t);
        end-pr;

MDR_getOutgoingHeaderCount

        ///===============================================================================
        // MDR_getOutgoingHeaderCount
        //
        // Returns the number of headers in the current response
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //
        //   @return the number of headers being returned in current http response
        //
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_getOutgoingHeaderCount packed(7: 0)
          extproc('MDR_getOutgoingHeaderCount');
          handle like(MDR_handle_t);
        end-pr;

MDR_getOutgoingCookieCount

        ///===============================================================================
        // MDR_getOutgoingCookieCount
        //
        // Returns the number of cookies in the current response
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //
        //   @return the number of cookies being returned in current http response
        //
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_getOutgoingCookieCount packed(7: 0)
          extproc('MDR_getOutgoingCookieCount');
          handle like(MDR_handle_t);
        end-pr;

MDR_getHeaderName

        ///===============================================================================
        // MDR_getHeaderName
        //
        // Returns the name of a header based on its ordinal position in the headers array
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //   @param (input) pos = array position to retrieve
        //
        //   @eturn the name of the header, or *NOTFOUND
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_getHeaderName char(200) extproc('MDR_getHeaderName');
          handle like(MDR_handle_t);
          pos    packed(7: 0) const;
        end-pr;

MDR_getQueryVarName

        ///===============================================================================
        // MDR_getQueryVarName
        //
        // Returns the name of a query string variable based on its ordinal position
        // in the query string array
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //   @param (input) pos = array position to retrieve
        //
        //   @return the name of the query string variable, or *NOTFOUND
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_getQueryVarName char(200) extproc('MDR_getQueryVarName');
          handle like(MDR_handle_t);
          pos    packed(7: 0) const;
        end-pr;

MDR_getCookieName

        ///===============================================================================
        // MDR_getCookieName
        //
        // Returns the name of a cookie based on its ordinal position in the cookies array
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //   @param (input) pos = array position to retrieve
        //
        //   @return the name of the cookie, or *NOTFOUND
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_getCookieName char(200) extproc('MDR_getCookieName');
          handle like(MDR_handle_t);
          pos    packed(7: 0) const;
        end-pr;

MDR_getOutgoingHeaderName

        ///===============================================================================
        // MDR_getOutgoingHeaderName
        //
        // Returns the name of a header in the current response based on its
        // ordinal position in the array
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //   @param (input) pos = array position to retrieve
        //
        //   @return the name of the header, or *NOTFOUND
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_getOutgoingHeaderName char(200)
          extproc('MDR_getOutgoingHeaderName');
          handle like(MDR_handle_t);
          pos    packed(7: 0) const;
        end-pr;

MDR_getOutgoingCookieName

        ///===============================================================================
        // MDR_getOutgoingCookieName
        //
        // Returns the name of a cookie in the current response based on its
        // ordinal position in the array
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //   @param (input) pos = array position to retrieve
        //
        //   @return the name of the cookie, or *NOTFOUND
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_getOutgoingCookieName char(200)
          extproc('MDR_getOutgoingCookieName');
          handle like(MDR_handle_t);
          pos    packed(7: 0) const;
        end-pr;

        ///=======================================================================================
        // MDR_locationInfo
        //
        // Provides root IFS folder and IFS folder to use. In SRVPGM MDRTOOLS
        //   @param (output) library: MDREST4I Library (MDRST....)
        //   @param (output) rootIFSPath: MDREST4I root IFS path
        //   @param (output) instFolder: instance folder name (default, T14, ...)
        ///=======================================================================================
        Dcl-Pr MDR_locationInfo ExtPgm('MRLOCINF');
          library       char(10);
          rootIFSPath   char(20);
          instFolder    char(7);
        end-pr;

MDR_chkObj

        ///===============================================================================
        // MDR_chkObj
        //
        // Check for a disk object (similar to CHKOBJ CL cmd)
        //
        //  @param (input) library = library to look in (or *LIBL, *CURLIB)
        //  @param (input) object  = name of object
        //  @param (input) type    = object type (*PGM, *FILE etc)
        //  @param (input) rtnLib  = Returns the library where the object was found
        //                 (pass *OMIT if you don't need this)
        //
        //  @return 0 if object not found, 1 if it was found
        // @info MDRFRAME5
        ///===============================================================================

        dcl-pr MDR_chkObj int(10) extproc(*cwiden:'MDR_chkObj');
          library pointer value options(*string);
          object  pointer value options(*string);
          type    pointer value options(*string);
          rtnLib  char(10) options(*omit);
        end-pr;

MDR_b64_encode

        ///===============================================================================
        // MDR_b64_encode
        //
        // Encode string in base64 format
        //
        //   @param (output) dst = destination (encoded) string
        //   @param (input) src = source (not encoded) string
        //
        //   @return 0 if successful, -1 otherwise
        // @info MDRFRAME7
        ///===============================================================================

        dcl-pr MDR_b64_encode int(10) extproc(*cwiden:'MDR_b64_encode') opdesc;
          dst varchar(5000000:4) options(*varsize);
          src varchar(5000000:4) const options(*varsize) ccsid(*hex);
        end-pr;

MDR_b64_decode

        ///===============================================================================
        // MDR_b64_decode(): Decode string in base64 format
        //
        //   @param (output) dst = destination (decoded) string
        //   @param (input) src = source (encoded) string
        //
        //   @return 0 if successful, -1 otherwise
        // @info MDRFRAME7
        ///===============================================================================

        dcl-pr MDR_b64_decode int(10) extproc(*cwiden:'MDR_b64_decode') opdesc;
          dst varchar(5000000:4) options(*varsize);
          src varchar(5000000:4) const options(*varsize);
        end-pr;

MDR_encode

        ///===============================================================================
        // MDR_encode
        //
        // URL-encode string
        //
        //   @param (input) handle = handle returned by MDR_newClient.
        //   @param (output) dst = destination (encoded) string
        //   @param (input) src = source (not encoded) string
        // @info MDRFRAME8
        ///===============================================================================

        dcl-pr MDR_encode extproc(*cwiden:'MDR_encode') opdesc;
          handle like(MDR_Handle_t);
          dst    varchar(5000000:4) options(*varsize);
          src    varchar(5000000:4) const options(*varsize);
        end-pr;

MDR_decode

        ///===============================================================================
        // MDR_decode
        //
        // URL-decode string
        //
        //   @param (input) handle = handle returned by MDR_newClient.
        //   @param (output) dst = destination (decoded) string
        //   @param (input) src = source (encoded) string
        // @info MDRFRAME8
        ///===============================================================================

        dcl-pr MDR_decode extproc(*cwiden:'MDR_decode') opdesc;
          handle like(MDR_Handle_t);
          dst    varchar(5000000:4) options(*varsize);
          src    varchar(5000000:4) const options(*varsize);
        end-pr;

MDR_writeBodyToFile

        ///===============================================================================
        // MDR_writeBodyToFile
        //
        // Write an HTTP request/response body to a stream (IFS) file.
        //
        //   @param (input) handle = handle provided by MDR_newClient or MDRAPI
        //   @param (input) body = MDR_BODY_REQUEST or MDR_BODY_RESPONSE
        //   @param (input) stmf = path to stream/ifs file to save to
        //   @param (output/optional) errmsg = variable to receive an error message
        //                            if an error occurs. or *OMIT if not needed.
        //
        //   @return 0 if successful, -1 upon failure
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_writeBodyToFile int(10)
               extproc(*cwiden:'MDR_writeBodyToFile') opdesc;
          handle like(MDR_Handle_t);
          body   int(10) value;
          stmf   varchar(5000:4)  const options(*varsize);
          errmsg varchar(32767:4) options(*varsize: *omit: *nopass);
        end-pr;

    dcl-c MDR_BODY_REQUEST  9901;
    dcl-c MDR_BODY_RESPONSE 9902;

MDR_readBodyFromFile

        ///===============================================================================
        // MDR_readBodyFromFile
        //
        // Read an HTTP request/response body from a stream (IFS) file.
        //
        //   @param (input) handle = handle provided by MDR_newClient or MDRAPI
        //   @param (input) body = MDR_BODY_REQUEST or MDR_BODY_RESPONSE
        //   @param (input) stmf = path to stream/ifs file to read from
        //   @param (output/optional) errmsg = variable to receive an error message
        //                  if an error occurs. or *OMIT if not needed.
        //
        //   @return 0 if successful, -1 upon failure
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_readBodyFromFile int(10)
               extproc(*cwiden:'MDR_readBodyFromFile') opdesc;
          handle like(MDR_Handle_t);
          body   int(10) value;
          stmf   varchar(5000:4)  const options(*varsize);
          errmsg varchar(32767:4) options(*varsize: *omit: *nopass);
        end-pr;

Provider Functions

MDR_isBinaryMode

        ///===============================================================================
        // MDR_isBinaryMode
        //
        // Detects whether the API was called in binary mode.
        //
        // NOTE: MDRFRAME is intended to be used in binary mode,
        //        if called from an EBCDIC or MIXED mode, functionality
        //        may be limited.
        //
        // @return *ON if in binary mode, *OFF otherwise
        //
        // Example:
        //     if MDR_isBinaryMode() = *OFF;
        //        not in binary mode!  why?
        //     endif;
        // @info MDRFRAME
        ///===============================================================================


        dcl-pr MDR_isBinaryMode ind extproc(*cwiden: 'MDR_isBinaryMode');
        end-pr;

MDR_isHTTPS

        ///===============================================================================
        // MDR_isHTTPS
        //
        // Detects whether this API was called using secure HTTP.
        // (aka SSL or TLS)
        //
        // @return *ON if in HTTPS mode, *OFF for plain HTTP
        //
        // Example:
        //
        // if MDR_isHTTPS() = *OFF;
        //   MDR_setError( handle: 'ERR9999'
        //                       : 'This API requires SSL/TLS encryption!!'
        //                       : 1 : 20: : 0 );
        //   return;
        // endif;
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_isHTTPS ind extproc(*cwiden: 'MDR_isHTTPS');
        end-pr;

MDR_print

        ///===============================================================================
        // MDR_print
        //
        //  Print a string directly to the API output without format
        //  checking. This will be appended to the end of any previously
        //  sent data.
        //
        //  @param (input) handle = context handle, identifies which MDRest4i session
        //                 is currently running.
        //  @param (input) string = the string you wish to print in the job's EBCDIC
        //                 it will be converted to UTF-8 before appending.
        //
        // Example:
        //
        //  MDR_setHeader(handle: 'content-type': 'text/plain');
        //  MDR_setStatus(handle: 200);
        //  MDR_print(handle: 'This is plain text API output!');
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_print extproc(*cwiden: 'MDR_print') opdesc;
          handle like(MDR_handle_t);
          string varchar(65536:4) options(*varsize) const;
        end-pr;

MDR_len_print

        ///===============================================================================
        // MDR_len_print
        //
        // Same as MDR_print but with a pointer and length parameter.
        //
        //  @param (input) handle context handle, identifies which MDRest4i session
        //                 is currently running.
        //  @param (input) buf = pointer to buffer containing EBCDIC data
        //  @param (input) len = length of data in buffer.
        //
        //  @return length of string appended to API output from the string buffer
        //
        // Example:
        //    dcl-s BUF char(1000);
        //    dcl-s p_BUF pointer;
        //    dcl-s LEN uns(10);
        //
        //    p_buf = %addr(BUF);
        //    BUF = 'Data data data';
        //    LEN = 14;
        //    MDR_len_print(handle: p_BUF: LEN);
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_len_print int(10) extproc(*cwiden: 'MDR_len_print');
          handle like(MDR_handle_t);
          buf    pointer value;
          len    uns(10) value;
        end-pr;

MDR_write

        ///===============================================================================
        // MDR_write
        //
        // This is the same as "MDR_print", above except that the MDRest4i framework will
        // write the data as-is (no conversion to UTF-8)
        //
        //  @param (input) handle = context handle, identifies which MDRest4i session
        //                 is currently running.
        //  @param (input) string = the string you wish to print in UTF-8 encoding
        //                 or binary data to be sent as-is
        //
        //  Example:
        //  // first load a VARCHAR(4) field named imagedata with
        //  // the bytes from a .JPG file, then:
        //
        //  MDR_setHeader(handle: 'content-type': 'image/jpeg');
        //  MDR_setStatus(handle: 200);
        //  MDR_write(handle: imagedata);
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_write extproc(*cwiden: 'MDR_write') opdesc;
          handle like(MDR_handle_t);
      /if defined(*V7R2M0)
          string varchar(65536:4) options(*varsize) const ccsid(*utf8);
      /else
          string varchar(65536:4) options(*varsize) const;
      /endif
        end-pr;

MDR_len_write

        ///===============================================================================
        // MDR_len_write
        //
        // Same as MDR_write but with a separate length parameter.
        //
        //  @param (input) handle = context handle, identifies which MDRest4i session
        //                 is currently running.
        //  @param (input) buf = pointer to buffer containing UTF-8 encoded data
        //  @param (input) len = length of data in buffer.
        //
        //  @return number of bytes added to the response header
        //
        // Example:
        //    p_image = %alloc(fileSize);
        //    lenRead = read(fd: p_image: fileSize);
        //    MDR_len_write(handle: image: lenRead);    or
        //    numbytes = MDR_len_write(handle: image: lenRead);
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_len_write int(10) extproc(*cwiden: 'MDR_len_write');
          handle like(MDR_handle_t);
          buf    pointer value;
          len    uns(10) value;
        end-pr;

MDR_setError

        ///===============================================================================
        // MDR_setError
        //
        // Set an error to be returned from the API
        //
        //  @param (input) handle = context handle, identifies which MDRest4i session
        //                 is currently running.
        //  @param (input) error_id = the 7-character message ID to be
        //                 reported to the caller.
        //  @param (input) error_text = The full text of the message. This string will
        //                 be sent to the caller as the error message. (It will not be
        //                 modified according to the error_id.)
        //  @param (input) error_statement = statement number to report that the error
        //                 occurred.
        //  @param (input) error_severity = severity of the error to be reported,
        //                 typically should be 10 = Minor
        //                                     20 = Important error
        //                                     30 = Severe Error
        //                                     40 = Critical Error
        //  @param (input) http_status = http status code to return.
        //                 (0=keep same status, usually 500 for server error)
        //                 200 = success
        //                 4xx = client-side error
        //                 etc.
        //
        //  NOTE: You can clear any pending error status by calling with:
        //        MDR_setError(handle: *NULL: *NULL: 0: 0: 0);
        //
        // Example:
        //
        //   MDR_setError( handle:
        //               : 'TEST123'
        //               : 'Any text can go here'
        //               : 123
        //               : 40
        //               : 500 );
        //
        //  This will send back the following
        //
        //  error_id = 'TEST123'
        //  error_text = 'Any text can go here'
        //  statement = 123
        //  severity = 40
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_setError extproc(*cwiden: 'MDR_C_setError');
          handle          like(MDR_handle_t);
          error_id        pointer value options(*string);
          error_text      pointer value options(*string);
          error_statement uns(10) value;
          error_severity  int(10) value;
          http_status     int(10) value;
        end-pr;

MDR_COBOL_setError

        ///===============================================================================
        // MDR_COBOL_setError
        //
        // This is a wrapper around MDR_setError that used fixed-length
        // strings for error_id and error_text. There's no reason to use
        // it from RPG.
        //
        //  @param (input) handle = context handle, identifies which MDRest4i session
        //                 is currently running.
        //  @param (input) error_id = the 7-character message ID to be
        //                 reported to the caller.
        //  @param (input) error_text = The full text of the message. This string will
        //                 be sent to the caller as the error message. (It will not be
        //                 modified according to the error_id.)
        //  @param (input) error_statement = statement number to report that the error
        //                 occurred.
        //  @param (input) error_severity = severity of the error to be reported,
        //                 typically should be 10 = Minor
        //                                     20 = Important error
        //                                     30 = Severe Error
        //                                     40 = Critical Error
        //
        // If called from Cobol, you would refer to it by the extproc
        // name (MDR_setError).
        //
        // CALL PROCEDURE 'MDR_setError'
        //    USING LS-HANDLE
        //          WS-ERROR-ID        (PIC X(7))
        //          WS-ERROR-TEXT      (PIC X(500))
        //          WS-ERROR-STATEMENT (USAGE AS BINARY)
        //          WS-SEVERITY        (USAGE AS BINARY)
        //          WS-HTTP-STATUS     (USAGE AS BINARY)
        // END-CALL.
        //
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_COBOL_setError extproc(*cwiden: 'MDR_setError');
          handle          like(MDR_handle_t);
          error_id        char(7)   const options(*omit);
          error_text      char(500) const options(*omit);
          error_statement uns(10)   value;
          error_severity  int(10)   value;
        end-pr;

MDR_setErrorMsg

        ///===============================================================================
        // MDR_setErrorMsg
        //
        // Use a message file to set an error returned by the API.
        //
        // This routine differs from MDR_setError in that it uses the
        // format of a message in a *MSGF object to control the contents
        // of your message. Each &1, &2, &3, etc in the text of your
        // message will be replaced with data from the 'msgdta'
        // parameter.
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //   @param (input) msgfile = An IBM *MSGF object found on disk. This
        //                  parameter is treated as CHAR(21) and expects the
        //                  format LIBRARY/OBJECT in uppercase.
        //   @param (input) msgid = The 7-character message ID from the msgfile
        //                  object to be used. Must exist in 'msgfile'
        //   @param (input) msgdta = The message data to be used to fill-in
        //                  variables from the message file.
        //   @param (input) msgdtalen = Length in bytes of the msgdta parameter,
        //                  or 0 if no data is needed
        //   @param (input) error_statement = statement number to report that
        //                  the error occurred.
        //   @param (input) error_severity = severity of the error to be reported,
        //                  typically should be 10 = Minor
        //                                      20 = Important error
        //                                      30 = Severe Error
        //                                      40 = Critical Error
        //
        // Example:
        //
        //   dcl-ds DS_CPF2105 qualified;
        //     object  char(10) inz('CUSTMAST');
        //     library char(10) inz('*LIBL');
        //     type    char(7)  inz('*FILE');
        //   end-ds;
        //
        //   MDR_setErrorMsg( handle
        //                  : '*LIBL/QCPFMSG'
        //                  : 'CPF2105'
        //                  : DS_CPF2105
        //                  : %len(DS_CPF2105)
        //                  : 123
        //                  : 40 );
        //
        //  This will send back the following
        //
        //  error_id = 'CPF2105'
        //  error_text = 'Object CUSTMAST in *LIBL type *FILE not found'
        //  statement = 123
        //  severity = 40
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_setErrorMsg extproc(*cwiden: 'MDR_C_setErrorMsg');
          handle          like(MDR_handle_t);
          msgfile         pointer value options(*string);
          msgid           pointer value options(*string);
          msgdta          pointer value options(*string);
          msgdtalen       int(10) value;
          error_statement uns(10) value;
          error_severity  int(10) value;
        end-pr;

MDR_setStatus

        ///===============================================================================
        // MDR_setStatus
        //
        // Set an HTTP status code to be sent as output
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //   @param (input) status = 3-digit status code.
        //   @param (input/optional) = message sent to the HTTP server along with
        //               the status code. If no message is provided, the default
        //               message is sent.
        //
        // Common codes are:
        //       200 = OK; API was successful
        //       302 = Redirect; Browser should open a different URL
        //       400 = Bad Request; Caller sent bad data.
        //       403 = Forbidden; You lack authority to carry out that
        //               action.
        //       404 = Not Found; The resource you are trying to retrieve
        //               cannot be found.
        //       500 = Server error;  An error occurred within the API
        //               and the program was not successful.
        //
        // Example:
        //  MDR_setStatus(handle: 500);  // indicates a generic error
        //
        // Example:
        //  MDR_setStatus(handle: 500: 'Program Crashed');
        //
        // Example:
        //  MDR_setStatus(handle: 302);  // indicates a redirect
        //  MDR_setHeader(handle: 'location':'https://www.midrangedynamics.com');
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_setStatus extproc(*cwiden: 'MDR_setStatusOD') opdesc;
          handle          like(MDR_handle_t);
          status          uns(5) const;
          reason          varchar(50:4) const options(*omit:*nopass);
        end-pr;

MDR_getQueryVar

        ///===============================================================================
        // MDR_getQueryVar
        //
        // Retrieve an input variable from the query string. The query string is the
        // part of the URL that follows the ?.
        //
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //   @param (input) name = name of query string variable to retrieve
        //
        //   @return the value of the query string variable.
        //
        // Example:
        //   URL is http://yourserver/mdrapi/customer/123?op=call
        //
        //   action = MDR_getQueryVar('op');
        //
        //   action will be set to 'call'
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_getQueryVar varchar(2048)
                               rtnparm
                               extproc(*cwiden:'MDR_RPG_getQueryVar');
          handle          like(MDR_handle_t);
          name            varchar(200) const;
        end-pr;

MDR_getPathVar

        ///===============================================================================
        // MDR_getPathVar
        //
        // Retrieve a portion of the path. The path is the part of the URL
        // that comes after the host/port name, and before the query string.
        //
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //   @param (input) key = value in path that result is relative to
        //   @param (input) position = position within the path relative to the key.
        //                  values: zero = the key
        //                          negative value = positions before the key
        //                          positive value = positions after the key
        //
        //   @return the value of the path at that position, or '*NOTFOUND' if
        //           you specify a portion of the path that does not exist.
        //
        // Example:
        //   URL is http://yourserver/mdrapi/customer/123/test
        //
        //   custid = MDR_getPathVar(handle: 'customer': 1);  // 123
        //   test   = MDR_getPathVar(handle: 'test': -1);     // 123
        //   x      = MDR_getPathVar(handle: 'mdrapi': 3);    // test
        //   name   = MDR_getPathVar(handle: 'customer': 0)   // customer
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_getPathVar varchar(2048)
                              rtnparm
                              extproc(*cwiden:'MDR_RPG_getPathVar');
          handle          like(MDR_handle_t);
          key             pointer value options(*string:*trim);
          position        int(10) value;
        end-pr;

MDR_getPathVarCount

        ///===============================================================================
        // MDR_getPathVarCount
        //
        // Returns the number of path components in the current request
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //
        //   @return the number of path parameter elements
        //
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_getPathVarCount packed(7: 0) extproc('MDR_getPathVarCount');
          handle like(MDR_handle_t);
        end-pr;

MDR_getQueryVarCount

        ///===============================================================================
        // MDR_getQueryVarCount
        //
        // Returns the number of query string variables in the current request
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //
        //   @return the number of query parameters in current request
        //
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_getQueryVarCount packed(7: 0)
          extproc('MDR_getQueryVarCount');
          handle like(MDR_handle_t);
        end-pr;

MDR_newHandle

        ///===============================================================================
        // MDR_newHandle
        //
        // Generate a new MDRest4i session handle
        //
        //   @return the pointer to the handle in memory.  You must call
        //           MDR_freeHandle to free the memory for this pointer.

        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_newHandle pointer extproc(*cwiden:'MDR_newHandle');
        end-pr;

MDR_freeHandle

        ///===============================================================================
        // MDR_freeHandle
        //
        // Free the memory used by an MDRest4i session handle.
        //
        //  @param (input) handlePtr = pointer to a session handle created by
        //                 MDR_newHandle that should be freed up.
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_freeHandle extproc(*cwiden:'MDR_freeHandle');
          handlePtr pointer value;
        end-pr;

MDR_sendJobInfo

        ///===============================================================================
        // MDR_sendJobInfo
        //
        // To assist with debugging and other diagnostic usages, MDRest4i supports adding
        // a customer header to the output containing the job information.
        //
        // There are two ways to enable this. It can be enabled for all programs by
        // placing the following in your HTTP server's httpd.conf file:
        //      SetEnv MDR_JOB_HEADER Y
        //
        // Alternately, it can be enabled in a per-program basis by calling the following
        // prototype from your API:
        //      MDR_endJobInfo(handle: *ON);
        //
        //   @param (input) handle = MDRest4i session handle
        //   @param (input) enable = pass *ON to enable the header, *OFF otherwise
        //
        // Output:
        //   The following header will be returned from the API:
        //
        // x-mdrsrvjob: pgm=library/object; curuser=userid; job=123456/user/jobname
        // @info MDRFRAME5
        ///===============================================================================

        dcl-pr MDR_sendJobInfo extproc(*cwiden:'MDR_sendJobInfo');
          handle like(MDR_Handle_t);
          enable ind const;
        end-pr;

MDR_getAuth

        ///===============================================================================
        // MDR_getAuth
        //
        // Retrieves the authorization string provided from the consumer
        // (available in provider, only.)
        //
        //   @param (input/output) handle = handle provided by MDRAPI
        //   @param (output/optional) type = (output/optional) type of authentication
        //                            used, BASIC, BEARER or DIGEST
        //   @param (output/optional) user = (output/optional) userid provided
        //                            (blank for bearer)
        //   @param (output/optional) token = (output/optional) authentication token or
        //                            password. For basic this is the password, for bearer
        //                            it is the authentication token, for digest it is the
        //                            response hash.
        //
        //   @return 0 if successful, -1 if there was no authorization
        //           header, or if the header was invalid.
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_getAuth int(10)
               extproc(*cwiden:'MDR_getAuth') opdesc;
          handle like(MDR_Handle_t);
          type   varchar(256:4) options(*varsize:*omit:*nopass);
          user   varchar(256:4) options(*varsize:*omit:*nopass);
          token  varchar(2048:4) options(*varsize:*omit:*nopass);
        end-pr;

Consumer Functions

MDR_newClient

        ///===============================================================================
        // MDR_newClient
        //
        // Create a new handle for a client connection
        //
        //   @return a pointer to a dynammically allocated client handle.
        //           (call MDR_freeClient to release the memory)
        //           or *NULL upon failure
        // @info MDRFRAME8
        ///===============================================================================

        dcl-pr MDR_newClient pointer extproc(*cwiden:'MDR_newClient');
        end-pr;

MDR_setClientOpt

        ///===============================================================================
        // MDR_setClientOpt
        //
        // Set an option within a client instance
        //
        //  NOTE: In addition to these options, you can also set headers
        //        with MDR_setHeader() or cookies with MDR_setCookie()
        //
        //  @param (input) handle = identifies the client instance
        //  @param (input) opt = option to set (see constants below)
        //  @param (input) val = value to set option to.
        //
        //  @return 0 if option set successfully, -1 upon error
        // @info MDRFRAME8
        ///===============================================================================

        dcl-pr MDR_setClientOpt int(10) opdesc
                                extproc(*cwiden: 'MDR_setClientOpt');
          handle like(MDR_Handle_t);
          option int(10) const;
          value  pointer value options(*string);
        end-pr;

Constants for MDR_setClientOpt

MDR_BUF_SIZE = size of send/receive buffer MDR_KDB_PATH = IFS pathname of key store database (TLS/SSL) MDR_KDB_PASSWORD = password needed for MDR_KDB_PATH, above. MDR_KDB_LABEL = label for MDR_KDB_PATH, above. MDR_DCM_APPID = application ID to use with digital cert mgr MDR_TIMEOUT = timeout in millseconds to wait before giving up on network operations MDR_IDLE_LIMIT = by default, the MDRest4i client will leave the connection to the server open between requests to improve performance. The idle limit is the maximum time (in seconds) that it will try to use this open connection. Set this to 0 to always disconnect between requests. MDR_LAX_AUTH = Allow lax authentication for TLS/SSL certificates Y=Yes, N=No. MDR_USEC_DELAY = Delay between retries in microseconds MDR_MAX_RETRIES = Maximum amount of retries/redirects before giving up on connection. MDR_MAX_REDIRECTS = Maximum amount of http redirects that will be followed before giving up. MDR_FOLLOW_AUTH_HEADER = Does the Authorization: header get resent in a redirect? ('yes', 'no', default = 'no') MDR_FOLLOW_ORIG_METHOD = Do 301,302,303 redirects keep the original HTTP method, (vs. changing it to GET) ('yes', 'no', default: 'no') MDR_AUTH_TYPE = Type of authentication. ('basic', 'digest', 'bearer') if you set this to basic or bearer, the credentials will always be sent to the server. if this is left unset, the key will only be sent if the server requests it. You may set this to your own custom string if you need to use an unsupported authentication type. In that case, (or when using a bearer token) you should also set the MDR_AUTH_TOKEN. MDR_USER = UserID for authentication (if basic or digest) MDR_PASSWORD = Password for authentication (if basic or digest) MDR_AUTH_TOKEN = Token for authentication (if bearer token or custom) MDR_LOG_PATH = Path to use for creating log files. 'ifs:/path/to/file' 'pf:library/file' 'dtaq:library/dtaq' MDR_LOG_PARTS = Allows selecting details to be logged (default: everything is logged) 'request=Y + requestUri=N requestHeader=Y + requestBody=N + response=N + responseHeader=N responseBody=Y' MDR_PROXY_URL = URL for proxy server in this format: 'http://hostname:port' MDR_PROXY_USER = Userid to login to proxy server MDR_PROXY_PASSWORD = Password to login to proxy server MDR_CLEAR_LOG = Y/N should the IFS log file be cleared on the next request (default=N)

dcl-c MDR_BUF_SIZE           const(2001);
dcl-c MDR_KDB_PATH           const(2002);
dcl-c MDR_KDB_PASSWORD       const(2003);
dcl-c MDR_KDB_LABEL          const(2004);
dcl-c MDR_DCM_APPID          const(2005);
dcl-c MDR_TIMEOUT            const(2006);
dcl-c MDR_LAX_AUTH           const(2007);
dcl-c MDR_USEC_DELAY         const(1000);
dcl-c MDR_MAX_RETRIES        const(1001);
dcl-c MDR_AUTH_TYPE          const(1002);
dcl-c MDR_USER               const(1003);
dcl-c MDR_PASSWORD           const(1004);
dcl-c MDR_AUTH_TOKEN         const(1005);
dcl-c MDR_LOG_PATH           const(1006);
dcl-c MDR_PROXY_URL          const(1007);
dcl-c MDR_PROXY_USER         const(1008);
dcl-c MDR_PROXY_PASSWORD     const(1009);
dcl-c MDR_MAX_REDIRECTS      const(1010);
dcl-c MDR_IDLE_LIMIT         const(1011);
dcl-c MDR_LOG_PARTS          const(1012);
dcl-c MDR_FOLLOW_AUTH_HEADER const(1013);
dcl-c MDR_FOLLOW_ORIG_METHOD const(1014);
dcl-c MDR_CLEAR_LOG          const(1015);

MDR_setClientCfg

        ///===============================================================================
        // MDR_setClientCfg
        //
        // Set client configuration within a client instance.
        //
        // This is a wrapper for MDR_setClientOpt, it lets you set all
        // of the desired options using a single property string.
        //
        // NOTE: In addition to these options, you can also set headers
        //       with MDR_setHeader() or cookies with MDR_setCookie()
        //
        //   @param (input) handle = (input) identifies the client instance
        //   @param (input) options = (input) property string representing the options
        //                  to set.
        //
        // Options are specified without the MDR_ prefix, and without underscores.
        // For example, MDR_LOG_PATH is set as logPath="/path/to/file.txt"
        //
        // Example of setting all options:
        //
        //    opts = 'bufSize=50000 kdbPath="/ifs/path/myfile.kdb" +
        //            kdbPassword=myPass kdbLabel="Label 123" +
        //            dcmAppId=ACME_CLIENT_APP timeout=30000 laxAuth=Y +
        //            uSecDelay=250000 maxRetries=10 user=sklement +
        //            password=bigboy proxyUrl=http://myprox.com:123 +
        //            proxyUser=scottk proxyPassword=d00fus +
        //            maxRedirects=3 idleLimit=5 authType=basic +
        //            logPath="/MDRest4i/logs/daily-%Y%m%d.txt"';
        //
        //    MDR_setClientCfg(handle: opts);
        //
        // See MDR_setClientOpt for a description of the above options.
        // @info MDRFRAME8
        ///===============================================================================

        dcl-pr MDR_setClientCfg opdesc
                                extproc(*cwiden: 'MDR_setClientCfg');
          handle like(MDR_Handle_t);
          options varchar(32767:4) const options(*varsize);
        end-pr;

MDR_freeClient

        ///===============================================================================
        // MDR_freeClient
        //
        // Free the memory used by an HTTP client
        //
        //   @param (input) handle = handle returned by MDR_newClient.
        //
        // Once this is called, you must not use the handle again.
        // @info MDRFRAME8
        ///===============================================================================

        dcl-pr MDR_freeClient extproc(*cwiden: 'MDR_freeClient');
          handle like(MDR_Handle_t);
        end-pr;

MDR_request

        ///===============================================================================
        // MDR_request
        //
        // Make an HTTP request with an HTTP client
        //
        //   @param (input) handle = handle returned by MDR_newClient.
        //   @param (input) method = HTTP method (GET, POST, PUT, DELETE, etc)
        //   @param (input) uri = the URL to make the request to
        //   @param (input/optional) sendData = data to send to the HTTP server (request
        //                           body) or *OMIT if no data to be sent via this parm.
        //                           may be prefixed with 'ifs:' to send from a file
        //   @param (output/optional) receiveData = data received from the HTTP server
        //                            (response body) or *OMIT if the receiveData is not
        //                            to be returned via this parm.  May be prefixed with
        //                            'ifs:' to save document to an IFS stream file.
        //
        //   @return the HTTP status code (200=success)
        //           or a -1 if a client-side error occurred
        //
        // NOTE: You may also call MDR_getHeader, MDR_getCookie MDR_getRequest to get data
        //       from this transaction
        //
        // @info MDRFRAME8
        ///===============================================================================

        dcl-pr MDR_request int(10) extproc(*cwiden: 'MDR_request') opdesc;
          handle      like(MDR_Handle_t);
          method      varchar(32:4) const;
          uri         varchar(32767:4) const options(*varsize);
        /if not defined(*V7R2M0)
          sendData    varchar(16773100:4) const options(*varsize:*omit:*nopass);
          receiveData varchar(16773100:4) options(*varsize:*omit:*nopass);
        /elseif defined(MDR_REQUEST_TRANSLATE)
          sendData    varchar(16773100:4) const options(*varsize:*omit:*nopass)
                                          ccsid(*utf8);
          receiveData varchar(16773100:4) options(*varsize:*omit:*nopass)
                                          ccsid(*utf8);
        /else
          sendData    varchar(16773100:4) const options(*varsize:*omit:*nopass)
                                          ccsid(*hex);
          receiveData varchar(16773100:4) options(*varsize:*omit:*nopass)
                                          ccsid(*hex);
        /endif
        end-pr;

MDR_getRespPtr

        ///===============================================================================
        // MDR_getRespPtr
        //
        // Retrieves a pointer to the response body
        //
        // NOTE: The main use of this is to handle data larger than 16mb.
        //       By working with it using pointer/length.
        //
        // NOTE: this returns a direct pointer to the buffer, it does
        //       not make a copy. You should not dealloc this pointer or
        //       change its data or unpredictable results will occur.
        //
        //   @param (input) handle = handle returned by MDR_newClient.
        //   @param (output) ptr = pointer, on output will bet set to the address of the
        //                  response body
        //   @param (output) size = on output will be set to the size of the response
        //                  body in bytes
        //
        // @info MDRFRAME8
        ///===============================================================================

        dcl-pr MDR_getRespPtr extproc(*cwiden:'MDR_getRespPtr');
          handle      like(MDR_Handle_t);
          ptr         pointer;
          size        uns(20);
        end-pr;

MDR_getClientError

        ///===============================================================================
        // MDR_getClientError
        //
        // Retrieve the last error message for a client connection.
        //
        //   @param (input) handle = handle representing the current client session
        //   @param (output/optional) msgid = CHAR(7) message id (or *OMIT)
        //   @param (output/optional) msg = textual message  (or *OMIT)
        //   @param (output/optional) sev = message severity (or *OMIT)
        // @info MDRFRAME8
        ///===============================================================================

        dcl-pr MDR_getClientError extproc(*cwiden:'MDR_getClientError') opdesc;
          handle      like(MDR_Handle_t);
          msgid       char(7)          options(*omit:*nopass);
          msg         varchar(32767:4) options(*omit:*varsize:*nopass);
          sev         int(10)          options(*omit:*nopass);
        end-pr;

JSON Functions

The following set of JSON functions are found in the MDRST/QRPGLESRC.MDRYAJLR4 copybook

RPG Prototypes for YAJL with mdr_ prefix

MDR_beginArray

if called without parameter or with blank parameter, it starts non-labeled array. If no parameter, writes labeled array eg. "myarray": [

@param (input/opt) array label

@return Yajl generation status

dcl-pr mdr_beginArray
  label varchar(65535) const options(*varsize:*nopass);
end-pr;

MDR_endArray

ends the array by adding closing square bracket @return: Yajl generation status

dcl-pr mdr_endArray int(10) extproc('YAJL_ENDARRAY')
end-pr;

MDR_beginObject

if called without parameter or with blank parameter, it starts non-labeled object. Otherwise, it writes labeled object eg. "myobject": { @param (input/opt) array label

@return Yajl generation status

dcl-pr mdr_beginObject int(10) extproc('YAJL_BEGINOBJ');
  label varchar(65535) const options(*varsize:*nopass);
end-pr;

MDR_endObject

ends the object by adding closing curly bracket @return Yajl generation status

dcl-pr mdr_endObject int(10) extproc('YAJL_ENDOBJ')
end-pr;

MDR_addNull

Add a null value to a JSON data stream @param label (input) = label of property to add to object value of 'label' will be set to null. e.g "name": null

@return Yajl generation status

dcl-pr mdr_addNull int(10) extproc('YAJL_ADDNULL');
  value varchar(65535) const options(*varsize:*nopass);
end-pr;

MDR_addChar

Add a character value to the JSON data stream if one parameter: add character string to add to JSON stream if two parameters: key of property to add to object, and value

@param label (input) = key of property to add to object

@param value (input) = character string to set as property value

if the third parameter is given:

@param isNull (input) = if *ON output is null, otherwise is value above

@return yajl_gen_status_ok upon success, or generator status code upon failure.

Example: mdr_addChar('name' : mdlReq.name : mdlReq.name:=' '); if mdlReq.name is blank, then the JSON will look like this: "name": null if mdlReq.name is 'stuart', then the JSON will look like this: "name": "stuart"

dcl-pr mdr_addChar int(10) extproc('YAJL_ADDCHAR');
  label varchar(65535) const options(*varsize);
  value varchar(65535) const options(*varsize:*nopass:*omit);
  isnull ind const options(*nopass:*omit);
end-pr;

MDR_addNum

Add a numeric value to the JSON data stream if one parameter: add number to JSON stream (in string form) if two parameters: key of property to add to object, and value

@param label (input) = key of property to add to object

@param value (input) = number to set as property value (in string form)

if the third parameter is given: @param isNull (input) = if *ON output is null, otherwise is value above

@return yajl_gen_status_ok upon success, or generator status code upon failure.

dcl-pr mdr_addNum int(10) extproc('YAJL_ADDNUM');
  label varchar(65535) const options(*varsize);
  value varchar(65535) const options(*varsize:*nopass:*omit);
  isnull ind const options(*nopass:*omit);
end-pr;

MDR_addBool

Add a boolean value to the JSON data stream if one parameter: RPG indicator, where ON=true, OFF=false to add to JSON data stream if two parameters: key of property to add to object, and value(true or false)

@param label (input) = key of property to add to object

@param value (input) = RPG indicator to set as a boolean value.

if the third parameter is given: @param isNull (input) = if *ON output is null, otherwise is value above

@return yajl_gen_status_ok upon success, or generator status code upon failure.

dcl-pr mdr_addBool int(10) extproc('YAJL_ADDBOOL');
  label varchar(65535) const options(*varsize);
  Value ind const options(*nopass);
  isnull ind const options(*nopass:*omit);
end-pr;

MDR_startJson

Open a YAJL JSON generator addchar etc functions to build JSON

@param beautify (input) = ON would add line breaks and indentation for readability OFF would generate compact JSON @param escSolidus (input) = On would escape the solidus (aka forward slash) characters. default is Off

@return: yajl_gen_status_ok (i.e. 0) if successful yajl_gen_open_fail (i.e. 1000001) upon failure

dcl-pr mdr_startJson int(10) Extproc('YAJL_GENOPEN');
  beautify ind const;
  escSolidus ind const options(*nopass);
end-pr;

MDR_endJson

closes the JSON generation channel and deallocates memory. subsequent addchar, getJson etc cannot be used

dcl-pr mdr_endJson Extproc('YAJL_GENCLOSE')
end-pr;

MDR_getJson

Copies JSON generator buffer to the caller's variable or buffer.

@param ccsid = (input) CCSID to convert data to. 0=job CCSID.

@param bufptr = (input) Pointer to variable or buffer to copy the data to.

@param bufSize = (input) Size of the jsonBuf buffer (in bytes)

@param rtnLen = (output) length of data placed in buffer

@return YAJL generator status.

dcl-pr mdr_getJson int(10) Extproc('YAJL_COPYBUF');
  ccsid  int(10) value;
  bufptr pointer value;
  bufsize int(10) value;
  rtnlen int(10);
end-pr;

MDR_getJsonPtr

@param returns a pointer to JSON internal buffer where JSON data is stored.

@param rtnptr = (output) pointer to YAJL's generator buffer

@param rtnlen = (output) length of returned buffer in bytes

@return YAJL generator status.

dcl-pr mdr_getJsonPtr int(10) Extproc('YAJL_GETBUF');
  bufptr pointer;
  bufsize uns(10);
end-pr;

MDR_getJsonStr

@return the current JSON buffer to an RPG variable of max 2000000 size. Receiving variable must be a varchar. Not optimized and can impact performance. Use mdr_getJson for larger size or better performance

dcl-pr mdr_getJsonStr varucs2(2000000) extproc('YAJL_COPYBUFSTR')
end-pr;

MDR_addTimestamp

Adds an ISO 8601 timestamp in: YYYY-MM-DDTHH:MM:SS.sss format to the JSON document.

@param (input) name = key name if within an object, or *omit

@param (input) val = standard RPG timestamp field

@param (input/opt) tz = time zone to use, examples are: 'Z' = UTC '+0500' = 5 hours east of UTC '-0600' = 6 hours west of UTC ' ' = local time '*UTC' (default) Convert to UTC and report as a UTC timestamp

@param (input) datesep = date separator (default: -)

@param (input) timesep = time separator (default: :)

@param (input) tzsep = timezone sep (default: none)

@return returns yajl_gen_status_ok upon success, or generator status code upon failure.

dcl-pr mdr_addTimestamp extproc('YAJL_ADDTIMESTAMP');
  name           Varchar(65535) CONST OPTIONS(*VARSIZE:*OMIT);
  val            Timestamp  CONST;
  tz             Varchar(6)  CONST OPTIONS(*OMIT:*NOPASS);
  datesep        Varchar(1)  CONST OPTIONS(*OMIT:*NOPASS);
  timesep        Varchar(1)  CONST OPTIONS(*OMIT:*NOPASS);
  tzsep          Varchar(1)  CONST OPTIONS(*OMIT:*NOPASS);
  isnull         ind         CONST OPTIONS(*OMIT:*NOPASS);
end-pr;

MDR_getEntry

@return the value at the specified key node. e.g. for the node "city":"Paris", it will return "Paris". The node must be of string type, otherwise, it will return blank

dcl-pr mdr_getEntry varchar(1024) extproc('YAJL_GETSTRKEY');
  bgnNode pointer value;
  entry varchar(50) const;
end-pr;

MDR_GetNumKey

@return the numeric value in string form at the specified key node. for the node "orderno":57689, it will return '57689. The node must be of numeric type. Otherwise, it returns blank

dcl-pr mdr_GetNumKey varchar(50) extproc('YAJL_GETNUMSTR');
  node pointer value;
end-pr;

MDR_object_insert

Inserts a new node into an object in a YAJL tree structure

@param node = (i/o) object node to insert into

@param type = (input) type of node to insert (one of the MDR_t_xxx constants below) @param newKey = (input) new key name to insert

@param newVal = (input) string representation of new value to insert (only used for numbers/strings) @param rel = (input/opt) relationship to refKey (MDR_xx below)

@param refKey = (input/opt) key to reference when inserting

@return the newly created node (yajl_val) or *NULL upon failure

dcl-pr mdr_object_insert Pointer extproc('YAJL_OBJECT_INSERT');
  node           Pointer        VALUE;
  type           Int(10)        VALUE;
  newKey         Varchar(1024)  CONST OPTIONS(*VARSIZE);
  newVal         Varchar(65535) CONST OPTIONS(*VARSIZE);
  xrel           Int(10)        VALUE OPTIONS(*NOPASS);
  refKey         Varchar(1024)  CONST OPTIONS(*VARSIZE: *NOPASS: *OMIT);
End-PR;

Dcl-C MDR_before  CONST(1);
Dcl-C MDR_after   CONST(2);
Dcl-C MDR_replace CONST(3);
Dcl-C MDR_append  CONST(X'1FFFFFFF');

Dcl-C MDR_t_string CONST(1);
Dcl-C MDR_t_number CONST(2);
Dcl-C MDR_t_object CONST(3);
Dcl-C MDR_t_array  CONST(4);
Dcl-C MDR_t_true   CONST(5);
Dcl-C MDR_t_false  CONST(6);
Dcl-C MDR_t_null   CONST(7);

MDR_array_add

Adds data to the end of an array in a tree node

@param node = (i/o) array node to add onto

@param type = (input) type of node to insert (one of the yajl_t_xxx constants @param newVal = (input) string representation of new value to insert (only used for numbers/strings)

@return the newly created node (yajl_val) or *NULL upon failure

dcl-pr mdr_array_add Pointer extproc('YAJL_ARRAY_ADD');
  node           Pointer        VALUE;
  type           Int(10)        VALUE;
  newVal         Varchar(65535) CONST OPTIONS(*VARSIZE);
End-PR;
The rest of the functions below, coem from MDRST/QRPGLESRC.MDRFRAME

MDR_setFormat

        ///===============================================================================
        // MDR_setFormat
        //
        // Sets the format that the MDRest4i framework uses to send/receive documents
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //   @param (input) format = one of the MDR_FORMAT_xxx constants
        // @info MDRFRAME
        ///===============================================================================

        dcl-c MDR_FORMAT_JSON 0;
        dcl-c MDR_FORMAT_XML  1;

        dcl-pr MDR_setFormat extproc(*cwiden:'MDR_setFormat');
          handle          like(MDR_handle_t);
          format          packed(7: 0) const;
        end-pr;

MDR_genParseOptions

        ///===============================================================================
        // MDR_genParseOptions
        //
        // Set parsing/generating options for the MDRest4i DATA-INTO or DATA-GEN tools.
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //   @param (input) options = (input) configuration options for either the
        //                  parser or generator. See notes below:
        //
        // These options can be used to configure how MDRFRAME(GENERATOR)
        // (with DATA-GEN or MDR_DATAGEN) generates documents as well as
        // how MDRFRAME(PARSER) (with DATA-INTO or MDR_DATAINTO) parses
        // documents.
        //
        // Options are specified as a string in the format option=value.
        // Multiple options can be specified by separating them with
        // spaces. If spaces are needed within a value, they can be
        // specified by placing the value in double quote marks, such as
        // option="value with spaces"
        //
        // For use with DATA-INTO or MDR_DATAINTO
        //
        // - value_null = the value written to a subfield when the corresponding
        //           JSON is null. Default = *NULL
        // - value_true = the value written to a subfield when the corresponding
        //           JSON is true. Default = '1'
        // - value_false = the value written to a subfield when the corresponding
        //           JSON is false. Default = '0'
        // - document_name = The name given to the document-level element of a
        //           JSON or XML document.
        // - datasubf = = XML only, the name of a subfield for a tag's inner
        //           value. Default = none
        // - req = yes/no whether data is automatically read from the request
        //           body of HTTP requests. Default=yes
        // - ns = XML only, namespace processing. keep=keep namespaces,
        //           remove=strip namespaces from tag names. Default=keep
        // - convts = yes/no whether timestamps are interpreted and
        //           ISO 8601 timestamps are converted to RPG/DB2 timestamps.
        //           Default=no
        //
        // For DATA-GEN or MDR_DATAGEN
        //
        // - datasubf = XML only, the name of a subfield for a tag's inner
        //             value. Default=none
        // - req = yes/no whether data is automaticaly written to the
        //             response body of HTTP requests. Default=yes
        // - sequenceType = array/object, controls how DATA-GEN sequences
        //             are generated. default=object
        // - includeEmptyArrays = yes/no. If yes, an array with 0 elements
        //             will be written as an empty array in the resulting
        //             document. If no, 0 elements will prevent the element
        //             from being written entirely. Default=no
        // - beautify = yes/no, whether the output contains tabbing and
        //             linefeeds to make it easier for a human to read.
        //             default=no
        // - format = XML or JSON = which format should data be generated in.
        //             Default=json unless the request body was in XML.
        // - convts = yes/no = should RPG/DB2 timestamps be converted into
        //             ISO 8601 format. default=no
        // - tstzoutput = ucs/local/none, timestamp timezone output. Should a
        //             timezone be appended? IF ucs, timestamps will be converted
        //             from the computer's current timezone to UCS, and a
        //             'Z' (Z=Zulu, which is the ISO 8601 method of denoting
        //             UTC/GMT) appeneded. If local, the computers current
        //             timezone will be appended to the timestamp. If none
        //             (default) no timezone is appended. Default=none
        //
        // For MDR_DATAINTO or MDR_DATAGEN
        //
        // - trace = Specify an IFS path, and a trace file will be generated
        //           to assist with debugging the operation. Default=none.
        //           Example: trace="/tmp/trace.txt"
        // - trim = all/none. Whether blanks are trimmed from character
        //           strings. default=all
        // - countPrefix = A prefix used for counting JSON or XML elements
        //           when parsing, or controlling the number of output elements when writing. Same a

        // - renamePrefix = A prefix used by MDR_DATAGEN to control the names
        //           of outout elements. Same as the "renameprefix" option for
        //           RPG's DATA-GEN opcode. Default=none
        // - req = yes/no Whether data is automatically read from the request
        //           body or written to the response body of HTTP requests.
        //           Default=yes
        // - ccsid = CCSID of document. Values are ucs2, utf16, utf8, job or
        //           a ccsid number. Default=utf8 when generating, job ccsid
        //           when reading from a variable, utf8 when reading from a
        //           request body.
        // - document_name = the name of the document-level element. Used by
        //           MDR_DATAGEN for generating XML documents. default=none
        // - doc = string/file, controls where the JSON is read from or
        //           written to. If set to string, the Document parameter is
        //           interpreted as the JSON or XML document itself. If set
        //           to file, the Document parameter is interpreted as the
        //           path to a file in the IFS. Default=string
        // - output = in MDR_DATAGEN sequences, controls how the output is
        //           treated. clear=output is cleared before generating,
        //           append=output is added to the end of an existing
        //           file/string, or continue=output continued from the last
        //           sequence operation. Default=clear for start of sequences,
        //           continue otherwise.
        //
        // EXAMPLE:
        //
        //    MDR_genParseOptions(handle: 'document_name=inputmodel +
        //                                 req=yes +
        //                                 tsconv=yes +
        //                                 trace="/tmp/debug trace.txt"')
        //
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_genParseOptions extproc(*cwiden:'MDR_genParseOptions')
                                   opdesc;
          handle      like(MDR_handle_t);
          options     varchar(32764:4)    const options(*varsize:*omit);
        end-pr;

MDR_DATAINTO

        ///===============================================================================
        // MDR_DATAINTO
        //
        // The MDRest4i version of DATA-INTO.
        //
        // Note: It's typically considered better to use RPG's DATA-INTO opcode
        //       if possible, but this works similarly, and can be used on V7R2.
        //
        //
        //  @param (input) handle = context handle, identifies which MDRest4i
        //                 session is currently running.
        //  @param (input) format = (input) a JSON document representing the format of
        //                 variable in 'resultVar'.
        //  @param (input) resultVar = (output) a variable (typically a DS) that will
        //                 contain the result of parsing the JSON/XML.
        //  @param (input) document = (input) JSON/XML document to parse. If doc=file is
        //                 specified, this should contain the IFS pathname where the data
        //                 is read from. Otherwise this should contain the data.
        //                 This parameter is ignored (and may be *OMIT) unless req=no is
        //                 specified in the options.
        //
        //  @param (input) options = (input) configuration options for the parser
       // @info MDRFRAME6
        ///===============================================================================

        dcl-pr MDR_DATAINTO extproc('MDR_DATAINTO') opdesc;
          handle      like(MDR_handle_t);
          format      varchar(10000:4)    const options(*varsize:*omit);
          resultVar   char(16773100)      options(*varsize:*omit);
          document    varchar(16773100:4) options(*varsize:*omit);
          options     varchar(10000:4)    const options(*varsize:*omit);
        end-pr;

MDR_DATAGEN

        ///===============================================================================
        // MDR_DATAGEN
        //
        // The MDRest4i version of DATA-GEN
        //
        //  Note: It's typically considered better to use RPG's DATA-GEN opcode
        //         if possible, but this works similarly, and can be used on V7R2.
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //   @param (input) format = (input) a JSON document representing the format of
        //                  variable in 'sourceVar'.
        //                  or may be *START or *END for sequences.
        //
        //   @param (input) sourceVar = (input) a variable (typically a DS) that contains
        //                  the data that will be placed in the JSON/XML
        //   @param (input) document = (i/o) JSON/XML document. If doc=file is specified
        //                  this is input-only, and should contain the pathname to where
        //                  the document goes. If doc=string, this is output-only and is
        //                  where the parsed document goes may be omitted if the
        //                  document is only to be sent via HTTP (i.e. you don't need a
        //                  copy in your program.)
        //
        //  options = (input) configuration options for the generator
        // @info MDRFRAME6
        ///===============================================================================

        dcl-pr MDR_DATAGEN extproc('MDR_DATAGEN') opdesc;
          handle      like(MDR_handle_t);
          format      varchar(10000:4)    const options(*varsize);
          sourceVar   char(16773100)      options(*varsize: *omit);
          document    varchar(16773100:4) options(*varsize:*omit);
          options     varchar(10000:4)    const options(*varsize);
        end-pr;

MDR_tree_parse

        ///===============================================================================
        // MDR_tree_parse
        //
        // Parse a JSON document into a tree structure
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //   @param (input) stmf = IFS stream file containing JSON document to parse
        //                  or *OMIT if not reading from a file.
        //   @param (input) input = String containing JSON document to parse in UTF-8
        //                  or *OMIT if not reading from a string
        //   @param (input) errMsg = Error message returned if JSON does not parse
        //                  successfully (or *OMIT)
        //
        //   @return the pointer to the tree structure's document node
        //           or *NULL upon failure
        // @info MDRFRAME7
        ///===============================================================================

        dcl-pr MDR_tree_parse pointer extproc(*cwiden: 'MDR_tree_parse') opdesc;
          handle      like(MDR_handle_t);
          stmf        varchar(5000:4)     const options(*varsize: *omit);
      /if defined(*V7R2M0)
          input       varchar(5242880:4)  const options(*varsize: *omit)
                                          ccsid(*utf8);
      /else
          input       varchar(5242880:4)  const options(*varsize: *omit);
      /endif
          errMsg      varchar(4096:4)     options(*varsize:*omit);
        end-pr;

MDR_tree_free

        ///===============================================================================
        // MDR_tree_free
        //
        // Free up memory used by a JSON tree structure
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //   @param (input) docNode = pointer to the document node (returned by the
        //                 MDR_tree_parse procedure)
        // @info MDRFRAME7
        ///===============================================================================

        dcl-pr MDR_tree_free extproc(*cwiden:'MDR_tree_free');
          handle      like(MDR_handle_t);
          docNode     pointer value;
        end-pr;

MDR_buf_jsonPathV

        ///===============================================================================
        // MDR_buf_jsonPathV
        //
        // Retrieve a string representation of a given JSON path. Output to buffer.
        //
        // MDR_buf_jsonPathU: Same as above, but output is uppercase
        // MDR_buf_jsonPathL: Save as above, but output is lowercase
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //   @param (input) dst = pointer to the destination buffer to populate
        //                  (data will be in job CCSID)
        //   @param (input) size = size of destination buffer (in bytes)
        //   @param (input) path = character string representing a JSON path
        //   @param (input) isNull = Returns 1 if value is NULL, 0 otherwise
        //                  (you may *OMIT isNull)
        //
        //   @return the length of data placed in dst (in bytes)
        // @info MDRFRAME7
        ///===============================================================================

        dcl-pr MDR_buf_jsonPathV uns(10) extproc(*cwiden:'MDR_buf_jsonPathV');
          handle      like(MDR_handle_t);
          dst         pointer value;
          size        uns(10) value;
          path        pointer value options(*string);
          isNull      int(10) options(*omit);
        end-pr;

MDR_buf_jsonPathU

        ///===============================================================================
        // MDR_buf_jsonPathU
        //
        // Retrieve a string representation of a given JSON path. Output to buffer in
        // upper case.
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //   @param (input) dst = pointer to the destination buffer to populate
        //                  (data will be in job CCSID)
        //   @param (input) size = size of destination buffer (in bytes)
        //   @param (input) path = character string representing a JSON path
        //   @param (input) isNull = Returns 1 if value is NULL, 0 otherwise
        //                  (you may *OMIT isNull)
        //
        //   @return the length of data placed in dst (in bytes)
        // @info MDRFRAME7
        ///===============================================================================

        dcl-pr MDR_buf_jsonPathU uns(10) extproc(*cwiden:'MDR_buf_jsonPathU');
          handle      like(MDR_handle_t);
          dst         pointer value;
          size        uns(10) value;
          path        pointer value options(*string);
          isNull      int(10) options(*omit);
        end-pr;

MDR_buf_jsonPathL

        ///===============================================================================
        // MDR_buf_jsonPathL
        //
        // Retrieve a string representation of a given JSON path. Output to buffer in
        // lower case.
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //   @param (input) dst = pointer to the destination buffer to populate
        //                  (data will be in job CCSID)
        //   @param (input) size = size of destination buffer (in bytes)
        //   @param (input) path = character string representing a JSON path
        //   @param (input) isNull = Returns 1 if value is NULL, 0 otherwise
        //                  (you may *OMIT isNull)
        //
        //   @return the length of data placed in dst (in bytes)
        // @info MDRFRAME7
        ///===============================================================================

        dcl-pr MDR_buf_jsonPathL uns(10) extproc(*cwiden:'MDR_buf_jsonPathL');
          handle      like(MDR_handle_t);
          dst         pointer value;
          size        uns(10) value;
          path        pointer value options(*string);
          isNull      int(10) options(*omit);
        end-pr;

MDR_jsonPathV

        ///===============================================================================
        // MDR_jsonPathV
        //
        // Retrieve a string representation of a given JSON path. Output to string.
        //
        // MDR_jsonPathU: Same as above, but output is uppercase
        // MDR_jsonPathL: Save as above, but output is lowercase
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //   @param (input) path = character string representing a JSON path
        //   @param (input/optional) isNull = Returns *ON if value is NULL, *OFF otherwise
        //                  (you may *OMIT isNull)
        //
        //   @return value (in string format) of the given JSON path
        // @info MDRFRAME7
        ///===============================================================================

        dcl-pr MDR_jsonPathV varchar(10240:4)
                             extproc(*cwiden:'MDR_jsonPathV')
                             rtnparm opdesc;
          handle      like(MDR_handle_t);
          path        varchar(2048:4) const options(*varsize);
          isNull      ind options(*omit:*nopass);
        end-pr;

MDR_jsonPathU

        ///===============================================================================
        // MDR_jsonPathU
        //
        // Retrieve a string representation of a given JSON path. Output to string in
        // upper case.
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //   @param (input) path = character string representing a JSON path
        //   @param (input/optional) isNull = Returns *ON if value is NULL, *OFF otherwise
        //                  (you may *OMIT isNull)
        //
        //   @return value (in upper case string format) of the given JSON path
        // @info MDRFRAME7
        ///===============================================================================

        dcl-pr MDR_jsonPathU varchar(10240:4)
                             extproc(*cwiden:'MDR_jsonPathU')
                             rtnparm opdesc;
          handle      like(MDR_handle_t);
          path        varchar(2048:4) const options(*varsize);
          isNull      ind options(*omit:*nopass);
        end-pr;

MDR_jsonPathL

        ///===============================================================================
        // MDR_jsonPathL
        //
        // Retrieve a string representation of a given JSON path. Output to string in
        // lower case.
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //   @param (input) path = character string representing a JSON path
        //   @param (input/optional) isNull = Returns *ON if value is NULL, *OFF otherwise
        //                  (you may *OMIT isNull)
        //
        //   @return value (in lower case string format) of the given JSON path
        // @info MDRFRAME7
        ///===============================================================================

        dcl-pr MDR_jsonPathL varchar(10240:4)
                             extproc(*cwiden:'MDR_jsonPathL')
                             rtnparm opdesc;
          handle      like(MDR_handle_t);
          path        varchar(2048:4) const options(*varsize);
          isNull      ind options(*omit:*nopass);
        end-pr;

MDR_jsonPathN

        ///===============================================================================
        // MDR_jsonPathN
        //
        // Retrieve the numeric representation of a given JSON path.
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //   @param (input) path = character string representing a JSON path
        //   @param (input/optional) isNull = Returns *ON if value is NULL, *OFF otherwise
        //                  (you may *OMIT isNull)
        //
        //   @return the numeric representation as packed(30: 9)
        //           or 0 if it cannot be represented as a number
        // @info MDRFRAME7
        ///===============================================================================

        dcl-pr MDR_jsonPathN packed(30: 9)
                             extproc(*cwiden:'MDR_jsonPathN') opdesc;
          handle      like(MDR_handle_t);
          path        varchar(2048:4) const options(*varsize);
          isNull      ind options(*omit:*nopass);
        end-pr;

MDR_jsonPathF

        ///===============================================================================
        // MDR_jsonPathF
        //
        // Retrieve a numeric representation of a given JSON path in floating point format
        //
        //
        //   @param (input) handle = context handle, identifies which MDRest4i session is
        //                  currently running.
        //   @param (input) path = character string representing a JSON path
        //   @param (input/optional) isNull = Returns *ON if value is NULL, *OFF otherwise
        //                  (you may *OMIT isNull)
        //
        //   @return the numeric representation as float(8)
        //           or 0 if it cannot be represented as a number
        // @info MDRFRAME7
        ///===============================================================================

        dcl-pr MDR_jsonPathF float(8)
                             extproc(*cwiden:'MDR_jsonPathF') opdesc;
          handle      like(MDR_handle_t);
          path        varchar(2048:4) const options(*varsize);
          isNull      ind options(*omit:*nopass);
        end-pr;

MDR_getArraySize

        ///===============================================================================
        // MDR_getArraySize
        //
        // Returns the number of elements in a JSON array given the path to the array
        // element.
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //   @param (input) path   = path to the JSON array node (can be CHAR, CHARZ or
        //                  VARCHAR4)
        //                  - if this is empty/blank/omitted the root node is assumed.
        //
        //   @return the number of array elements, or -1 upon error
        // @info MDRFRAME7
        ///===============================================================================

        dcl-pr MDR_getArraySize int(10)
                                extproc(*cwiden:'MDR_getArraySize')
                                opdesc;
          handle      like(MDR_handle_t);
          path        varchar(2048:4) const options(*varsize:*omit);
        end-pr;

MDR_jsonPathZ

        ///===============================================================================
        // MDR_jsonPathZ
        //
        // This is like MDR_jsonPathV except that it returns a timestamp field. If the data
        // timestamp automatically. If it matches an RPG timestamp, that will be returned
        // instead.
        //
        //   @param (input) handle = context handle, identifies which MDRest4i
        //                  session is currently running.
        //   @param (input) path = character string representing a JSON path
        //   @param (input/optional) isNull = Returns *ON if value is NULL, *OFF otherwise
        //                  (you may *OMIT isNull)
        //
        //   @return value (in timestamp format) of the JSON data,
        //        or z'0001-01-01-00.00.00.000000' upon error.
        // @info MDRFRAME7
        ///===============================================================================

        dcl-pr MDR_jsonPathZ timestamp
               extproc(*cwiden:'MDR_jsonPathZ') opdesc;
          handle      like(MDR_handle_t);
          path        varchar(2048:4) const options(*varsize);
          isNull      ind options(*omit:*nopass);
        end-pr;

Attachment Functions

MDR_getPartCount

        ///===============================================================================
        // MDR_getPartCount
        //
        // Retrieves the number of parts in a multipart input document
        //
        //   @param (input) handle = handle provided by MDR_newClient or MDRAPI
        //
        //   @return the number of parts if successful, -1 upon failure
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_getPartCount int(10)
               extproc(*cwiden:'MDR_getPartCount') opdesc;
          handle like(MDR_Handle_t);
        end-pr;

MDR_getPartName

        ///===============================================================================
        // MDR_getPartName
        //
        // Retrieves the name of a part in a multi part input document
        //
        //   @param (input) handle = handle provided by MDR_newClient or MDRAPI
        //   @param (input) partNo = the part number to get the name of
        //
        //   @return the name
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_getPartName varchar(2048:4)
               extproc(*cwiden:'MDR_getPartName') rtnparm opdesc;
          handle like(MDR_Handle_t);
          partNo int(10) const;
        end-pr;

MDR_getPartFileName

        ///===============================================================================
        // MDR_getPartFileName
        //
        // Retrieves the filename of a part in a multipart input document
        //
        //   @param (input) handle = handle provided by MDR_newClient or MDRAPI
        //   @param (input) partNo = the part number to get the file name of
        //
        //   @return the filename
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_getPartFileName varchar(2048:4)
               extproc(*cwiden:'MDR_getPartFileName') rtnparm opdesc;
          handle like(MDR_Handle_t);
          partNo int(10) const;
        end-pr;

MDR_getPartType

        ///===============================================================================
        // MDR_getPartType
        //
        // Retrieves the content-type of a part in a multipart input document
        //
        //   @param (input) handle = handle provided by MDR_newClient or MDRAPI
        //   @param (input) partNo = the part number to get the type of
        //
        //   @return the content-type
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_getPartType varchar(2048:4)
               extproc(*cwiden:'MDR_getPartType') rtnparm opdesc;
          handle like(MDR_Handle_t);
          partNo int(10) const;
        end-pr;

MDR_getPartBuf

        ///===============================================================================
        // MDR_getPartBuf
        //
        // Copy attachment body to a memory buffer identified by a pointer
        //
        //   @param (input) handle = handle provided by MDR_newClient or MDRAPI
        //   @param (input) partNo = the part number to get the type of
        //   @param (output) buf = pointer to the memory buffer to store body in
        //   @param (input) size = size of the memory buffer
        //
        //   @return the length of data written to the memory buffer
        //           or -1 upon failure
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_getPartBuf int(20)
               extproc(*cwiden:'MDR_getPartBuf');
          handle like(MDR_Handle_t);
          partNo int(10) const;
          buf    pointer value;
          size   uns(20) const;
        end-pr;

MDR_getPart

        ///===============================================================================
        // MDR_getPart
        //
        // Copy attachment body to a variable
        //
        //   @param (input) handle = handle provided by MDR_newClient or MDRAPI
        //   @param (input) partNo = the part number to get the type of
        //   @param (output) var = character variable to store data into
        //
        //   @return the length of data written to the memory buffer
        //           or -1 upon failure
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_getPart int(20)
               extproc(*cwiden:'MDR_getPart') opdesc;
          handle like(MDR_Handle_t);
          partNo int(10) const;
          var    varchar(16000000:4) options(*varsize);
        end-pr;

    ///===============================================================================
    // Content-Transfer-Encoding values for multipart messages
    //
    //  MDR_CTE_NONE   - no content-transfer-encoding assigned
    //  MDR_CTE_BINARY - data should be interpreted as binary values
    //  MDR_CTE_8BIT   - data should be interpreted as 8-bit char
    //  MDR_CTE_BASE64 - data should be base64 encoded/decoded
    //
    ///===============================================================================

    dcl-c MDR_CTE_NONE 0;
    dcl-c MDR_CTE_BINARY 536870912;
    dcl-c MDR_CTE_8BIT   536870913;
    dcl-c MDR_CTE_BASE64 536870915;

MDR_addPart

        ///===============================================================================
        // MDR_addPart
        //
        // Add a new attachment to a multipart output
        //
        //   @param (input) handle = handle provided by MDR_newClient or MDRAPI
        //   @param (input) contentType = content-type of newly added part
        //   @param (input) xferEnc = content-transfer-encoding of part
        //   @param (input) attname = attachment filename sent over network
        //   @param (input) data = string representing the data to store in the
        //                  attachment.
        //   @param (input/output/optional) name = name of this message part.
        //
        //   @return the length of data written to the memory buffer
        //           or -1 upon failure
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_addPart int(10)
               extproc(*cwiden:'MDR_addPart') opdesc;
          handle like(MDR_Handle_t);
          contentType varchar(2048:4)     const options(*omit);
          xferEnc     int(10)             const options(*omit);
          attName     varchar(2048:4)     const options(*omit);
          data        varchar(16000000:4) const options(*varsize:*omit);
          name        varchar(2048:4)     const options(*varsize:*nopass:*omit);
        end-pr;

MDR_copyToClob

        ///===============================================================================
        // MDR_copyToClob
        //
        // Copies data from a VARCHAR(4) (or fixed-length char if called from Cobol or CL)
        // to a DB2 CLOB field.
        //
        //   @param (output) dstClob = the clob to copy to
        //   @param (input) srcData = the source VARCHAR4 string.
        //   @param (input) size = the %SIZE of the CLOB column
        // @info MDRFRAME5
        ///===============================================================================

        dcl-pr MDR_copyToClob extproc(*cwiden:'MDR_copyToClob') opdesc;
          dstClob char(16000000)            options(*varsize);
      /if defined(*V7R2M0)
          srcData varchar(16000000:4) const options(*varsize) ccsid(*utf8);
      /else
          srcData varchar(16000000:4) const options(*varsize);
      /endif
          size    uns(10)             const;
        end-pr;

IFS Functions

MDRF_dirname

        ///===============================================================================
        // MDRF_dirname
        //
        // Extract the directory portion of a path. For example, if the path
        // is /one/two/three, "/one/two" would be the directory portion.
        //
        //
        //   @param (input) path = name to extract the directory from
        //
        //   @return the directory, or '' upon error
        // @info MDRFRAME12
        ///===============================================================================

        dcl-pr MDRF_dirname varchar(5000:4) rtnparm
               extproc(*cwiden:'MDRF_dirname') opdesc;
          path varchar(5000:4) const options(*varsize);
        end-pr;

MDRF_basename

        ///===============================================================================
        // MDRF_basename
        //
        // Extract the base (object name) portion of a path. For example if the path is
        // /one/two/three, the base is "three"
        //
        //   @param (input) path = name to extract the base name from
        //
        //   @return the base name, or '' upon error
        // @info MDRFRAME12
        ///===============================================================================

        dcl-pr MDRF_basename varchar(5000:4) rtnparm
               extproc(*cwiden:'MDRF_basename') opdesc;
          path varchar(5000:4) const options(*varsize);
        end-pr;

MDRF_exists

        ///===============================================================================
        // MDRF_exists
        //
        // check if an object exists in the IFS
        //
        //  @param (input) path = name of object to check
        //
        //  @return '1' if it exists or '0' otherwise
        // @info MDRFRAME12
        ///===============================================================================

        dcl-pr MDRF_exists ind
               extproc(*cwiden:'MDRF_exists') opdesc;
          path varchar(5000:4) const options(*varsize);
        end-pr;

MDRF_mkdir

        ///===============================================================================
        // MDRF_mkdir
        //
        // Create a new directory ("folder")
        //
        //   @param (input) path = name of directory to create
        //   @param (input/optional) opts = options to control how directory is created
        //
        //      Options are a space-separated name=value listing. For
        //      example they could be "owner=rwx group=rx public=x"
        //
        //      options are:
        //      owner=rwx  - owner permissions
        //      group=rwx  - group permissions
        //      public=rwx  - public permissions
        //      rstdrnmunl=Y/N  - enable restricted ren/unlink support
        //      intermed=Y/N  - should intermediate directories be created if they are,
        //                    they will be given rwxrwxrwx permissions
        //                    (modified by the umask.)
        //
        //   @return '1' if successful (or exists) and '0' otherwise
        // @info MDRFRAME12
        ///===============================================================================

        dcl-pr MDRF_mkdir ind
               extproc(*cwiden:'MDRF_mkdir') opdesc;
          path varchar(5000:4) const options(*varsize);
          opts varchar(256: 4) const options(*varsize:*omit:*nopass);
        end-pr;

MDRF_rmdir

        ///===============================================================================
        // MDRF_rmdir
        //
        // Remove/delete a directory (optionally including its contents)
        //
        //   @param (input) path = name of directory to delete
        //   @param (input/optional) subtree = *ON to delete any contents, or *OFF only
        //                           remove directory if empty.
        //
        //   @return 0 for success, -1 for error
        // @info MDRFRAME12
        ///===============================================================================

        dcl-pr MDRF_rmdir int(10)
               extproc(*cwiden:'MDRF_rmdir') opdesc;
          path    varchar(5000:4) const options(*varsize);
          subtree ind const options(*omit:*nopass);
        end-pr;

MDRF_delete

        ///===============================================================================
        // MDRF_delete
        //
        // Delete a file or other non-directory object
        //
        //  @param (input) path name of object to delete
        //
        // @return 0 for success, -1 for error
        // @info MDRFRAME12
        ///===============================================================================

        dcl-pr MDRF_delete int(10)
               extproc(*cwiden:'MDRF_delete') opdesc;
          path    varchar(5000:4) const options(*varsize);
        end-pr;

MDRF_open

        ///===============================================================================
        // MDRF_open
        //
        // Open a stream (IFS) file
        //
        //   @param (input) path = IFS path of the file to open
        //   @param (input/optional) opts = options string
        //   @param (output/optional) errmsg = error message
        //
        // OPTIONS STRING
        //   Format is XXXX, prop=val prop=val prop=val
        //
        //  XXXX = flags.  R=read, W=write, A=append, B=binary, N=create new
        //  prop=val = list of space-separated property=value options
        //
        //  owner=permissions (rwx, rw, rx, wx, w, x)
        //  group=permissions (rwx, rw, rx, wx, w, x)
        //  public=permissions (rwx, rw, rx, wx, w, x)
        //       (default if none of the permissions set = inherit from directory)
        //  intermediate=Y/N should intermediate directories be created
        //       (short form intermed=Y/N or int=Y/N also works)
        //  ccsid=XXXX the CCSID of the file when creating
        //       (default = 1208 aka UTF-8)
        //       (fileccsid is an alias for ccsid)
        //  pgmccsid=XXXX the CCSID of the data in your program
        //       (default = job ccsid. localccsid is an alias for pgmccsid)
        //  buffersize=XXXX the size of the internal read buffer used by
        //       the file access routines.
        //       (default=65536 -- aka 64k)
        //  eol=XXX end of line sequence. crlf, cr, lf or a 1 or 2 byte hex code
        //       (default=CRLF, for UTF-8 use eol=0d0a for unix use eol=lf or eol=0a)
        //  replace=Y/N, if opening with W=write or N=new, replace an existing
        //       file if found.
        //
        //  example: fh = MDRF_open('/path/to/file'
        //                         : 'N,ccsid=819 owner=RW group=RW public=R'
        //                         : err );
        //
        //   @return a handle to the open file
        //           or NULL upon error (and errmsg is set)
        // @info MDRFRAME12
        ///===============================================================================

        dcl-pr MDRF_open pointer
               extproc(*cwiden:'MDRF_open') opdesc;
          path   varchar(5000:4)  const options(*varsize);
          opts   varchar(500: 4)  const options(*varsize: *nopass: *omit);
          errmsg varchar(32767:4) options(*varsize: *nopass: *omit);
        end-pr;

MDRF_read

        ///===============================================================================
        // MDRF_read
        //
        // Read data from a stream (IFS) file
        //
        //   @param (input) handle = file handle returned by MDR_open
        //   @param (output) buf = buffer to read data into
        //
        //   @return the length of the data read or -1 upon failure
        // @info MDRFRAME12
        ///===============================================================================

        dcl-pr MDRF_read int(10)
               extproc(*cwiden:'MDRF_read') opdesc;
          handle pointer value;
          buf    varchar(16000000: 4) options(*varsize) ccsid(*hex);
        end-pr;

MDRF_len_read

        ///===============================================================================
        // MDRF_len_read
        //
        // Same as MDRF_read, except reads into pointer/length
        //
        //   @param (input) handle = file handle returned by MDR_open
        //   @param (output) buf = pointer to buffer to read data into
        //   @param (input) bufsiz = space available in buffer
        //
        //   @return the length of the data read or -1 upon failure
        // @info MDRFRAME12
        ///===============================================================================

        dcl-pr MDRF_len_read int(10)
               extproc(*cwiden:'MDRF_len_read') opdesc;
          handle pointer value;
          buf    pointer value;
          bufsiz uns(10) value;
        end-pr;

MDRF_readln

        ///===============================================================================
        // MDRF_readln
        //
        // Read a line of text from a stream (IFS) file
        //
        //   @param (input) handle = file handle returned by MDR_open
        //   @param (output) line = variable to read the line into
        //
        //   @return the length of the data read or -1 upon failure
        // @info MDRFRAME12
        ///===============================================================================

        dcl-pr MDRF_readln int(10)
               extproc(*cwiden:'MDRF_readln') opdesc;
          handle pointer value;
          line   varchar(16000000: 4) options(*varsize) ccsid(*hex);
        end-pr;

MDRF_len_readln

        ///===============================================================================
        // MDRF_len_readln
        //
        // Same as MDRF_readln except it reads into a buffer addressed via a pointer
        // and length
        //
        //   @param (input) handle = file handle returned by MDR_open
        //   @param (output) linebuf = pointer to buffer to read line into
        //   @param (input) bufsiz = space available in buffer
        //
        //   @return the length of the data read or -1 upon failure
        // @info MDRFRAME12
        ///===============================================================================

        dcl-pr MDRF_len_readln int(10)
               extproc(*cwiden:'MDRF_len_readln') opdesc;
          handle  pointer value;
          linebuf pointer value;
          bufsiz  uns(10) value;
        end-pr;

MDRF_write

        ///===============================================================================
        // MDRF_write
        //
        // Write data to a stream (IFS) file
        //
        //   @param (input) handle = file handle returned by MDR_open
        //   @param (input) data = variable containing data to be written
        //
        //   @return the length of the data written or 0 upon failure
        // @info MDRFRAME12
        ///===============================================================================

        dcl-pr MDRF_write int(10)
               extproc(*cwiden:'MDRF_write') opdesc;
          handle pointer value;
          data   varchar(16000000: 4) const options(*varsize) ccsid(*hex);
        end-pr;

MDRF_len_write

        ///===============================================================================
        // MDRF_len_write
        //
        // Same as MDRF_write except data is written from a pointer/length
        //
        //   @param (input) handle = file handle returned by MDR_open
        //   @param (input) buffer = pointer to buffer containing data to write
        //   @param (input) length = length of data to write from the buffer
        //
        //   @return the length of the data written or 0 upon failure
        // @info MDRFRAME12
        ///===============================================================================

        dcl-pr MDRF_len_write int(10)
               extproc(*cwiden:'MDRF_len_write') opdesc;
          handle pointer value;
          buffer pointer value;
          length uns(10) value;
        end-pr;

MDRF_writeln

        ///===============================================================================
        // MDRF_writeln
        //
        // Write data to a stream (IFS) file as a series of lines
        //
        //   @param (input) handle = file handle returned by MDR_open
        //   @param (input) line = data to be written to disk. An EOL sequence
        //                  (as set on MDRF_open) will be appended to the data.
        //
        //   @return the length of the line written or 0 upon failure
        // @info MDRFRAME12
        ///===============================================================================

        dcl-pr MDRF_writeln int(10)
               extproc(*cwiden:'MDRF_writeln') opdesc;
          handle pointer value;
          line   varchar(16000000: 4) const options(*varsize) ccsid(*hex);
        end-pr;

MDRF_len_writeln

        ///===============================================================================
        // MDRF_len_writeln
        //
        // Same a MDRF_writeln except data is written from a pointer/length
        //
        //   @param (input) handle = file handle returned by MDR_open
        //   @param (input) buffer = pointer to buffer containing the data to be written to disk.
        //                   An EOL sequence (as set on MDRF_open) will be appended to
        //                   the data.
        //   @param (input) length = length of buffer (in bytes)
        //
        //   @return the length of the line written or 0 upon failure
        // @info MDRFRAME12
        ///===============================================================================

        dcl-pr MDRF_len_writeln int(10)
               extproc(*cwiden:'MDRF_len_writeln') opdesc;
          handle pointer value;
          buffer pointer value;
          length uns(10) value;
        end-pr;

MDRF_close

        ///===============================================================================
        // MDRF_close
        //
        // Close a file that was opened by MDR_open
        //
        //   @param (input) handle = file handle returned by MDR_open
        //
        //   @return 0 if the file was successfully closed -1 otherwise
        // @info MDRFRAME12
        ///===============================================================================

        dcl-pr MDRF_close int(10)
               extproc(*cwiden:'MDRF_close') opdesc;
          handle pointer value;
        end-pr;

MDRF_objInfo_t

        ///===============================================================================
        // MDRF_objInfo_t
        //  Structure for information about an object in a directory
        //
        //             mode = file mode (flags identifying auths, etc)
        //              uid = numeric userid
        //              gid = numeric group id
        //            ccsid = ccsid of the data in the file
        //      isDirectory = *ON means its a directory, *OFF otherwise
        //           isFile = *ON means its a regular obj, *OFF otherwise
        //             size = size of the data in the file (bytes)
        //        allocSize = amount of disk space reserved for file
        //                     (in bytes)
        //     timeAccessed = the last time the file was accessed (in any
        //                     manner, including read-only)
        //   timeAttrChange = the last time the file's attributes were
        //                     changed (file name, permissions, ccsid, etc)
        //   timeDataChange = the last time the data in the file was
        //                     changed.
        //          objType = IBM i object type
        //            owner = owning user profile name
        //            group = assigned group profile name
        ///===============================================================================

        dcl-ds MDRF_objInfo_t qualified template;
          mode           uns(10);
          uid            uns(10);
          gid            uns(10);
          ccsid          uns(5);
          isDirectory    ind;
          isFile         ind;
          size           uns(20);
          allocSize      uns(20);
          timeAccessed   timestamp;
          timeAttrChange timestamp;
          timeDataChange timestamp;
          timeCreated    timestamp;
          objType        char(10);
          owner          char(10);
          group          char(10);
        end-ds;

MDRF_openDir

        ///===============================================================================
        // MDRF_openDir
        //
        // Open a directory so you can read the files within it
        //
        //   @param (input) path = path name to directory to open
        //   @param (input/optional) pattern = pattern of filenames to return, this
        //                           allows for *, ? or [a-z] wildcards.
        //                           Default = return all filenames
        //
        //   @return a handle to an open directory. It can be read with MDRF_readDir,
        //           and must be closed with MDRF_closeDir.
        //           or *NULL upon error
        // @info MDRFRAME12
        ///===============================================================================

        dcl-pr MDRF_openDir pointer
               extproc(*cwiden:'MDRF_openDir') opdesc;
          path    varchar(5000:4) const options(*varsize);
          pattern varchar(5000:4) const options(*varsize: *omit: *nopass);
        end-pr;

MDRF_readDir

        ///===============================================================================
        // MDRF_readDir
        //
        // Read the next filename from a directory (previously opened with MDRF_openDir)
        //
        //   @param (input) dirh = handle to the open directory
        //   @param (output) filename = filename returned
        //   @param (output/optional) fileinfo = information about the returned file.
        //
        // NOTE: Gathering the object information takes extra time,
        //       so don't pass the 3rd parameter if you don't need it.
        //
        // @return *ON is returned to indicate that a filename was read
        //         or *OFF is returned to indicate that all files in the
        //         directory (that match your pattern) have been read.
        // @info MDRFRAME12
        ///===============================================================================

        dcl-pr MDRF_readDir ind
               extproc(*cwiden:'MDRF_readDir') opdesc;
          dirh     pointer         const;
          filename varchar(5000:4) options(*varsize);
          fileinfo likeds(MDRF_objInfo_t) options(*nopass: *omit);
        end-pr;

MDRF_closeDir

        ///===============================================================================
        // MDRF_closeDir
        //
        // Close an open directory handle (that was opened with MDRF_open)
        //
        //   @param (input) dirh = directory handle to close
        // @info MDRFRAME12
        ///===============================================================================

        dcl-pr MDRF_closeDir
               extproc(*cwiden:'MDRF_closeDir');
          dirh     pointer         value;
        end-pr;

MDRF_len_readAll

        ///===============================================================================
        // MDRF_len_readAll
        //
        // Read the entire contents of a file into a buffer
        //
        //   @param (input) path = pathname to file to read from
        //   @param (output) buf = buffer to place file data into
        //   @param (input) bufsize = size of buf
        //   @param (output) errmsg = buffer to place an error message into
        //   @param (input) errsize = size of errmsg
        //
        //   @return the number of bytes read from the file
        //           or -1 upon error (with errmsg set)
        // @info MDRFRAME12
        ///===============================================================================

        dcl-pr MDRF_len_readAll int(20)
               extproc(*cwiden:'MDRF_len_readAll');
          path    pointer value options(*string);
          buf     pointer value;
          bufsize uns(20) value;
          errmsg  pointer value;
          errsize uns(10) value;
        end-pr;

MDRF_readAll

        ///===============================================================================
        // MDRF_readAll
        //
        // Read the entire contents of a file into a string
        //
        //   @param (input) path = pathname to file to read from
        //   @param (output) string = string to place file contents into
        //   @param (output/optional) errmsg = string to place error message into
        //
        //   @return the number of bytes read from the file
        //           or -1 upon error (with errmsg set)
        // @info MDRFRAME12
        ///===============================================================================

        dcl-pr MDRF_readAll int(20)
               extproc(*cwiden:'MDRF_readAll') opdesc;
          path    varchar(5000:4)     options(*varsize) const;
          string  varchar(16000000:4) options(*varsize);
          errmsg  varchar(1000:4)     options(*varsize:*omit:*nopass);
        end-pr;

MDRF_len_writeAll

        ///===============================================================================
        // MDRF_len_writeAll
        //
        // Write an entire file from one buffer
        //
        //   @param (input) path = pathname to file to write to
        //   @param (input) buf = buffer to write file data from
        //   @param (input) bufsize = length of data in buf to write
        //   @param (output) errmsg = buffer to place an error message into
        //   @param (input) errsize = size of errmsg
        //
        //   @return the number of bytes written to the file
        //           or -1 upon error (with errmsg set)
        // @info MDRFRAME12
        ///===============================================================================

        dcl-pr MDRF_len_writeAll int(20)
               extproc(*cwiden:'MDRF_len_writeAll');
          path    pointer value options(*string);
          buf     pointer value;
          bufsize uns(20) value;
          errmsg  pointer value;
          errsize uns(10) value;
        end-pr;

MDRF_writeAll

        ///===============================================================================
        // MDRF_writeAll
        //
        // Write an entire file from one string. If the file already
        // exists, its contents are replaced.
        //
        //  @param (input) path = pathname to file to write to
        //  @param (input) buf = string to write file data from
        //  @param (output/optional) errmsg buffer to place an error message into
        //
        // @return the number of bytes written to the file
        //     or -1 upon error (with errmsg set)
        // @info MDRFRAME12
        ///===============================================================================

        dcl-pr MDRF_writeAll int(20)
               extproc(*cwiden:'MDRF_writeAll') opdesc;
          path    varchar(5000:4)     options(*varsize) const;
          buf     varchar(16000000:4) options(*varsize) const;
          errmsg  varchar(1000:4)     options(*varsize:*omit:*nopass);
        end-pr;

MDR_path2obj

        ///===============================================================================
        // MDR_path2obj
        //
        // Given an IFS-style path name, calculate the system library, object, member,
        // IASP, etc.
        //
        //   @param (input) inpath = ifs-style path name
        //   @param (output) qsysobj = MDR_sysobj_t structure containing the system names.
        //                   If the resulting object is an IFS-only object, the isStmf
        //                   indicator will be on. Otherwise, the member, object, library
        //                   and iasp will be set.  the Path is always set.
        //
        //   @return 1 if the output is a stream file, or 0 if it is a library/obj.
        //
        // EXAMPLE: (RPG)
        //   dcl-s  path varchar(5000) inz('/qsys.lib/qgpl.lib/proof.pgm);
        //   dcl-ds sys  likeds(MDR_sysobj_t);
        //
        //   if MDRSDK_path2Obj(path: sys) = 1;
        //     cmd = 'CALL PGM(' + %trim(sys.library)
        //         + '/' + %trim(sys.object) + ')';
        //     QCMDEXC(cmd: %len(cmd));
        //   endif;
        // @info MDRFRAME5
        ///===============================================================================


        dcl-pr MDR_path2obj int(10)
               extproc(*cwiden:'MDR_path2obj') opdesc;
          path    varchar(5000:4) const options(*varsize);
          qsysobj likeds(MDR_sysobj_t);
        end-pr;

MDR_sysobj_t

        ///===============================================================================
        // The data structure used by MDR_path2obj and MDR_path2src to format the
        // IBMi object name from IFS path format to library naming
        //
        // isStmf= *On = path is an IFS stream file
        // path = IFS format path of IBMi object
        // member = source member name
        // object = object name
        // library = library name
        // iasp = IASP name
        ///===============================================================================
        dcl-ds MDR_sysobj_t qualified template;
          isStmf  ind;
          path    char(5000);
          member  char(10);
          object  char(10);
          library char(10);
          iasp    char(10);
        end-ds;

Advanced Consumer Functions

    ///===============================================================================
    // Note: This section is for more advanced usage and
    //      will not be included in the customer program
    //      unless they define MDR_ADVANCED_OPTIONS
    ///===============================================================================

  /if defined(MDR_ADVANCED_OPTIONS)

    dcl-c MAX_HEADERS   100;
    dcl-c MAX_PATHVARS  100;
    dcl-c MAX_QUERYVARS 100;
    dcl-c MAX_COOKIES   100;
        ///===============================================================================
        // This is the structure where incoming HTTP headers
        // are stored inside the request.
        //
        // count = number of headers
        // header(x).name = name of header
        // header(x).value = value of header
        //
        // Note: Cookies are not provided in the header list.
        ///===============================================================================

        dcl-ds MDR_RPG_Headers_t qualified template;
          count uns(10) inz(0);
          dcl-ds header dim(MAX_HEADERS);
            name  varchar(200);
            *n    char(1) inz(x'00');
            value varchar(2048);
            *n    char(1) inz(x'00');
          end-ds;

    end-ds;

pathvar

        ///===============================================================================
        // This is the structure where path variables are
        // stored inside the request.
        //
        // count = number of path vars
        // pathvar(x).value = value of path
        //
        // Note: Path parts are relative to MDRAPI, so
        //       pathvar(1).value is always 'mdrapi'
        //       pathvar(2).value is always 'api-name'
        //
        // typically customers will use 3+ for their own
        // data. For example:
        //    http://server:port/mdrapi/customer/1
        //
        //  pathvar(1).value = 'mdrpapi'
        //  pathvar(2).value = 'customer'
        //  parmvar(3).value = '1'
        ///===============================================================================

        dcl-ds MDR_RPG_PathVars_t qualified template inz;
          count uns(10) inz(0);
          dcl-ds pathvar dim(MAX_PATHVARS);
            value varchar(2048);
            *n    char(1) inz(x'00');
          end-ds;

    end-ds;
        ///===============================================================================
        // This is the structure where cookies are
        // stored inside the request.
        //
        // count = number of cookies
        // cookie(x).name  = name of the cookie
        // cookie(x).value = value of the cookie
        ///===============================================================================

        dcl-ds MDR_RPG_Cookies_t qualified template inz;
          count uns(10) inz(0);
          dcl-ds cookie dim(MAX_COOKIES);
            name  varchar(200);
            *n    char(1) inz(x'00');
            value varchar(2048);
            *n    char(1) inz(x'00');
          end-ds;

    end-ds;

queryvar

        ///===============================================================================
        // This is the structure where query string variables
        // are stored inside the request.
        //
        // count = number of variables
        // queryvar(x).name  = name of the variable
        // queryvar(x).value = value of the variable
        ///===============================================================================

        dcl-ds MDR_RPG_QueryVars_t qualified template inz;
          count uns(10) inz(0);
          dcl-ds queryvar dim(MAX_QUERYVARS);
            name  varchar(200);
            *n    char(1) inz(x'00');
            value varchar(2048) inz(x'00');
            *n    char(1);
          end-ds;

    end-ds;

MDR_httpBody_t

        ///===============================================================================
        // This is how MDRFRAME internatlly stores the HTTP
        // request body. I don't expect that it would typically
        // be used by customers -- but it is here if needed.
        //
        // size   = amount of memory allocated for the body
        // ccsid  = CCSID that the body data is stored in
        // length = length of the data in the body
        // buffer = data in the body.
        //
        // Note that the HTTP body is allocated in teraspace
        // and can be as large as 4 GB. (We may expand this to
        // to 2 TB if ever needed.)  To access the full data,
        // when this exceeds 16 MB, you'll need to use pointers
        // instead of the 'buffer' variable.
        ///===============================================================================

        dcl-ds MDR_httpBody_t qualified template;
          size     int(20) inz(0);
          ccsid    uns(5)  inz(0);
          *n       char(6) inz(*ALLx'00');
          length   int(20) inz(0);
      /if defined(*V7R2M0)
          buffer   char(16000000) ccsid(*utf8);
      /else
          buffer   char(16000000);
      /endif
        end-ds;

MDR_Error_t

        ///===============================================================================
        // This is how MDRFRAME internally stores error messages.
        //
        //         id = null-terminated msgid.
        //  statement = null-terminated statement number
        //       text = null-terminated error message text
        //        sev = message severity
        ///===============================================================================

        dcl-ds MDR_Error_t qualified align(*full) template;
          id         char(8);
          statement  char(11);
          text       char(32768);
          sev        int(10);
        end-ds;

MDR_logOpts_t

        ///===============================================================================
        // Details of which parts of the requests are logged
        //
        //    reqHdr = 1=log request header, 0=dont
        //    reqUri = 1=log request URI, 0=dont
        //   reqBody = 1=log request body, 0=dont
        //   respHdr = 1=log response header, 0=dont
        //  respBody = 1=log response body, 0=dont
        ///===============================================================================

        dcl-ds MDR_logOpts_t qualified align(*full) template;
          reqHdr int(10);
          reqUri int(10);
          reqBody int(10);
          respHdr int(10);
          respBody int(10);
        end-ds;

MDR_Request_t

        ///===============================================================================
        // MDR_Request_t: This is the internal data structure that
        //                MDRest4i stores data about the current request
        //                (or transaction) in.
        //
        //         headers = structure containing the header information
        //         cookies = structure containing the cookie information
        //       queryvars = structure containing the query variable info
        //        pathvars = structure containing the path variable info
        // outgoing_headers = The headers to use on output
        // outgoing_cookies = The cookies to use on output
        //         request = teraspace pointer to the HTTP body of
        //                   the input. (see MDR_httpBody_t)
        //        response = teraspace pointer to the HTTP body of the
        //                   the output. (see MDR_httpBody_t)
        //     contentType = pointer to C-style string containing the
        //                   content type received from the caller
        //          method = pointer to C-style string containing the
        //                   HTTP method
        //             uri = pointer to C-style string containing the URI
        //         utf2job = code for mapping network/job CCSIDs
        //        in_multi = multipart document for input
        //       out_multi = multipart document for output
        //          status = the HTTP status code to return
        //         isHTTPS = 1 if using SSL/TLS, or 0 otherwise
        //          format = format that MDRest4i is using for this
        //                   transaction. See the MDR_FORMAT_xxx
        //                   constants.
        //          binary = 1 if the Apache server called us in binary
        //                   mode, 0 otherwise.
        //           error = the last error that occurred in the framework
        ///===============================================================================

        dcl-ds MDR_Request_t qualified template inz align(*full);
          headers          likeds(MDR_RPG_Headers_t);
          cookies          likeds(MDR_RPG_Cookies_t);
          queryvars        likeds(MDR_RPG_QueryVars_t);
          pathvars         likeds(MDR_RPG_PathVars_t);
          outgoing_headers likeds(MDR_RPG_Headers_t);
          outgoing_cookies likeds(MDR_RPG_Cookies_t);
          request          pointer;
          response         pointer;
          contentType      pointer;
          method           pointer;
          uri              pointer;
          utf2job          pointer;
          in_multi         pointer;
          out_multi        pointer;
          status           int(10);
          isHTTPS          int(10);
          format           int(10);
          binary           int(10);
          error            likeds(MDR_Error_t);
          logOpts          likeds(MDR_logOpts_t);
        end-ds;

MDR_getRequest

        ///===============================================================================
        // MDR_getRequest
        //
        // This retrieves the (internal) request structure that the MDRest4i framework
        // uses to store information about this transaction.
        //
        //   @param (input) handle = context handle, identifies which MDRest4i session
        //                  is currently running.
        //   @param (input) request = returns a pointer to the request structure which
        //                  should be in the format of MDR_Request_t, above.
        //
        //   @return 0 always
        //
        // Example:
        //   dcl-ds req likeds(MDR_Request_t) based(p_req);
        //   MDR_getRequest(p_req);
        //
        //   if req.format = MDR_FORMAT_XML;
        //      xml-specific code here.
        //   endif;
        // @info MDRFRAME
        ///===============================================================================

        dcl-pr MDR_getRequest int(10) extproc(*cwiden: 'MDR_getRequest');
          handle  like(MDR_handle_t);
          request pointer;
        end-pr;
      /endif