サンプル・サービス・プログラム

以下の例は、文字ストリングを 16 進数に変換するサービス・プログラム CVTTOHEX の作成方法を示しています。 次の 2 つのパラメーターがサービス・プログラムに渡されます。

  1. 変換すべき文字フィールド (InString)
  2. 2 バイトの 16 進数が入る文字フィールド (HexString)

フィールド HexString は変換の結果を入れ、また変換する ストリングの長さを指示するために用いられます。 例えば、文字ストリング 30 桁を渡すが 最初の 10 桁だけを変換したい場合には、20 バイト (2 × 10) の 2 番目のパラメーターを 渡すことになります。 渡されたフィールドの長さを基に、サービス・プログラムは 処理の長さを決定します。

図 42 はサービス・プログラムのソースを示したものです。図 43 は CvtToHex のプロトタイプを含む /COPY メンバーを示したものです。

サービス・プログラム中に含まれるプロシージャーの基本ロジックは、以下に示 すとおりです。

  1. 操作記述子は渡されるパラメーターの長さを決めるために使用される。
  2. 変換すべき長さが決められる。文字ストリングの長さよりも小さいか、 あるいは 16 進ストリング・フィールドの 2 分の 1 の長さになります。
  3. ストリングの各文字は サブルーチン GetHex を使用して 2 バイトの 16 進値に変換されます。

    GetHex が、実行時のパフォーマンスを向上させるため、サブプロシージャー ではなくサブルーチンとしてコーディングされていることに注意してください。 EXSR 命令はバインド呼び出しよりずっと高速で実行され、この例では、 GetHex が頻繁に呼び出されます。

  4. プロシージャーが呼び出し元に戻る。

サービス・プログラムは操作記述子を利用しますが、これは渡されたパラメーターの正確な性質 (この場合には長さ) が前もって分らない場合に、使用される ILE 構造です。 操作記述子は、CALLB 命令の命令拡張子 (D) を指定した時 またはプロトタイプに OPDESC を指定した時にプロシージャーに対する呼び出し時に作成されます。

操作記述子を使用するためには、サービス・プログラムで ILE バインド可能 API の CEEDOD (操作記述子の検索) を呼び出さなければなりません。 この API には CALLB 命令に 定義しなければならないある種のパラメーターが必要です。 しかし、これだけで必要な情報、すなわち長さを得る ことができます。 操作記述子の詳細については、操作記述子の使用を参照してください。

図 42. サービス・プログラム CvtToHex のソース
      *=================================================================*
      * CvtToHex - 入力ストリングを 16 進出力ストリングに変換
      *=================================================================*
     H COPYRIGHT('(C) Copyright MyCompany 1995')
     D/COPY RPGGUIDE/QRPGLE,CVTHEXPR
      *-----------------------------------------------------------------*
      * メイン入力パラメーター
      * 1. 入力:  ストリング                 文字(n)
      * 2. 出力:  16 進ストリング            文字(2 * n)
      *-----------------------------------------------------------------*
     D CvtToHex        PI                    OPDESC
     D   InString                 16383      CONST OPTIONS(*VARSIZE)
     D   HexString                32766      OPTIONS(*VARSIZE)

      *-----------------------------------------------------------------*
      * CEEDOD (操作記述子用の検索) 用のプロトタイプ
      *-----------------------------------------------------------------*
     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)

      * 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

      *-----------------------------------------------------------------*
      * プログラムで使用されるその他のフィールド                        *
      *-----------------------------------------------------------------*
     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

      *-----------------------------------------------------------------*
      * 渡されたパラメーターの長さを判別するために、操作記述子を        *
      * 使用します。                                                    *
      *-----------------------------------------------------------------*
     C                   CALLP     CEEDOD(1         : DescType : DataType :
     C                                    DescInfo1 : DescInfo2: Inlen    :
     C                                    *OMIT)
     C                   CALLP     CEEDOD(2         : DescType : DataType :
     C                                    DescInfo1 : DescInfo2: HexLen   :
     C                                    *OMIT)
      *-----------------------------------------------------------------*
      * 取り扱う長さの判別 (入力の長さの最小、および                    *
      * 16 進の長さの半分)                                              *
      *-----------------------------------------------------------------*
     C                   IF        InLen > HexLen / 2
     C                   EVAL      InLen = HexLen / 2
     C                   ENDIF

      *-----------------------------------------------------------------*
      * 入力ストリングの文字ごとに、2 バイトの 16 進表記に変換          *
      * (例えば、'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

      *-----------------------------------------------------------------*
      * 実行後; 呼び出し元へ戻ります。                                  *
      *-----------------------------------------------------------------*
     C                   RETURN

      *=================================================================*
      * GetHex - 'InChar' を 'HexDs' へ変換するサブルーチン             *
      *                                                                 *
      * 2 つの 16 進の桁を区切るために、16 による除算を使用します。     *
      * その商を最初の桁に、剰余を 2 番目の桁とします。                 *
      *=================================================================*
     C     GetHex        BEGSR
     C                   EVAL      IntChar = InChar
     C     IntNum        DIV       16            X1                5 0
     C                   MVR                     X2                5 0
      *-----------------------------------------------------------------*
      * 16 進文字のリスト '012...CDEF' のサブストリングを得るために、   *
      * 16 進の桁 (プラス 1) を使用します。                             *
      *-----------------------------------------------------------------*
     C                   EVAL      HexC1 = %SUBST(HexDigits:X1+1:1)
     C                   EVAL      HexC2 = %SUBST(HexDigits:X2+1:1)
     C                   ENDSR
図 43. CvtToHex のプロトタイプでの /COPY メンバーのソース
      *=================================================================*
      * CvtToHex - 入力ストリングを 16 進出力ストリングに変換
      *
      * パラメーター
      * 1. 入力:  ストリング                 文字(n)
      * 2. 出力:  16 進ストリング            文字(2 * n)
      *=================================================================*
     D CvtToHex        PR                    OPDESC
     D   InString                 16383      CONST OPTIONS(*VARSIZE)
     D   HexString                32766      OPTIONS(*VARSIZE)

このサービス・プログラムを設計する時には、後日プログラムをより容易に更新できるよう インターフェースの判別にバインダー言語を利用するよう決定されました。 図 44 は、サービス・プログラム CVTTOHEX のエクスポートを定義するのに必要なバインダー言語を示します。このソースは CRTSRVPGM コマンド の EXPORT、SRCFILE、および SRCMBR パラメーターで使われます。

図 44. CvtToHex のためのバインダー言語のソース
STRPGMEXP SIGNATURE('CVTHEX')
   EXPORT SYMBOL('CVTTOHEX')
ENDPGMEXP

STRPGMEXP のパラメーター SIGNATURE は、サービス・プログラムが提供する インターフェースを指定します。 この場合には、バインダー言語で識別されるエクスポートがインターフェースです。 CVTTOHEX へバインドされるプログラムがこのインターフェース識別値を使用し ます。

バインダー言語 EXPORT ステートメントがサービス・プログラムの エクスポートを指定します。 呼び出し元に対して使用したいエクスポートをもつ各プロシージャーに 1 つ必要 です。 この場合、サービス・プログラムには 1 つのプロシージャーを含む 1 つ のモジュールが入っています。 そのため、EXPORT ステートメントが 1 つだけ必要になります。

バインダー言語およびインターフェース識別値について詳しくは、「ILE 概念」を 参照してください。