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_b64_decode()

Decode string in Base64Url format. Base64Url differs slightly from base64 in order to remove any characters that have a special meaning in a URL, including the +, / and = characters that are normally found in base64.

JWT uses Base64Url instead of standard base64

Type Name IO Description
@param dst output destination (decoded) string
@param src input source (encoded) string
@return return 0 if successful, -1 otherwise
@info MDRFRAME7
ProtoType
dcl-pr MDR_b64url_decode int(10)
                         extproc(*cwiden:'MDR_b64url_decode') opdesc;
  dst varchar(5000000:4) options(*varsize) ccsid(*hex);
  src varchar(5000000:4) const options(*varsize);
end-pr;

MDR_b64_decode(): Decode string in base64 format

Type Name IO Description
@param dst output destination (decoded) string
@param src input source (encoded) string
@return return 0 if successful, -1 otherwise
@info MDRFRAME7
ProtoType
dcl-pr MDR_b64_decode int(10) extproc(*cwiden:'MDR_b64_decode') opdesc;
  dst varchar(5000000:4) options(*varsize) ccsid(*hex);
  src varchar(5000000:4) const options(*varsize);
end-pr;

MDR_b64_encode

Encode string in base64 format

Type Name IO Description
@param dst output destination (encoded) string
@param src input source (not encoded) string
@return return 0 if successful, -1 otherwise
@info MDRFRAME7
ProtoType
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_b64url_encode

Encode string in Base64Url format. Base64Url differs slightly from base64 in order to remove any characters that have a special meaning in a URL, including the +, / and = characters that are normally found in base64.

JWT uses Base64Url instead of standard base64

Type Name IO Description
@param dst output destination (encoded) string
@param src input source (not encoded) string
@return return 0 if successful, -1 otherwise
@info MDRFRAME7
ProtoType
dcl-pr MDR_b64url_encode int(10)
                         extproc(*cwiden:'MDR_b64url_encode') opdesc;
  dst varchar(5000000:4) options(*varsize);
  src varchar(5000000:4) const options(*varsize) ccsid(*hex);
end-pr;

MDR_chkObj

Check for a disk object (similar to CHKOBJ CL cmd)

Type Name IO Description
@param library input library to look in (or LIBL, CURLIB)
@param object input name of object
@param type input object type (PGM, FILE etc)
@param rtnLib input Returns the library where the object was found (pass *OMIT if you don't need this)
@return return 0 if object not found, 1 if it was found
@info MDRFRAME5
ProtoType
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_decode

URL-decode string

Type Name IO Description
@param handle input handle returned by MDR_newClient.
@param dst output destination (decoded) string
@param src input source (encoded) string
@info MDRFRAME8
ProtoType
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_encode

URL-encode string

Type Name IO Description
@param handle input handle returned by MDR_newClient.
@param dst output destination (encoded) string
@param src input source (not encoded) string
@info MDRFRAME8
ProtoType
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_getCookie

Retrieves the value of an HTTP cookie on input.

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param name input name of HTTP cookie to retrieve
@return return the value of the cookie or '*NOTFOUND' if you specify a cookie that does not exist
@info MDRFRAME

Example: session = MDR_getCookie(handle: 'SessionId');

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

MDR_getCookieCount

Returns the number of cookies in the current request

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@return return the number of cookies in current http request
@info MDRFRAME
ProtoType
dcl-pr MDR_getCookieCount packed(7: 0) extproc('MDR_getCookieCount');
  handle like(MDR_handle_t);
end-pr;

MDR_getCookieName

Returns the name of a cookie based on its ordinal position in the cookies array

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param pos input array position to retrieve
@return return the name of the cookie, or *NOTFOUND
@info MDRFRAME
ProtoType
dcl-pr MDR_getCookieName char(200) extproc('MDR_getCookieName');
  handle like(MDR_handle_t);
  pos    packed(7: 0) const;
end-pr;

MDR_getHeader

Retrieves the value of an HTTP header on input.

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param name input name of HTTP header to retrieve
@return return the value of the header. or '*NOTFOUND' if you specify a header that does not exist
@info MDRFRAME

Example:

agent = MDR_getHeader(handle: 'user-agent'); by thge way this doesnt work!!!

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

MDR_getHeaderCount

Returns the number of Custom headers only in the current request

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@return return the number of headers in current http request
@info MDRFRAME
ProtoType
dcl-pr MDR_getHeaderCount packed(7: 0) extproc('MDR_getHeaderCount');
  handle like(MDR_handle_t);
end-pr;

MDR_getHeaderName

Returns the name of a header based on its ordinal position in the headers array

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param pos input array position to retrieve
@return return the name of the header, or *NOTFOUND
@info MDRFRAME
ProtoType
dcl-pr MDR_getHeaderName char(200) extproc('MDR_getHeaderName');
  handle like(MDR_handle_t);
  pos    packed(7: 0) const;
end-pr;

MDR_getOutgoingCookie

Retrieves the value of an HTTP cookie in the response to an HTTP request

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param name input name of HTTP cookie to retrieve
@return return the value of the cookie or '*NOTFOUND' if you specify a cookie that does not exist
@info MDRFRAME

Example: session = MDR_getOutgoingCookie(handle: 'SessionId');

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

MDR_getOutgoingCookieCount

Returns the number of cookies in the current response

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@return return the number of cookies being returned in current http response
@info MDRFRAME
ProtoType
dcl-pr MDR_getOutgoingCookieCount packed(7: 0)
  extproc('MDR_getOutgoingCookieCount');
  handle like(MDR_handle_t);
end-pr;

MDR_getOutgoingCookieName

Returns the name of a cookie in the current response based on its ordinal position in the array

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param pos input array position to retrieve
@return return the name of the cookie, or *NOTFOUND
@info MDRFRAME
ProtoType
dcl-pr MDR_getOutgoingCookieName char(200)
  extproc('MDR_getOutgoingCookieName');
  handle like(MDR_handle_t);
  pos    packed(7: 0) const;
end-pr;

MDR_getOutgoingHeader

Retrieves the value of an HTTP header in the response to an HTTP request.

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param name input name of HTTP header to retrieve
@return return the value of the header. or '*NOTFOUND' if you specify a header that does not exist
@info MDRFRAME

Example: agent = MDR_getOutgoingHeader(handle: 'user-agent');

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

MDR_getOutgoingHeaderCount

Returns the number of headers in the current response

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@return return the number of headers being returned in current http response
@info MDRFRAME
ProtoType
dcl-pr MDR_getOutgoingHeaderCount packed(7: 0)
  extproc('MDR_getOutgoingHeaderCount');
  handle like(MDR_handle_t);
end-pr;

MDR_getOutgoingHeaderName

Returns the name of a header in the current response based on its ordinal position in the array

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param pos input array position to retrieve
@return return the name of the header, or *NOTFOUND
@info MDRFRAME
ProtoType
dcl-pr MDR_getOutgoingHeaderName char(200)
  extproc('MDR_getOutgoingHeaderName');
  handle like(MDR_handle_t);
  pos    packed(7: 0) const;
end-pr;

MDR_getQueryVarName

Returns the name of a query string variable based on its ordinal position in the query string array

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param pos input array position to retrieve
@return return the name of the query string variable, or *NOTFOUND
@info MDRFRAME
ProtoType
dcl-pr MDR_getQueryVarName char(200) extproc('MDR_getQueryVarName');
  handle like(MDR_handle_t);
  pos    packed(7: 0) const;
end-pr;

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_locationInfo

Provides root IFS folder and IFS folder to use. In SRVPGM MDRTOOLS

Type Name IO Description
@param **** output
@param **** output
@param **** output
ProtoType
dcl-pr MDR_locationInfo ExtPgm('MRLOCINF');
  library       char(10);
  rootIFSPath   char(20);
  instFolder    char(7);
end-pr;

MDR_readBodyFromFile

Read an HTTP request/response body from a stream (IFS) file.

Type Name IO Description
@param handle input handle provided by MDR_newClient or MDRAPI
@param body input MDR_BODY_REQUEST or MDR_BODY_RESPONSE
@param stmf input path to stream/ifs file to read from
@param errmsg output/optional variable to receive an error message if an error occurs. or *OMIT if not needed.
@return return 0 if successful, -1 upon failure
@info MDRFRAME
ProtoType
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;

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.

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param cookie input name of the cookie to set
@param value input value of the cookie to set
@info MDRFRAME
Example
SESSION_ID = '12345';
MDR_setCookie(handle: 'SessionId': SESSION_ID);
ProtoType
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_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

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param header input name of the header to set
@param value input value of the header to set
@info MDRFRAME
Example
MDR_setHeader( handle
: 'content-type':
: 'application/octet-stream');
ProtoType
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_translate

translates the input data from one CCSID to another

Type Name IO Description
@param **** input
@param **** input
@param **** input
@param **** input
@param **** input
@param **** input
@param **** input
@return return the length of the translated data or -1 upon error Note: When the value 0 is supplied in either "fromCCSID" or "toCCSID" it is taken as host CCSID value. When errorMsg is blank, that means whole input data has been translated, otherwise, error message explains the error
ProtoType
dcl-pr MDR_translate int(10);
  fromCCSID int(10);
  toCCSID int(10);
  inputData pointer;
  inputLen  int(10);
  targetData Pointer;
  targetLength int(10);
  errorMsg varchar(50);
end-pr;

MDR_writeBodyToFile

Write an HTTP request/response body to a stream (IFS) file.

Type Name IO Description
@param handle input handle provided by MDR_newClient or MDRAPI
@param body input MDR_BODY_REQUEST or MDR_BODY_RESPONSE
@param stmf input path to stream/ifs file to save to
@param errmsg output/optional variable to receive an error message if an error occurs. or *OMIT if not needed.
@return return 0 if successful, -1 upon failure
@info MDRFRAME
ProtoType
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;
Constants used for body parm
dcl-c MDR_BODY_REQUEST  9901;
dcl-c MDR_BODY_RESPONSE 9902;
Example
  // Variable used to hold IFS path for reading/saving response body
  dcl-s ifspath varchar(500:4);

  // Logic to write response body to IFS file
  ifspath = '/home/stuart/echohdr_resp.txt';
  MDR_writeBodyToFile(handle:MDR_BODY_REQUEST:ifsPath:errorMsg);

Provider-Functions

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.

  • 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.

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param error_id input the 7-character message ID to be reported to the caller.
@param error_text input 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 error_statement input statement number to report that the error occurred.
@param error_severity input severity of the error to be reported, typically should be 10 = Minor
@info MDRFRAME
ProtoType
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_freeHandle

Free the memory used by an MDRest4i session handle.

Type Name IO Description
@param handlePtr input pointer to a session handle created by MDR_newHandle that should be freed up.
@info MDRFRAME
ProtoType
dcl-pr MDR_freeHandle extproc(*cwiden:'MDR_freeHandle');
  handlePtr pointer value;
end-pr;

MDR_getAuth

Retrieves the authorization string provided from Authorisation request header (available in provider, only.)

Type Name IO Description
@param handle input/output handle provided by MDRAPI
@param type output/optional (output/optional) type of authentication used, BASIC, BEARER or DIGEST
@param user output/optional (output/optional) userid provided (blank for bearer)
@param token output/optional (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 return 0 if successful, -1 if there was no authorization header, or if the header was invalid.
@info MDRFRAME
ProtoType
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;

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.

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param key input value in path that result is relative to
@param position input 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 return the value of the path at that position, or '*NOTFOUND' if you specify a portion of the path that does not exist.
@info MDRFRAME
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
ProtoType
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

Returns the number of path components in the current request

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@return return the number of path parameter elements
@info MDRFRAME
ProtoType
dcl-pr MDR_getPathVarCount packed(7: 0) extproc('MDR_getPathVarCount');
  handle like(MDR_handle_t);
end-pr;

MDR_getQueryVar

Retrieve an input variable from the query string. The query string is the part of the URL that follows the ?.

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param name input name of query string variable to retrieve
@return return the value of the query string variable.
@info MDRFRAME
Example
URL is http://yourserver/mdrapi/customer/123?op=call

action = MDR_getQueryVar('op');

action will be set to 'call'
ProtoType
dcl-pr MDR_getQueryVar varchar(2048)
                       rtnparm
                       extproc(*cwiden:'MDR_RPG_getQueryVar');
  handle          like(MDR_handle_t);
  name            varchar(200) const;
end-pr;

MDR_getQueryVarCount

Returns the number of query string variables in the current request

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@return return the number of query parameters in current request
@info MDRFRAME
ProtoType
dcl-pr MDR_getQueryVarCount packed(7: 0)
  extproc('MDR_getQueryVarCount');
  handle like(MDR_handle_t);
end-pr;

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.

Type Name IO Description
@return return ON if in binary mode, OFF otherwise
@info MDRFRAME
Example
if MDR_isBinaryMode() = *OFF;
not in binary mode!  why?
endif;
ProtoType
dcl-pr MDR_isBinaryMode ind extproc(*cwiden: 'MDR_isBinaryMode');
end-pr;

MDR_isHTTPS

Detects whether this API was called using secure HTTPS. (aka SSL or TLS)

Type Name IO Description
@return return ON if in HTTPS mode, OFF for plain HTTP
@info MDRFRAME
Example
if MDR_isHTTPS() = *OFF;
MDR_setError( handle: 'ERR9999'
: 'This API requires SSL/TLS encryption!!'
: 1 : 20: : 0 );
return;
endif;
ProtoType
dcl-pr MDR_isHTTPS ind extproc(*cwiden: 'MDR_isHTTPS');
end-pr;

MDR_len_print

Same as MDR_print but with a pointer and length parameter.

Type Name IO Description
@param **** input
@param buf input pointer to buffer containing EBCDIC data
@param len input length of data in buffer.
@return return length of string appended to API output from the string buffer
@info MDRFRAME
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);
ProtoType
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_len_write

Same as MDR_write but with a separate length parameter.

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param buf input pointer to buffer containing UTF-8 encoded data
@param len input length of data in buffer.
@return return number of bytes added to the response header
@info MDRFRAME
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);
ProtoType
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_newHandle

Generate a new MDRest4i session handle

Type Name IO Description
@return return the pointer to the handle in memory. You must call MDR_freeHandle to free the memory for this pointer.
@info MDRFRAME
ProtoType
dcl-pr MDR_newHandle pointer extproc(*cwiden:'MDR_newHandle');
end-pr;

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.

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param string input the string you wish to print in the job's EBCDIC it will be converted to UTF-8 before appending.
@info MDRFRAME
Example
MDR_setHeader(handle: 'content-type': 'text/plain');
MDR_setStatus(handle: 200);
MDR_print(handle: 'This is plain text API output!');
ProtoType
dcl-pr MDR_print extproc(*cwiden: 'MDR_print') opdesc;
  handle like(MDR_handle_t);
  string varchar(65536:4) options(*varsize) const;
end-pr;

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);

Type Name IO Description
@param handle input MDRest4i session handle
@param enable input 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
ProtoType
dcl-pr MDR_sendJobInfo extproc(*cwiden:'MDR_sendJobInfo');
  handle like(MDR_Handle_t);
  enable ind const;
end-pr;

MDR_setError

Set an error to be returned from the API

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param error_id input the 7-character message ID to be reported to the caller.
@param error_text input 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 error_statement input statement number to report that the error occurred.
@param error_severity input severity of the error to be reported, typically should be 10 = Minor 20 = Important error 30 = Severe Error 40 = Critical Error
@param http_status input 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);
@info MDRFRAME
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
ProtoType
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_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.

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param msgfile input An IBM *MSGF object found on disk. This parameter is treated as CHAR(21) and expects the format LIBRARY/OBJECT in uppercase.
@param msgid input The 7-character message ID from the msgfile object to be used. Must exist in 'msgfile'
@param msgdta input The message data to be used to fill-in variables from the message file.
@param msgdtalen input Length in bytes of the msgdta parameter, or 0 if no data is needed
@param error_statement input statement number to report that the error occurred.
@param error_severity input severity of the error to be reported, typically should be 10 = Minor 20 = Important error 30 = Severe Error 40 = Critical Error
@info MDRFRAME
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
ProtoType
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

Set an HTTP status code to be sent as output

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param status input 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.
@info MDRFRAME

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');
ProtoType
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_ValidateUser

Validate the user IBM i user login. Returns the error message if the user has not supplied the correct credentials.

Type Name IO Description
@param **** input
@param **** input
@param **** input
@param **** output
@return return on for valid user profile and password, off otherwise
@info MDRFRAME99
Dcl-pr MDR_validateUser ind;
  handle        like(MDR_Handle_t);
  authUser      varchar(10:4);
  authPwd       varchar(2048:4);
  errorMsg      varchar(100:4);
end-pr;

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)

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param string input the string you wish to print in UTF-8 encoding or binary data to be sent as-is
@info MDRFRAME
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);
ProtoType
dcl-pr MDR_write extproc(*cwiden: 'MDR_write') opdesc;
  handle like(MDR_handle_t);
  string varchar(65536:4) options(*varsize) const ccsid(*utf8);
  string varchar(65536:4) options(*varsize) const;
end-pr;

Consumer-Functions

MDR_freeClient

Free the memory used by an HTTP client

Type Name IO Description
@param handle input handle returned by MDR_newClient. Once this is called, you must not use the handle again.
@info MDRFRAME8
ProtoType
dcl-pr MDR_freeClient extproc(*cwiden: 'MDR_freeClient');
  handle like(MDR_Handle_t);
end-pr;

MDR_getClientError

Retrieve the last error message for a client connection.

Type Name IO Description
@param handle input handle representing the current client session
@param msgid output/optional CHAR(7) message id (or *OMIT)
@param msg output/optional textual message (or *OMIT)
@param sev output/optional message severity (or *OMIT)
@info MDRFRAME8
ProtoType
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;

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.

Type Name IO Description
@param handle input handle returned by MDR_newClient.
@param ptr output pointer, on output will bet set to the address of the response body
@param size output on output will be set to the size of the response body in bytes
@info MDRFRAME8
ProtoType
dcl-pr MDR_getRespPtr extproc(*cwiden:'MDR_getRespPtr');
  handle      like(MDR_Handle_t);
  ptr         pointer;
  size        uns(20);
end-pr;

MDR_newClient

Create a new handle for a client connection

Type Name IO Description
@return return a pointer to a dynammically allocated client handle. (call MDR_freeClient to release the memory) or *NULL upon failure
@info MDRFRAME8
ProtoType
dcl-pr MDR_newClient pointer extproc(*cwiden:'MDR_newClient');
end-pr;

MDR_request

Make an HTTP request with an HTTP client

Type Name IO Description
@param handle input handle returned by MDR_newClient.
@param method input HTTP method (GET, POST, PUT, DELETE, etc)
@param uri input the URL to make the request to
@param sendData input/optional 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 receiveData output/optional 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 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 datafrom this transaction
@info MDRFRAME8
ProtoType
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_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()

Type Name IO Description
@param handle input (input) identifies the client instance
@param options input (input) property string representing the optionsto 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:
@info MDRFRAME8
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 +
        clearLog=N logPath="/MDRest4i/logs/daily-%Y%m%d.txt"';

MDR_setClientCfg(handle: opts);

See MDR_setClientOpt for a description of the above options.

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

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()

Type Name IO Description
@param handle input identifies the client instance
@param opt input option to set (see constants below)
@param val input value to set option to.
@return return 0 if option set successfully, -1 upon error
@info MDRFRAME8
ProtoType
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

Constant Description
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.
See this tip for handling slow APIs from your consumer code.
MDR_MAX_RETRIES Maximum amount of retries 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 const 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)

Handling Slow API Responses

If an endpoint/api being connected to has a very slow response, the following settings can be used to make the Consumer request be more "patient".

For Example:

// Create a new handle for a client connection and et the connection variables.                         
p_handle = MDR_newClient();                                                           
MDR_setClientCfg(handle:'timeout=5000 uSecDelay=50000 maxRetries=100');

The read operation will be performed in a loop that will run maximum 100 attempts (as per the value set in "maxRetries") and after every timeout, it will wait/sleep for 50000 microseconds which means 0.05 seconds before the next attempt of trying to read the socket.

In a specific attempt of trying to read the socket, if it gets the response, it comes out of the loop, and if it doesn't get response at all, the consumer program will run for 100 iterations of 5000 millisecond timeout at each iteration and for 0.05 seconds delay between each attempt.

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);

Json-Functions

MDR_buf_jsonPathL

Retrieve a string representation of a given JSON path. Output to buffer in lower case.

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param dst input pointer to the destination buffer to populate (data will be in job CCSID)
@param size input size of destination buffer (in bytes)
@param path input character string representing a JSON path
@param isNull input Returns 1 if value is NULL, 0 otherwise (you may *OMIT isNull)
@return return the length of data placed in dst (in bytes)
@info MDRFRAME7
ProtoType
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_buf_jsonPathL:

Same as above, but output is lowercase

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param dst input pointer to the destination buffer to populate (data will be in job CCSID)
@param size input size of destination buffer (in bytes)
@param path input character string representing a JSON path
@param isNull input Returns 1 if value is NULL, 0 otherwise (you may *OMIT isNull)
@return return the length of data placed in dst (in bytes)
@info MDRFRAME7
ProtoType
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

Retrieve a string representation of a given JSON path. Output to buffer in upper case.

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param dst input pointer to the destination buffer to populate (data will be in job CCSID)
@param size input size of destination buffer (in bytes)
@param path input character string representing a JSON path
@param isNull input Returns 1 if value is NULL, 0 otherwise (you may *OMIT isNull)
@return return the length of data placed in dst (in bytes)
@info MDRFRAME7
ProtoType
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_jsonPathU:

Same as above, but output is uppercase

MDR_buf_jsonPathV

Retrieve a string representation of a given JSON path. Output to buffer.

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.

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param format input (input) a JSON document representing the format of variable in 'sourceVar'. or may be START or END for sequences.
@param sourceVar input (input) a variable (typically a DS) that contains the data that will be placed in the JSON/XML
@param document input (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
ProtoType
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_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.

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param format input (input) a JSON document representing the format of variable in 'resultVar'.
@param resultVar input (output) a variable (typically a DS) that will contain the result of parsing the JSON/XML.
@param document input (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 options input (input) configuration options for the parser
@info MDRFRAME6
ProtoType
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_genParseOptions

Set parsing/generating options for the MDRest4i DATA-INTO or DATA-GEN tools.

  • 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.
Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param options input (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
@info MDRFRAME

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"')
ProtoType
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_getArraySize

Returns the number of elements in a JSON array given the path to the array element.

  • if this is empty/blank/omitted the root node is assumed.
Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param path input path to the JSON array node (can be CHAR, CHARZ or VARCHAR4)
@return return the number of array elements, or -1 upon error
@info MDRFRAME7
ProtoType
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_getCount

Get the count of the outermost number of elements parsed by MDR_DATAINTO. (For RPG's DATA-INTO, this is in the PSDS, do not use this procedure.)

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@return return the count of the outermost element in the document
@info MDRFRAME6
ProtoType
dcl-pr MDR_getCount uns(10) extproc('MDR_getCount');
  handle      like(MDR_handle_t);
end-pr;

MDR_jsonPathF

Retrieve a numeric representation of a given JSON path in floating point format

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param path input character string representing a JSON path
@param isNull input/optional Returns ON if value is NULL, OFF otherwise (you may *OMIT isNull)
@return return the numeric representation as float(8) or 0 if it cannot be represented as a number
@info MDRFRAME7
ProtoType
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_jsonPathL

Retrieve a string representation of a given JSON path. Output to string in lower case.

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param path input character string representing a JSON path
@param isNull input/optional Returns ON if value is NULL, OFF otherwise (you may *OMIT isNull)
@return return value (in lower case string format) of the given JSON path
@info MDRFRAME7
ProtoType
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_jsonPathL: Save as above, but output is lowercase

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param path input character string representing a JSON path
@param isNull input/optional Returns ON if value is NULL, OFF otherwise (you may *OMIT isNull)
@return return value (in string format) of the given JSON path
@info MDRFRAME7
ProtoType
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_jsonPathN

Retrieve the numeric representation of a given JSON path.

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param path input character string representing a JSON path
@param isNull input/optional Returns ON if value is NULL, OFF otherwise (you may *OMIT isNull)
@return return the numeric representation as packed(30: 9) or 0 if it cannot be represented as a number
@info MDRFRAME7
ProtoType
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_jsonPathU

Retrieve a string representation of a given JSON path. Output to string in upper case.

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param path input character string representing a JSON path
@param isNull input/optional Returns ON if value is NULL, OFF otherwise (you may *OMIT isNull)
@return return value (in upper case string format) of the given JSON path
@info MDRFRAME7
ProtoType
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_jsonPathU: Same as above, but output is uppercase

MDR_jsonPathV

Retrieve a string representation of a given JSON path. Output to string.

MDR_jsonPathZ

This is like MDR_jsonPathV except that it returns a timestamp field. If the data matches the ISO 8601 format for a timestamp, it will be converted to an RPG timestamp automatically. If it matches an RPG timestamp, that will be returned instead.

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param path input character string representing a JSON path
@param isNull input/optional Returns ON if value is NULL, OFF otherwise (you may *OMIT isNull)
@return return value (in timestamp format) of the JSON data, or z'0001-01-01-00.00.00.000000' upon error.
@info MDRFRAME7
ProtoType
dcl-pr MDR_jsonPathZ timestamp
       extproc(*cwiden:'MDR_jsonPathZ') opdesc;
  path        varchar(2048:4) const options(*varsize);
  isNull      ind options(*omit:*nopass);
end-pr;

MDR_setFormat

Sets the format that the MDRest4i framework uses to send/receive documents

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param format input one of the MDR_FORMAT_xxx constants
@info MDRFRAME

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

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

MDR_tree_free

Free up memory used by a JSON tree structure

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param docNode input pointer to the document node (returned by the MDR_tree_parse procedure)
@info MDRFRAME7
ProtoType
dcl-pr MDR_tree_free extproc(*cwiden:'MDR_tree_free');
  handle      like(MDR_handle_t);
  docNode     pointer value;
end-pr;

MDR_tree_parse

Parse a JSON document into a tree structure

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param stmf input 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 errMsg input Error message returned if JSON does not parse successfully (or *OMIT)
@return return the pointer to the tree structure's document node or *NULL upon failure
@info MDRFRAME7
ProtoType
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);
  input       varchar(5242880:4)  const options(*varsize: *omit)
                                  ccsid(*utf8);
  input       varchar(5242880:4)  const options(*varsize: *omit);
  errMsg      varchar(4096:4)     options(*varsize:*omit);
end-pr;

Attachment-Functions

Attachment Constants

The following constants (defined in the MDFRAME copybook) are used when adding or retrieving attachments in Provider or Consumer code. They are used to sepcify the Content-Transfer-Encoding or the Disposition type variables where required.

Transfer-Encoding

Content-Transfer-Encoding constants for attachments.

Constant Description
MDR_CTE_NONE no content-transfer-encoding assigned
dcl-c MDR_CTE_NONE 0;
MDR_CTE_BINARY data should be interpreted as binary values
dcl-c MDR_CTE_BINARY 536870912;
MDR_CTE_8BIT data should be interpreted as 8-bit char
dcl-c MDR_CTE_8BIT 536870913;
MDR_CTE_BASE64 data should be base64 encoded/decoded
dcl-c MDR_CTE_BASE64 536870915;

Disposition

This value is determines how a part is being attached to the message. In Multi-part attachments this may needs to be specified for each attachment.

Constant Description
MDR_MSGDISP_NONE do not provide a disposition
dcl-c MDR_MSGDISP_NONE x'00000000';
MDR_MSGDISP_ATTACH (default) part is an attachment
dcl-c MDR_MSGDISP_INLINE x'10000001';
MDR_MSGDISP_INLINE part should be considered inline
dcl-c MDR_MSGDISP_ATTACH x'10000002';
MDR_MSGDISP_FORMDATA part is a variable in a form
dcl-c MDR_MSGDISP_FORMDATA x'10000003';

MDR_addPart

Add a new attachment to a multipart output

Type Name IO Description
@param handle input handle provided by MDR_newClient or MDRAPI
@param contentType input content-type of newly added part.
See HTTP content-types for possible values.
@param xferEnc input content-transfer-encoding of part.
See transfer-encoding for available options
@param attname input attachment filename sent over network
@param data input string representing the data to store in the attachment. If this starts with stmf: the data will be read from a file.
@param name input/output/optional name of this message part.
@param disposition input/optional Tells MDRFRAME hwo to attach the attachment/part. See disposition constants for available options
@return return the length of data written to the memory buffer or -1 upon failure
@info MDRFRAME
ProtoType
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);
  disposition int(10)             const options(*omit:*nopass);
end-pr;

MDR_copyToClob

Copies data from a VARCHAR(4) (or fixed-length char if called from Cobol or CL) to a DB2 CLOB field.

Type Name IO Description
@param dstClob output the clob to copy to
@param srcData input the source VARCHAR4 string.
@param size input the %SIZE of the CLOB column
@info MDRFRAME5
ProtoType
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;

MDR_getPart

Copy attachment body to a variable

Type Name IO Description
@param handle input handle provided by MDR_newClient or MDRAPI
@param partNo input the part number to get the type of
@param var output character variable to store data into
@return return the length of data written to the memory buffer or -1 upon failure
@info MDRFRAME
ProtoType
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;

MDR_getPartBuf

Copy attachment body to a memory buffer identified by a pointer

Type Name IO Description
@param handle input handle provided by MDR_newClient or MDRAPI
@param partNo input the part number to get the type of
@param buf output pointer to the memory buffer to store body in
@param size input size of the memory buffer
@return return the length of data written to the memory buffer or -1 upon failure
@info MDRFRAME
ProtoType
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_getPartCount

Retrieves the number of parts in a multipart input document

Type Name IO Description
@param handle input handle provided by MDR_newClient or MDRAPI
@return return the number of parts if successful, -1 upon failure
@info MDRFRAME
ProtoType
dcl-pr MDR_getPartCount int(10)
       extproc(*cwiden:'MDR_getPartCount') opdesc;
  handle like(MDR_Handle_t);
end-pr;

MDR_getPartFileName

Retrieves the filename of a part in a multipart input document

Type Name IO Description
@param handle input handle provided by MDR_newClient or MDRAPI
@param partNo input the part number to get the file name of
@return return the filename
@info MDRFRAME
ProtoType
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_getPartName

Retrieves the name of a part in a multi part input document

Type Name IO Description
@param handle input handle provided by MDR_newClient or MDRAPI
@param partNo input the part number to get the name of
@return return the name
@info MDRFRAME
ProtoType
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_getPartType

Retrieves the content-type of a part in a multipart input document

Type Name IO Description
@param handle input handle provided by MDR_newClient or MDRAPI
@param partNo input the part number to get the type of
@return return the content-type
@info MDRFRAME
ProtoType
dcl-pr MDR_getPartType varchar(2048:4)
       extproc(*cwiden:'MDR_getPartType') rtnparm opdesc;
  handle like(MDR_Handle_t);
  partNo int(10) const;
end-pr;

Ifs-Functions

MDR_caseConvert

This simulates RPG's case=convert option for transforming a name from external document representation (XML or JSON) to a valid variable name.

The process works like this: 1) All accented letters are converted to non-accented versions. 2) any remaining non-letter/number values in the name are converted to the symbol specified in 'sym' (typically, an underscore) 3) Any consecutive symbols are compressed into one symbol. 4) Any symbols at the start of the name are removed 5) If the first letter of a variable is a number, the name is prefixed with N

Type Name IO Description
@param **** input (input) EBCDIC string representing the input name
@param **** input (input) symbol to replace punctuation characters with.
@return return the converted name
@info MDRFRAME6
Example
var = MDR_caseConvert('TEST!!!1TIME': '_');
returns TEST_1TIME
var = MDR_caseConvert('1TIME@@TEST': '_');
returns N1TIME_TEST
ProtoType
dcl-pr MDR_caseConvert varchar(4096:4) rtnparm
                       extproc(*cwiden: 'MDR_caseConvertOD') opdesc;
  src varchar(4096:4) const options(*varsize);
  sym varchar(1:4)    const;
end-pr;

MDR_path2obj

Given an IFS-style path name, calculate the system library, object, member, IASP, etc.

Type Name IO Description
@param inpath input ifs-style path name
@param qsysobj output 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 return 1 if the output is a stream file, or 0 if it is a library/obj.
@info MDRFRAME5
Example
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;
ProtoType
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;

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

Definition
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;

MDRF_basename

Extract the base (object name) portion of a path. For example if the path is one/two/three, the base is "three"

Type Name IO Description
@param path input name to extract the base name from
@return return the base name, or '' upon error
@info MDRFRAME12
ProtoType
dcl-pr MDRF_basename varchar(5000:4) rtnparm
       extproc(*cwiden:'MDRF_basename') opdesc;
  path varchar(5000:4) const options(*varsize);
end-pr;

MDRF_close

Close a file that was opened by MDR_open

Type Name IO Description
@param handle input file handle returned by MDR_open
@return return 0 if the file was successfully closed -1 otherwise
@info MDRFRAME12
ProtoType
dcl-pr MDRF_close int(10)
       extproc(*cwiden:'MDRF_close') opdesc;
  handle pointer value;
end-pr;

MDRF_closeDir

Close an open directory handle (that was opened with MDRF_open)

Type Name IO Description
@param dirh input directory handle to close
@info MDRFRAME12
ProtoType
dcl-pr MDRF_closeDir
       extproc(*cwiden:'MDRF_closeDir');
  dirh     pointer         value;
end-pr;

MDRF_delete

Delete a file or other non-directory object

Type Name IO Description
@param **** input
@return return 0 for success, -1 for error
@info MDRFRAME12
ProtoType
dcl-pr MDRF_delete int(10)
       extproc(*cwiden:'MDRF_delete') opdesc;
  path    varchar(5000:4) const options(*varsize);
end-pr;

MDRF_dirname

Extract the directory portion of a path. For example, if the path

Type Name IO Description
@param path input name to extract the directory from
@return return the directory, or '' upon error
@info MDRFRAME12
ProtoType
dcl-pr MDRF_dirname varchar(5000:4) rtnparm
       extproc(*cwiden:'MDRF_dirname') opdesc;
  path varchar(5000:4) const options(*varsize);
end-pr;

MDRF_exists

check if an object exists in the IFS

Type Name IO Description
@param path input name of object to check
@return return '1' if it exists or '0' otherwise
@info MDRFRAME12
ProtoType
dcl-pr MDRF_exists ind
       extproc(*cwiden:'MDRF_exists') opdesc;
  path varchar(5000:4) const options(*varsize);
end-pr;

MDRF_len_read

Same as MDRF_read, except reads into pointer/length

Type Name IO Description
@param handle input file handle returned by MDR_open
@param buf output pointer to buffer to read data into
@param bufsiz input space available in buffer
@return return the length of the data read or -1 upon failure
@info MDRFRAME12
ProtoType
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_len_readAll

Read the entire contents of a file into a buffer

Type Name IO Description
@param path input pathname to file to read from
@param buf output buffer to place file data into
@param bufsize input size of buf
@param errmsg output buffer to place an error message into
@param errsize input size of errmsg
@return return the number of bytes read from the file or -1 upon error (with errmsg set)
@info MDRFRAME12
ProtoType
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_len_readln

Same as MDRF_readln except it reads into a buffer addressed via a pointer and length

Type Name IO Description
@param handle input file handle returned by MDR_open
@param linebuf output pointer to buffer to read line into
@param bufsiz input space available in buffer
@return return the length of the data read or -1 upon failure
@info MDRFRAME12
ProtoType
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_len_write

Same as MDRF_write except data is written from a pointer/length

Type Name IO Description
@param handle input file handle returned by MDR_open
@param buffer input pointer to buffer containing data to write
@param length input length of data to write from the buffer
@return return the length of the data written or 0 upon failure
@info MDRFRAME12
ProtoType
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_len_writeAll

Write an entire file from one buffer

Type Name IO Description
@param path input pathname to file to write to
@param buf input buffer to write file data from
@param bufsize input length of data in buf to write
@param errmsg output buffer to place an error message into
@param errsize input size of errmsg
@return return the number of bytes written to the file or -1 upon error (with errmsg set)
@info MDRFRAME12
ProtoType
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_len_writeln

Same a MDRF_writeln except data is written from a pointer/length

Type Name IO Description
@param handle input file handle returned by MDR_open
@param buffer input 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 length input length of buffer (in bytes)
@return return the length of the line written or 0 upon failure
@info MDRFRAME12
ProtoType
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_mkdir

Create a new directory ("folder")

Type Name IO Description
@param path input name of directory to create
@param opts input/optional 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 return '1' if successful (or exists) and '0' otherwise
@info MDRFRAME12
ProtoType
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_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

Definition
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_open

Open a stream (IFS) file

  • R=read,
  • W=write,
  • A=append,
  • B=binary,
  • N=create new

prop=val = list of space-separated property=value options from the list below

  • 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.
Type Name IO Description
@param path input IFS path of the file to open
@param opts input/optional options string
@param errmsg output/optional error message OPTIONS STRING Format is XXXX, prop=val prop=val prop=val XXXX = flags:
@return return a handle to the open file or NULL upon error (and errmsg is set)
@info MDRFRAME12
Example
fh = MDRF_open('/path/to/file'
: 'N,ccsid=819 owner=RW group=RW public=R'
: err );
ProtoType
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_openDir

Open a directory so you can read the files within it

Type Name IO Description
@param path input path name to directory to open
@param pattern input/optional pattern of filenames to return, this allows for *, ? or [a-z] wildcards. Default = return all filenames
@return 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
ProtoType
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_read

Read data from a stream (IFS) file

Type Name IO Description
@param handle input file handle returned by MDR_open
@param buf output buffer to read data into
@return return the length of the data read or -1 upon failure
@info MDRFRAME12
ProtoType
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_readAll

Read the entire contents of a file into a string

Type Name IO Description
@param path input pathname to file to read from
@param string output string to place file contents into
@param errmsg output/optional string to place error message into
@return return the number of bytes read from the file or -1 upon error (with errmsg set)
@info MDRFRAME12
ProtoType
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_readDir

Read the next filename from a directory (previously opened with MDRF_openDir)

Type Name IO Description
@param dirh input handle to the open directory
@param filename output filename returned
@param fileinfo output/optional 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 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
ProtoType
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_readln

Read a line of text from a stream (IFS) file

Type Name IO Description
@param handle input file handle returned by MDR_open
@param line output variable to read the line into
@return return the length of the data read or -1 upon failure
@info MDRFRAME12
ProtoType
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_rmdir

Remove/delete a directory (optionally including its contents)

Type Name IO Description
@param path input name of directory to delete
@param subtree input/optional ON to delete any contents, or OFF only remove directory if empty.
@return return 0 for success, -1 for error
@info MDRFRAME12
ProtoType
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_write

Write data to a stream (IFS) file

Type Name IO Description
@param handle input file handle returned by MDR_open
@param data input variable containing data to be written
@return return the length of the data written or 0 upon failure
@info MDRFRAME12
ProtoType
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_writeAll

Write an entire file from one string. If the file already exists, its contents are replaced.

Type Name IO Description
@param path input pathname to file to write to
@param buf input string to write file data from
@param **** output/optional
@return return the number of bytes written to the file or -1 upon error (with errmsg set)
@info MDRFRAME12
ProtoType
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;

MDRF_writeln

Write data to a stream (IFS) file as a series of lines

Type Name IO Description
@param handle input file handle returned by MDR_open
@param line input data to be written to disk. An EOL sequence (as set on MDRF_open) will be appended to the data.
@return return the length of the line written or 0 upon failure
@info MDRFRAME12
ProtoType
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;

Advanced-Consumer-Functions

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

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

MDR_getRequest

This retrieves the (internal) request structure that the MDRest4i framework uses to store information about this transaction.

Type Name IO Description
@param handle input context handle, identifies which MDRest4i session is currently running.
@param request input returns a pointer to the request structure which should be in the format of MDR_Request_t, above.
@return return 0 always
@info MDRFRAME
Example
dcl-ds req likeds(MDR_Request_t) based(p_req);
MDR_getRequest(handle: p_req);

if req.format = MDR_FORMAT_XML;
xml-specific code here.
endif;
ProtoType
dcl-pr MDR_getRequest int(10) extproc(*cwiden: 'MDR_getRequest');
  handle  like(MDR_handle_t);
  request pointer;
end-pr;

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.

Definition
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_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

Definition
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:

This is the internal data structure that MDRest4i stores data about the current request (or transaction) in.

Sub-Field Description
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 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
Definition
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_RPG_Cookies_t

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

Definition
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(3072);
    *n    char(1) inz(x'00');
  end-ds;
end-ds;

MDR_RPG_Headers_t

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.

Definition
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(3072);
    *n    char(1) inz(x'00');
  end-ds;
end-ds;

MDR_RPG_PathVars_t

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.

Example
http://server:port/mdrapi/customer/1

pathvar(1).value = 'mdrpapi'
pathvar(2).value = 'customer'
parmvar(3).value = '1'
Definition
dcl-ds MDR_RPG_PathVars_t qualified template inz;
  count uns(10) inz(0);
  dcl-ds pathvar dim(MAX_PATHVARS);
    value varchar(3072);
    *n    char(1) inz(x'00');
  end-ds;
end-ds;

MDR_RPG_QueryVars_t

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

Definition
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;