Writing a converter in C

The following discussion is based on a converter that consists of four main parts:
  • A routing part that consults the function code in the communication area, and then calls the appropriate function
  • A function for Getlengths processing
  • A function for Decode processing
  • A function for Encode processing
Figure 1 shows how you can route control to the appropriate function.
Figure 1. Routing control to the functions in C
 EXEC CICS ADDRESS EIB(dfheiptr); /*Get addressability of
EIB*/

EXEC CICS ADDRESS COMMAREA(converter_parms_ptr);

switch(converter_parms_ptr->converter_function) {

case URP_GETLENGTHS:
{
converter_getlengths();
break;
}
case URP_DECODE:
{
converter_decode();
break;
}
case URP_ENCODE:
{
converter_encode();
break;
}

default:
{
converter_parms_ptr->converter_response = URP_INVALID;
}

} /* end switch */

EXEC CICS RETURN;

} /* end main */

In this program fragment, converter_parms_ptr is a locally declared pointer to the converter_parms structure declared in DFHRPCDH. All the other names beginning converter_ are names from this structure.

The processing is as follows:
  1. The converter_parms_ptr pointer is set by using EXEC CICS ADDRESS COMMAREA.
  2. The switch statement is used to select the function to be called. If you are not providing all the functions, you need fewer case statements.
  3. If the function is not valid, the response URP_INVALID is returned from the converter. This test is always advised, especially if the converter does not provide all three functions.
Figure 2 is an example of a Decode function.
Figure 2. Example of a Decode function in C
 void converter_decode(void)
{
decode_parms *decode_parms_ptr;

decode_parms_ptr = (decode_parms *)converter_parms_ptr;

if (strncmp
(decode_parms_ptr->decode_eyecatcher,DECODE_EYECATCHER_INIT,8)
== 0)
{
EXEC CICS GETMAIN
SET(decode_parms_ptr->decode_returned_data_ptr)
FLENGTH(sizeof(rem_proc_parms_103) + PW_LEN)
SHARED
NOSUSPEND
CICSDATAKEY
RESP(response)
RESP2(response2);

if (response != DFHRESP(NORMAL))
{
memcpy(outline,errmsg1,strlen(errmsg1));
EXEC CICS WRITEQ TD QUEUE(tdq) FROM(outline) LENGTH(30);
decode_parms_ptr->decode_response = URP_EXCEPTION;
decode_parms_ptr->decode_reason = NO_STORAGE;
}
else
{
/* move password and data to decode_password and
decode_server_input_data */

decode_parms_ptr->decode_response = URP_OK;
};
}
else
decode_parms_ptr->decode_response = URP_INVALID;
}

In this program fragment, names beginning decode_ , except decode_parms_ptr , are names from the decode_parms structure defined in DFHRPCDH.

The processing is as follows:
  1. The pointer decode_parms_ptr is set from converter_parms_ptr.
  2. The eyecatcher is checked to see if it agrees with the function code. If it does:
    1. EXEC CICS® GETMAIN is used to get storage for the password and for the communication area to be passed to the CICS program. The value of PW_LEN is set elsewhere in the program to 8 by #define . The output parameter decode_returned_data_ptr is used directly in the GETMAIN. In this case there is no conversion of data to be done, and the communication area size is the same as the size of the client data structure. ( rem_proc_parms_103 is a structure that defines the input data after XDR conversion.)
    2. If the response to the EXEC CICS GETMAIN is not NORMAL, an error message is directed to a transient data queue, the converter response is set to URP_EXCEPTION, and the reason code is set to NO_STORAGE, which is locally declared.
    3. If the response to the EXEC CICS GETMAIN is NORMAL, the data and password are transferred to the storage acquired by GETMAIN (not shown), and the converter response is set to URP_OK.
  3. If the eyecatcher is not the one for the function being called, the converter response is set to URP_INVALID.