Sample Service Program

The following example shows how to create a service program CVTTOHEX which converts character strings to their hexadecimal equivalent. Two parameters are passed to the service program:

  1. a character field (InString) to be converted
  2. a character field (HexString) which will contain the 2-byte hexadecimal equivalent

The field HexString is used to contain the result of the conversion and also to indicate the length of the string to be converted. For example, if a character string of 30 characters is passed, but you are only interested in converting the first ten, you would pass a second parameter of 20 bytes (2 times 10). Based on the length of the passed fields, the service program determines the length to handle.

Figure 43 shows the source for the service program. Figure 44 shows the /COPY member containing the prototype for CvtToHex.

The basic logic of the procedure contained within the service program is listed below:

  1. Operational descriptors are used to determine the length of the passed parameters.
  2. The length to be converted is determined: it is the lesser of the length of the character string, or one-half the length of the hex string field.
  3. Each character in the string is converted to a two-byte hexadecimal equivalent using the subroutine GetHex.

    Note that GetHex is coded as a subroutine rather than a subprocedure, in order to improve run-time performance. An EXSR operation runs much faster than a bound call, and in this example, GetHex is called many times.

  4. The procedure returns to its caller.

The service program makes use of operational descriptors, which is an ILE construct used when the precise nature of a passed parameter is not known ahead of time, in this case the length. The operational descriptors are created on a call to a procedure when you specify the operation extender (D) on the CALLB operation, or when OPDESC is specified on the prototype.

To use the operational descriptors, the service program must call the ILE bindable API, CEEDOD (Retrieve Operational Descriptor). This API requires certain parameters which must be defined for the CALLB operation. However, it is the last parameter which provides the information needed, namely, the length. For more information on operational descriptors, see Using Operational Descriptors.

Figure 43. Source for Service Program CvtToHex
      *=================================================================*
      * CvtToHex - convert input string to hex output string
      *=================================================================*
     H COPYRIGHT('(C) Copyright MyCompany 1995')
     D/COPY RPGGUIDE/QRPGLE,CVTHEXPR
      *-----------------------------------------------------------------*
      * Main entry parameters
      * 1. Input:   string                   character(n)
      * 2. Output:  hex string               character(2 * n)
      *-----------------------------------------------------------------*
     D CvtToHex        PI                    OPDESC
     D   InString                 16383      CONST OPTIONS(*VARSIZE)
     D   HexString                32766      OPTIONS(*VARSIZE)

      *-----------------------------------------------------------------*
      * Prototype for CEEDOD (Retrieve operational descriptor)
      *-----------------------------------------------------------------*
     D CEEDOD          PR
     D ParmNum                       10I 0 CONST
     D                               10I 0
     D                               10I 0
     D                               10I 0
     D                               10I 0
     D                               10I 0
     D                               12A   OPTIONS(*OMIT)

      * Parameters passed to CEEDOD
     D DescType        S             10I 0
     D DataType        S             10I 0
     D DescInfo1       S             10I 0
     D DescInfo2       S             10I 0
     D InLen           S             10I 0
     D HexLen          S             10I 0

      *-----------------------------------------------------------------*
      * Other fields used by the program                                *
      *-----------------------------------------------------------------*
     D HexDigits       C                   CONST('0123456789ABCDEF')
     D IntDs           DS
     D   IntNum                       5I 0 INZ(0)
     D   IntChar                      1    OVERLAY(IntNum:2)
     D HexDs           DS
     D   HexC1                        1
     D   HexC2                        1
     D InChar          S              1
     D Pos             S              5P 0
     D HexPos          S              5P 0

      *-----------------------------------------------------------------*
      * Use the operational descriptors to determine the lengths of     *
      * the parameters that were passed.                                *
      *-----------------------------------------------------------------*
     C                   CALLP     CEEDOD(1         : DescType : DataType :
     C                                    DescInfo1 : DescInfo2: Inlen    :
     C                                    *OMIT)
     C                   CALLP     CEEDOD(2         : DescType : DataType :
     C                                    DescInfo1 : DescInfo2: HexLen   :
     C                                    *OMIT)
      *-----------------------------------------------------------------*
      * Determine the length to handle (minimum of the input length     *
      * and half of the hex length)                                     *
      *-----------------------------------------------------------------*
     C                   IF        InLen > HexLen / 2
     C                   EVAL      InLen = HexLen / 2
     C                   ENDIF

      *-----------------------------------------------------------------*
      * For each character in the input string, convert to a 2-byte     *
      * hexadecimal representation (for example, '5' --> 'F5')          *
      *-----------------------------------------------------------------*
     C                   EVAL      HexPos = 1
     C                   DO        InLen         Pos
     C                   EVAL      InChar = %SUBST(InString : Pos :1)
     C                   EXSR      GetHex
     C                   EVAL      %SUBST(HexString : HexPos : 2) = HexDs
     C                   EVAL      HexPos = HexPos + 2
     C                   ENDDO

      *-----------------------------------------------------------------*
      * Done; return to caller.                                         *
      *-----------------------------------------------------------------*
     C                   RETURN

      *=================================================================*
      * GetHex - subroutine to convert 'InChar' to 'HexDs'              *
      *                                                                 *
      * Use division by 16 to separate the two hexadecimal digits.      *
      * The quotient is the first digit, the remainder is the second.   *
      *=================================================================*
     C     GetHex        BEGSR
     C                   EVAL      IntChar = InChar
     C     IntNum        DIV       16            X1                5 0
     C                   MVR                     X2                5 0
      *-----------------------------------------------------------------*
      * Use the hexadecimal digit (plus 1) to substring the list of     *
      * hexadecimal characters '012...CDEF'.                            *
      *-----------------------------------------------------------------*
     C                   EVAL      HexC1 = %SUBST(HexDigits:X1+1:1)
     C                   EVAL      HexC2 = %SUBST(HexDigits:X2+1:1)
     C                   ENDSR
Figure 44. Source for /COPY Member with Prototype for CvtToHex
      *=================================================================*
      * CvtToHex - convert input string to hex output string
      *
      * Parameters
      * 1. Input:   string                   character(n)
      * 2. Output:  hex string               character(2 * n)
      *=================================================================*
     D CvtToHex        PR                    OPDESC
     D   InString                 16383      CONST OPTIONS(*VARSIZE)
     D   HexString                32766      OPTIONS(*VARSIZE)

When designing this service program, it was decided to make use of binder language to determine the interface, so that the program could be more easily updated at a later date. Figure 45 shows the binder language needed to define the exports of the service program CVTTOHEX. This source is used in the EXPORT, SRCFILE and SRCMBR parameters of the CRTSRVPGM command.

Figure 45. Source for Binder Language for CvtToHex
STRPGMEXP SIGNATURE('CVTHEX')
   EXPORT SYMBOL('CVTTOHEX')
ENDPGMEXP

The parameter SIGNATURE on STRPGMEXP identifies the interface that the service program will provide. In this case, the export identified in the binder language is the interface. Any program bound to CVTTOHEX will make use of this signature.

The binder language EXPORT statements identify the exports of the service program. You need one for each procedure whose exports you want to make available to the caller. In this case, the service program contains one module which contains one procedure. Hence, only one EXPORT statement is required.

For more information on binder language and signatures, see ILE Concepts.



[ Top of Page | Previous Page | Next Page | Contents | Index ]