FCD処理API

本付録では、FCD処理APIを使用して、メインCOBOLアプリケーション・プログラムでオープンされたデータセットを、C言語で作成されたサブプログラムで読み書きする方法について説明します。

1. 概要

OpenFrameと一緒に提供されるFCD(File Control Description)処理APIを使用して、メインCOBOLアプリケーション・プログラムでオープンされたデータセットを、C言語で作成されたサブプログラムで読み書きするなどのI/Oが実行できます。ただし、メインCOBOLアプリケーション・プログラムをMF-COBOLコンパイラーでコンパイルする必要があります。

FCD処理APIライブラリは、データセットの情報を保存している構造体としてFCDを使用します。FCDは、MF-COBOLコンパイラーによってコンパイルされた実行バイナリが実行される際、データセットを開くときに生成されるメモリ構造体です。したがって、本書で説明するTmax FCD処理APIライブラリは、MF-COBOLコンパイラーによってコンパイルされた実行バイナリでのみ一緒に使用することができます。

最初からCで作成されたアプリケーション・プログラムでデータセットのI/Oを行う場合は、FCD処理APIライブラリではなく、C File Handlerライブラリを使用することをお勧めします。

FCD処理APIを使用してプログラムを作成するには、OpenFrameバイナリと一緒に配布されるtfcd.hヘッダー・ファイルを、Cで作成されたサブプログラムに含める必要があり、そのサブプログラムをコンパイルする際、libtfcd.soライブラリをリンクする必要があります。

Tmax FCD処理APIは、以下のように分類できます。

  • ファイル・オープン・セッション

    API 説明

    tfcd_open()

    FCD構造体に記述されているデータセットを開きます。

    tfcd_close()

    FCD構造体に記述されているデータセットを閉じます。

  • レコード・アクセス

    API 説明

    tfcd_start()

    相対データセットまたは索引データセットで次に読み取るレコードの位置に移動させます。

    tfcd_read()

    データセットのレコードを順次に読み取るか、またはキーを指定してランダムに読み取ります。

    tfcd_write()

    データセットに新しいレコードを書き込む(WRITE)か、または既存のレコードを再書き込み(REWRITE)します。

    tfcd_writea()

    レコードの先頭にASA制御文字を指定してデータセットに新しいレコードを書き込みます。

    tfcd_delete()

    データセットにある既存のレコードを削除します。(RELATIVE/INDEXED)

  • *特殊な操作

    API 説明

    tfcd_is_file_open()

    FCD構造体に記述されているデータセットが開かれているかを確認します。

    tfcd_get_status()

    データセットにI/Oを実行した後、エラーの発生有無を確認するために状態コードを取得します。

    tfcd_get_file_name()

    FCD構造体に記述されているデータセットのDD名を取得します。

    tfcd_get_rec_len()

    FCD構造体に記述されているデータセットのレコード長を取得します。

    tfcd_set_file_name()

    FCD構造体に記述されているデータセットのDD名を指定します。

    tfcd_set_relative_key()

    FCD構造体に記述されているデータセットの相対キーを指定します。(RELATIVE)

    tfcd_set_key_id()

    FCD構造体に記述されているデータセットのKEY IDを指定します。(INDEXED)

    tfcd_set_rec_len()

    FCD構造体に記述されているデータセットのレコード長を指定します。

2. ファイル・オープン・セッション

2.1. tfcd_open()

FCD構造体に記述されているデータセットを開きます。データセットのオープンは、JCLでDD文によって割り当てられたデータセットに対し、実際にレコードを読み書きするなどのI/Oを行うための準備手順です。

データセットを開くときに指定するオープン・モードでのtfcd.hヘッダー・ファイルには、以下のようなマクロが定義されています。

#define TFCD_OPEN_INPUT             0   /* OPEN INPUT */
#define TFCD_OPEN_OUTPUT            1   /* OPEN OUTPUT */
#define TFCD_OPEN_INOUT             2   /* OPEN I-O */
#define TFCD_OPEN_EXTEND            3   /* OPEN EXTEND */

データセットを正常に開いた場合、tfcd_get_status()で確認できる状態コードに00が保存されます。ただし、すでに開いているデータセットを再度開こうとすると、エラーが発生します。

  • プロトタイプ

    int tfcd_open(void *fcd, int open_mode, int flags);
  • パラメータ

    パラメータ 説明

    fcd(入出力)

    メインCOBOLアプリケーション・プログラムから渡されたFCD構造体アドレスです。

    open_mode(入力)

    データセットのオープン・モードです。

    • INPUT

    • OUTPUT

    • INOUT

    • EXTEND

    flags(入力)

    データセットを開くときに指定できる属性です。

    • NO REWIND

  • 戻り値

    正常に関数が実行された場合、0が返されます。状態コード値を確認して、データセットを正常にオープンしたのかを確認します。

2.2. tfcd_close()

FCD構造体に記述されているデータセットを閉じます。データセットのクローズは、アプリケーションでデータセットの読み書きなどのI/Oを行った後、アプリケーションと物理的なデータセットとの接続を切断する作業です。

データセットを正常に閉じた後は、tfcd_get_status()で確認できる状態コードに00が保存されます。閉じられたデータセットは、tfcd_open() APIを使用して再度開くことができます。

  • プロトタイプ

    int tfcd_close(void *fcd, int flags);
  • パラメータ

    パラメータ 説明

    fcd(入出力)

    メインCOBOLアプリケーション・プログラムから渡されたFCD構造体アドレスです。

    flags(入力)

    データセットを閉じるときに指定できる属性です。

    • WITH LOCK

  • 戻り値

    正常に関数が実行された場合、0が返されます。状態コード値を確認して、データセットを正常にクローズしたのかを確認します。

3. レコード・アクセス

3.1. tfcd_start()

相対データセット、または索引データセットで次に読み取るレコードの位置に移動させます。移動させるレコードの位置は、相対データセットの場合、tfcd_set_relative_key() APIを呼び出して相対レコード番号を指定します。一方、索引データセットの場合は、レコード・ポインター内にあるキーの位置に予めキー値を指定しておきます。

START APIの実行時に、キー値と同じレコードを検索するか、あるいはキー値より大きいか等しいレコードを検索するかを指定することができます。tfcd.hヘッダー・ファイルに以下のようなマクロが定義されています。

#define TFCD_START_DEFAULT          0   /* START */
#define TFCD_START_EQUAL            1   /* START (equal to full length) */
#define TFCD_START_GTEQ             2   /* START (not less than) */

VSAMデータセットの場合は、該当するデータセットのデフォルトのレコード・キー以外に副レコード・キーを追加で定義できます。副レコード・キーを使用してStart APIを実行するときは、tfcd_set_key_id() APIを呼び出して、次回Start APIで使用するキーIDを指定します。キーIDは、メインCOBOLアプリケーション・プログラムのSELECT文で副レコード・キーを指定した順に番号が与えられます。

  • プロトタイプ

    int tfcd_start(void *fcd, char *record, int flags);
  • パラメータ

    パラメータ 説明

    fcd(入出力)

    メインCOBOLアプリケーション・プログラムから渡されたFCD構造体アドレスです。

    record(入出力)

    移動させるレコードの位置が保存されているレコード・バッファー・ポインターです。

    flags(入力)

    データセットを開始するときに指定できる属性です。

    • EQUAL

    • GTEQ

  • 戻り値

    正常に関数が実行された場合、0が返されます。状態コード値を確認して、データセットを正常にオープンしたのかを確認します。

3.2. tfcd_read()

データセットのレコードを順次に読み取るか、キーを指定してランダムに読み取ります。ランダムにレコードを読み取る場合、相対データセットでは、tfcd_set_relative_key() APIを呼び出して相対レコード番号を指定します。一方、索引データセットでは、レコード・ポインター内にあるキーの位置に予めキー値を指定しておきます。

VSAMデータセットの場合は、該当するデータセットのデフォルトのレコード・キー以外に副レコード・キーを追加で定義できます。副レコード・キーを使用してランダムにレコードを読み取るときは、tfcd_set_key_id() APIを呼び出して次回READ APIで使用するキーIDを指定します。キーIDは、メインCOBOLアプリケーション・プログラムのSELECT文で副レコード・キーを指定した順に番号が与えられます。

tfcd.hヘッダー・ファイルには、Read APIの実行時にレコードを順次に読み取るか、ランダムに読み取るかを指定するマクロが以下のように定義されています。

#define TFCD_READ_DEFAULT           0   /* READ */
#define TFCD_READ_NEXT              1   /* READ (sequential) */

可変長レコード・データセットの場合、Read APIを使用してデータセットのレコードを読み取ると、tfcd_get_rec_len() APIを呼び出して読み取ったレコード長を取得できます。取得したレコード長は、RDWを除いたレコードのデータ部分の長さです。

  • プロトタイプ

    int tfcd_read(void *fcd, char *record, int flags);
  • パラメータ

    パラメータ 説明

    fcd(入出力)

    メインCOBOLアプリケーション・プログラムから渡されたFCD構造体のアドレスです。

    record(入出力)

    データセットから読み取ったレコードが保存されるレコード・バッファー・ポインターです。

    flags(入力)

    データセットを読み取るときに指定できる属性です。

    • DEFAULT

    • NEXT

  • 戻り値

    正常に関数が実行された場合、0が返されます。状態コード値を確認して、データセットを正常に読み取ったのかを確認します。

3.3. tfcd_write()

データセットに新しいレコードを書き込むか、または既存のレコードを再書き込みします。

順次データセットの場合はデータセットの最後にレコードを書き込み、相対データセットの場合はtfcd_set_relative_key() APIを呼び出して保存される相対レコード番号を指定します。索引データセットの場合は、レコード・ポインター内にあるキー順にレコードが保存されます。

tfcd.hヘッダー・ファイルには、Write APIの実行時に新しいレコードを書き込むか、既存のレコード内容を更新するかを指定するマクロが以下のように定義されています。

#define TFCD_WRITE_DEFAULT          0   /* WRITE */
#define TFCD_WRITE_REWRITE          1   /* REWRITE */

可変長レコード・データセットの場合、Write APIを使用してデータセットのレコードを書き込む前に、レコード長をtfcd_set_rec_len() APIを呼び出して指定することができます。そのとき、レコード長はRDWを除いたレコードのデータ部分の長さを指定します。

  • プロトタイプ

    int tfcd_write(void *fcd, char *record, int flags);
  • パラメータ

    パラメータ 説明

    fcd(入出力)

    メインCOBOLアプリケーション・プログラムから渡されたFCD構造体アドレスです。

    record(入力)

    データセットに書き込むレコードが保存されているレコード・バッファー・ポインターです。

    flags(入力)

    データセットを書き込むときに指定できる属性です。

    • WRITE

    • REWRITE

  • 戻り値

    正常に関数が実行された場合、0が返されます。状態コード値を確認して、データセットを正常に書き込んだのかを確認します。

3.4. tfcd_writea()

レコードの先頭にASA制御文字を指定し、データセットに新しいレコードを書き込みます。tfcd.hヘッダー・ファイルには、Writea APIの実行時にASA制御文字を指定するマクロが以下のように定義されています。

#define TFCD_WRITEA_AFTER           0   /* AFTER */
#define TFCD_WRITEA_BEFORE          1   /* BEFORE */

#define TFCD_WRITEA_TAB             2   /* TAB */
#define TFCD_WRITEA_PAGE            4   /* PAGE */
#define TFCD_WRITEA_MNEMONIC        8   /* MNEMONIC */
  • プロトタイプ

    int tfcd_writea(void *fcd, char *record, int lcount, int flags);
  • パラメータ

    パラメータ 説明

    fcd(入出力)

    メインCOBOLアプリケーション・プログラムから渡されたFCD構造体アドレスです。

    record(入力)

    データセットに書き込むレコードが保存されているレコード・バッファー・ポインターです。

    lcount(入力)

    レコードを出力する前に移動させる行数です。

    flags(入力)

    データセットを書き込むときに指定できる属性です。

  • 戻り値

    正常に関数が実行された場合、0が返されます。状態コード値を確認して、データセットを正常に書き込んだのかを確認します。

3.5. tfcd_delete()

相対データセットや索引データセットの場合、直前に読み取ったレコードを削除します。

  • プロトタイプ

    int tfcd_delete(void *fcd, char *record, int flags);
  • パラメータ

    パラメータ 説明

    fcd(入出力)

    メインCOBOLアプリケーション・プログラムから渡されたFCD構造体アドレスです。

    record(入力)

    データセットから削除するレコードが保存されているレコード・バッファー・ポインターです。

    flags(入力)

    データセットを削除するときに指定できる属性です。

  • 戻り値

    正常に関数が実行された場合、0が返されます。状態コード値を確認して、レコードを正常に削除したのかを確認します。

4. 特殊な操作

4.1. tfcd_is_file_open()

FCD構造体に記述されているデータセットが開かれているかを確認します。メインCOBOLアプリケーション・プログラムで開いたデータセットのDD名を変更する前に、データセットが開かれているかどうかを確認するために使用します。

  • プロトタイプ

    int tfcd_is_file_open(void *fcd);
  • パラメータ

    パラメータ 説明

    fcd(入力)

    メインCOBOLアプリケーション・プログラムから渡されたFCD構造体アドレスです。

  • 戻り値

    データセットが開かれていれば1、そうでない場合は0が返されます。

4.2. tfcd_get_status()

データセットI/Oを実行した後、エラーの発生有無を確認するためにデータセットの状態コードを取得します。一般的に状態コード値がスベースであると、データセットへのI/O機能が正常に実行されたことになります。

データセットI/Oの実行時に深刻なシステム・エラーやOpenFrameライブラリ・エラーが発生すると、エラーメッセージと同時にプログラムが終了されます。ただし、End of File(ファイルの終了)などの一般的なデータセットI/Oエラーの場合は、プログラムが終了せずに適切な状態コード値が設定された後、I/O関数が正常に返されます。したがって、I/O関数を実行した後は、必ずtfcd_get_status()関数を使用して、エラーの発生有無を確認する必要があります。

データセットI/O関数で設定できるデータセットの状態コード値は、MicroFocus Server Expressのオンライン・マニュアルを参照してください。

  • プロトタイプ

    int tfcd_get_status(void *fcd, char *status);
  • パラメータ

    パラメータ 説明

    fcd(入力)

    メインCOBOLアプリケーション・プログラムから渡されたFCD構造体アドレスです。

    status(出力)

    データセットの状態情報を保存するバッファーです。

  • 戻り値

    正常に関数が実行された場合、0が返されます。

4.3. tfcd_get_file_name()

FCD構造体に記述されているデータセットのDD名を取得します。開かれているデータセットと閉じられているデータセットの両方に使用できるAPIです。

  • プロトタイプ

    int tfcd_get_file_name(void *fcd, char *file_name);
  • パラメータ

    パラメータ 説明

    fcd(入力)

    メインCOBOLアプリケーション・プログラムから渡されたFCD構造体アドレスです。

    file_name(出力)

    データセットのDD名を保存するバッファーです。

  • 戻り値

    正常に関数が実行された場合、0が返されます。

4.4. tfcd_get_rec_len()

FCD構造体に記述されているデータセットのレコード長を取得します。固定長データセットが最初に開かれた時点で全体データセットの固定レコード長を取得する場合や、可変長データセット・レコードをREAD APIで読み取った後、読み取ったレコードの長さを取得する場合に使用できます。

可変長レコード・データセットのレコード長は、RDWを除いたレコードのデータ部分の長さです。

  • プロトタイプ

    int tfcd_get_rec_len(void *fcd, int *reclen);
  • パラメータ

    パラメータ 説明

    fcd(入力)

    メインCOBOLアプリケーション・プログラムから渡されたFCD構造体アドレスです。

    reclen(出力)

    データセットのレコード長を保存するバッファーです。

  • 戻り値

    正常に関数が実行された場合、0が返されます。

4.5. tfcd_set_file_name()

FCD構造体に記述されているデータセットのDD名を指定します。メインCOBOLアプリケーション・プログラムで開いたデータセットのDD名を変更し、新しいデータセットを開くために使用します。同APIを使用する前に、開かれていたデータセットはClose APIを使用して閉じる必要があります。

  • プロトタイプ

    int tfcd_set_file_name(void *fcd, char *file_name);
  • パラメータ

    パラメータ 説明

    fcd(入出力)

    メインCOBOLアプリケーション・プログラムから渡されたFCD構造体アドレスです。

    file_name(入力)

    データセットに指定するDD名です。

  • 戻り値

    正常に関数が実行された場合、0が返されます。

4.6. tfcd_set_relative_key()

FCD構造体に記述されているデータセットの相対キーを指定します(RELATIVE)。相対データセットの場合、tfcd_set_relative_key()で指定した相対キーの位置に新しいレコードを保存するか、保存されていた既存のレコードを読み取ります。

  • プロトタイプ

    int tfcd_set_relative_key(void *fcd, int relative_key);
  • パラメータ

    パラメータ 説明

    fcd(入出力)

    メインCOBOLアプリケーション・プログラムから渡されたFCD構造体アドレスです。

    relative_key(入力)

    相対データセットの相対キーです。

  • 戻り値

    正常に関数が実行された場合、0が返されます。

4.7. tfcd_set_key_id()

FCD構造体に記述されているデータセットのキーIDを指定します(INDEXED)。

副レコード・キーが追加で定義されているデータセットに対し、副レコード・キーを使用してランダムにレコードを読み取る場合、tfcd_set_key_id() APIを呼び出して次回Read APIで使用するキーIDを指定します。

  • プロトタイプ

    int tfcd_set_key_id(void *fcd, int key_id);
  • パラメータ

    パラメータ 説明

    fcd(入出力)

    メインCOBOLアプリケーション・プログラムから渡されたFCD構造体アドレスです。

    key_id(入力)

    データセットに指定するキーIDです。

  • 戻り値

    正常に関数が実行された場合、0が返されます。

4.8. tfcd_set_rec_len()

FCD構造体に記述されているデータセットのレコード長を指定します。可変長データセット・レコードをWrite APIを使用して書き込む前に、レコード長を指定する場合に使用します。可変長レコード・データセットのレコード長は、RDWを除いたレコードのデータ部分の長さを指定します。

  • プロトタイプ

    int tfcd_set_rec_len(void *fcd, int reclen);
  • パラメータ

    パラメータ 説明

    fcd(入出力)

    メインCOBOLアプリケーション・プログラムから渡されたFCD構造体アドレスです。

    reclen(入力)

    データセットに指定するレコード長です。

  • 戻り値

    正常に関数が実行された場合、0が返されます。