Sample Service Program

El ejemplo siguiente muestra cómo crear un programa de servicio CVTTOHEX que convierte series de caracteres a su equivalente hexadecimal. Se pasan dos parámetros al programa de servicio:
  1. un campo de caracteres (InString) que se va a convertir
  2. un campo de caracteres (HexString) que contendrá el equivalente hexadecimal de 2 bytes

El campo HexString se utiliza para contener el resultado de la conversión y también para indicar la longitud de la serie que se va a convertir. Por ejemplo, si se pasa una serie de caracteres de 30 caracteres, pero sólo está interesado en convertir los diez primeros, pasaría un segundo parámetro de 20 bytes (2 veces 10). Basándose en la longitud de los campos pasados, el programa de servicio determina la longitud que se debe manejar.

La Figura 1 muestra el origen del programa de servicio. Figura 2 muestra el miembro /COPY que contiene el prototipo de CvtToHex.

La lógica básica del procedimiento contenido en el programa de servicio se lista a continuación:
  1. Los descriptores operativos se utilizan para determinar la longitud de los parámetros pasados.
  2. La longitud que se va a convertir se determina: es la menor de la longitud de la serie de caracteres, o la mitad de la longitud del campo de serie hexadecimal.
  3. Cada carácter de la serie se convierte a un equivalente hexadecimal de dos bytes utilizando la subrutina GetHex.

    Tenga en cuenta que GetHex se codifica como una subrutina en lugar de un subprocedimiento, para mejorar el rendimiento en tiempo de ejecución. Una operación EXSR se ejecuta mucho más rápido que una llamada enlazada, y en este ejemplo, GetHex se llama muchas veces.

  4. El procedimiento vuelve a su interlocutor.

El programa de servicio utiliza descriptores operativos, que es una construcción ILE utilizada cuando la naturaleza precisa de un parámetro pasado no se conoce antes de tiempo, en este caso la longitud. Los descriptores operativos se crean en una llamada a un procedimiento cuando se especifica el expansor de operación (D) en la operación CALLB, o cuando se especifica OPDESC en el prototipo.

Para utilizar los descriptores operativos, el programa de servicio debe llamar a la API enlazable ILE, CEEDOD (Recuperar descriptor operativo). Esta API requiere determinados parámetros que deben definirse para la operación CALLB. Sin embargo, es el último parámetro que proporciona la información necesaria, es decir, la longitud. Para obtener más información sobre los descriptores operativos, consulte Utilización de descriptores operativos.

Figura 1. Fuente para el programa de servicios 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
Figura 2. Fuente para el miembro /COPY con prototipo para 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)

Al diseñar este programa de servicio, se decidió hacer uso del lenguaje enlazador para determinar la interfaz, para que el programa pudiera actualizarse más fácilmente en una fecha posterior. La Figura 3 muestra el lenguaje enlazador necesario para definir las exportaciones del programa de servicio CVTTOHEX. Este origen se utiliza en los parámetros EXPORT, SRCFILE y SRCMBR del mandato CRTSRVPGM.

Figura 3. Fuente del lenguaje Binder para CvtToHex
STRPGMEXP SIGNATURE('CVTHEX')
   EXPORT SYMBOL('CVTTOHEX')
ENDPGMEXP

El parámetro SIGNATURE en STRPGMEXP identifica la interfaz que el programa de servicio proporcionará. En este caso, la exportación identificada en el lenguaje enlazador es la interfaz. Cualquier programa vinculado a CVTTOHEX utilizará esta firma.

Las sentencias EXPORT del lenguaje enlazador identifican las exportaciones del programa de servicio. Necesita uno para cada procedimiento cuyas exportaciones desea poner a disposición del llamante. En este caso, el programa de servicio contiene un módulo que contiene un procedimiento. Por lo tanto, sólo se necesita una sentencia EXPORT.

Para obtener más información sobre el lenguaje enlazador y las firmas, consulte Conceptos ILE.